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

相关推荐
打小就很皮...11 天前
浏览器存储 Cookie,Local Storage和Session Storage
前端·缓存·浏览器
小妖66613 天前
chrome 浏览器怎么不自动提示是否翻译网站
浏览器
大名人儿17 天前
【浏览器网络请求全过程】
浏览器·网络请求·详解·全过程
windliang18 天前
Cursor 写一个网页标题重命名的浏览器插件
前端·浏览器
前端付豪18 天前
1、为什么浏览器要有渲染流程? ——带你一口气吃透 Critical Rendering Path
前端·后端·浏览器
啵啵学习19 天前
浏览器插件,提示:此扩展程序未遵循 Chrome 扩展程序的最佳实践,因此已无法再使用
前端·chrome·浏览器·插件·破解
前端南玖20 天前
通过performance面板验证浏览器资源加载与渲染机制
前端·面试·浏览器
mx95122 天前
真实业务场景:在React中使用Web Worker实现HTML导出PDF的性能优化实践
性能优化·浏览器
前端南玖1 个月前
浏览器如何确定最终的CSS属性值?解析计算优先级与规则
前端·css·浏览器
NSJim1 个月前
微软Edge浏览器字体设置
edge·浏览器·字体设置