浏览器环境的 Event loop

浏览器环境的 Event loop

相关概念

event loop

PS:Node 环境的 event loop 与浏览器有差异,这里只讨论浏览器环境

根据 HTML 规范定义,event loop 是浏览器为了协调事件、用户交互、脚本、渲染、网络必须使用的处理模型

event loop 可以根据不同环境分类为:

  • window event loop: 浏览器窗口环境的事件循环
  • worker event loop: web worker 和 service worker 环境的事件循环
  • worklet event loop: worklet 环境的事件循环

task

PS: 关于宏任务(macrotask),html 规范中并无相关描述,个人理解其应该是社区为了区分微任务创造的概念

task,任务。任务是一个结构体(struct),封装了负责以下操作的算法

  • Events:事件
  • Parsing: 解析文档
  • Callbacks: 回调
  • Using a resource: 获取资源
  • Reacting to DOM manipulation:响应 DOM 操作

一个 event loop 维护一到多个 任务队列(task queue) ,每个任务来特定的 任务源(task source),每个任务源关联一个特定的任务队列

常见任务源有这些:

  • DOM manipulation: DOM 操作
  • user interaction: 用户交互
  • networking: 网络活动
  • navigation and traversal:网页历史前进后退

使用任务源分类,是为了方便决定任务的优先级,比如给用户交互相关的任务队列 3/4 的优先权,就可以让界面保持响应性,但又不卡死其它任务队列

任务和微任务上属于 JS 引擎层面的概念,JS 代码执行必然属于任务或微任务,但反之不一定,比如绘制 UI 便是渲染引擎的工作

与 JS 相关的任务主要有:

  • script 代码执行
  • 各类事件监听函数回调
  • setTimeout,setInterval 定时器回调
  • requestAnimationFrame,requestIdleCallback 回调
  • postMessage,MessageChannel 通信

microtask

PS: html 规范中的 microtask 可以与 ECMA 规范中的 Jobs 概念对应

microtask,微任务。一个 event loop 只维护一个微任务队列(microtask queue),通过算法分类进入微任务队列的任务,即为微任务

PS: 微任务是任务,但微任务队列不是任务队列

微任务主要有:

  • Promise
  • MutationObserver

event loop 处理模型

html 规范中给出了非常详细的模型:event-loop-processing-model

简单提炼一下涉及到 JS 代码执行的部分:

  1. 选择一个任务队列
  2. 从任务队列中取出一个任务执行
  3. 检查微任务队列是否为空,如果为空,进入步骤 5
  4. 依次执行微任务队列中的微任务
  5. 检测是否需要渲染 UI,如需要渲染 UI,进入步骤 6
  6. 在渲染 UI 之前执行 requestAnimationFrame 回调
  7. 检测任务队列是否为空,如果不为空则回到步骤 2
  8. 执行 requestIdleCallback 回调

需要注意的点:

  • 从步骤 2 到 7 算一次 event loop,当前任务队列清空后才会执行 requestIdleCallBack 回调
  • 微任务队列只有一个,而微任务对象清空后才能进入下一次 event loop,如果在微任务中不断添加新的微任务,便会阻塞 event loop,无法进入下一步的 UI 渲染,导致卡顿
  • 渲染 UI 的基本条件应该是: 当前 event loop 所消耗的时长大于一个动画帧(animation frame)时长。这个时长由用户设备的屏幕刷新率相关,60HZ 刷新率为 1/60 s,即 16.67ms

参考资料

HTML Standard (whatwg.org)

相关推荐
m0_564914924 天前
为什么360极速浏览器X新建标签页总在所有标签页的最右侧打开?用键盘Ctrl+T新建标签页总在所有标签页最右侧打开解决办法。
浏览器
不一样的少年_4 天前
女朋友被链接折磨疯了,我写了个工具一键解救
前端·javascript·浏览器
平生不晚5 天前
优化使用img标签加载svg大图导致的内存开销
前端·浏览器
Canace5 天前
浏览器渲染原理概述
前端·性能优化·浏览器
柯腾啊8 天前
“Script error.”的产生原因和解决办法
前端·javascript·浏览器
不一样的少年_10 天前
1024程序员节:用不到100行代码做个“代码雨屏保”装X神器(附源码)
前端·javascript·浏览器
Juchecar10 天前
翻译:ChatGPT 的 Atlas:一款反网络的浏览器
浏览器
小时前端10 天前
面试官:线上应用内存持续泄漏,你如何快速定位并止血?
前端·浏览器
萌萌哒草头将军12 天前
重磅!首个 AI 浏览器发布,ChatGPT Atlas 浏览器问世!🚀🚀🚀
chrome·浏览器·v8
不一样的少年_12 天前
她说想要浪漫,我把浏览器鼠标换成了柴犬,点一下就有烟花(附源码)
前端·javascript·浏览器