导航


HTML

CSS

JavaScript

浏览器 & 网络

版本管理

框架

构建工具

TypeScript

性能优化

软实力

算法

UI、组件库

Node

冷门技能

针对性攻坚(TODO)


基本认知

Untitled

如上图,在任务管理器的进程一栏里,有道词典和有道云笔记就是进程,而在进程下又有着多个执行不同任务的线程。

进程

渲染进程

⇒ 渲染引擎线程

⇒ JS 引擎线程

为什么渲染线程与JS线程互斥

因为不能一边渲染内容,一边 JS 在修改 DOM。

所以

<div>Front of you</div>
<script>while(true) {}</script> <!-- JS一直在执行,不空闲 -->
<div>End of you</div> <!-- 页面一直卡死,不渲染任何东西 -->
<div>Front of you</div>
<script>
  setTimeout(() => {
    document.getElementByTagName('div')[0].innerText = 'Front of me';
  }, 1000);
</script> <!-- JS执行完后,空闲 -->
<div>End of you</div> <!-- 页面渲染 Front of you 和 End of you,1s后改为 Front of me -->

事件

宏任务、微任务

浏览器事件环的运行流程

Untitled

image.png

  1. 先在 JS 引擎线程执行栈中执行同步代码(遇到宏任务,会执行它们,并把宏任务们的回调放进宏任务队列)
  2. 然后清空所有微任务
  3. GUI 渲染
  4. 取一个宏任务回调出来执行(先进先出)【其实处理的都是宏任务的回调函数 e.g. ajax 回调,setTimeout 回调,例如代码执行时,遇到 setTimeout ,其实是立马执行了 setTimeout,但把回调放进了宏任务队列
  5. 再执行同步代码
  6. 清空微任务
  7. ... 循环

简单记顺序就是:

同步代码 → 清空所有微任务 → 渲染 → 取宏任务队列中一个出来执行