浏览器环境的 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)

相关推荐
小张认为的测试1 天前
Selenium 浏览器驱动代理 - 无需下载本地浏览器驱动镜像!(Java 版本!)
java·python·selenium·测试工具·浏览器
货拉拉技术2 天前
你的骨架屏用对了吗?
前端·性能优化·浏览器
十里八乡有名的后俊生11 天前
深入探索前端开发中的浏览器事件模型与请求处理
前端·javascript·浏览器
Alan_Wdd21 天前
解决谷歌人机验证 (reCAPTCHA) 无法加载问题
前端·chrome·浏览器·插件·人机验证·recaptcha
x-cmd1 个月前
[241202] Firefox 切换到 .tar.xz 用于 Linux 打包 | Red Hat 即将成为 WSL 官方发行版
linux·windows·firefox·浏览器·wsl·混合云·压缩方式
samlyx1 个月前
浏览器的事件循环机制
浏览器
我爱学习_zwj1 个月前
前端面试题-1(详解事件循环)
前端·javascript·面试·浏览器
九幽归墟2 个月前
深入理解 CPU 和 GPU 渲染
前端·浏览器·gpu
gqkmiss2 个月前
Chrome 浏览器 131 版本开发者工具(DevTools)更新内容
前端·chrome·浏览器·chrome devtools
敲代码的彭于晏2 个月前
除了localStorage、sessionStorage,了解Cache Storage吗?
前端·浏览器·pwa