会用 Performance 工具,就能深入理解 Event Loop

网站建设5年前发布
27 0 0

网页加载后,浏览器会解析 html、执行 js、渲染 css,这些工作都是在 Event Loop 里完成的,理解了 Event Loop 就能理解网页的运行流程。,但很多人对 Event Loop 的理解只是停留在概念层面,并没看过真实的 Event Loop 是怎样的。,其实在 Performance 工具里就可以看到,今天我们一起来看一下:,首先我们需要一个网页,我这里用的是 react 测试 fiber 用的网页:,https://claudiopro.github.io/react-fiber-vs-stack-demo/fiber.html,20230306005518d297f0c56cef108ea954650ee20181a52357a7693,点击 Performance 面板的 reload,录制 3 s 的数据:,20230306005519d40cab7267cf87d91a3323659c8f04386321e1616,其中 Main 这部分就是网页的主线程,也就是执行 Event Loop 的部分:,20230306005519c9a160570ea5e79faa2362dade8649c92490e5988,这块区域包含了所有 task 执行的流程,每个 task 的调用栈,因为像燃烧的火焰,所以也叫做火焰图。,鼠标划到想看的部分,向下拖动,就可以放大那个区域:,20230306005519519232712e817153a7b9699a4c6cf82731891f188,左右拖动可以调整看的位置:,20230306095319f70dc0f83d9c061ea12243d94a6036d39eb072651,展示的信息中很多种颜色,这些颜色代表着不同的含义:,灰色就代表宏任务 task:,2023030600575971cf19058213b321480116c63254953b267c1b761,蓝色的是 html 的 parse,橙色的是浏览器内部的 JS:,2023030600552177dec7f7373793f372359999ff199bff570ca9527,紫色是样式的 reflow、repaint,绿色的部分就是渲染:,20230306005522e8cf9278828b410efed56295f346d5b2f71c37362,其余的颜色都是用户 JS 的执行了,那些可以不用区分。,怎么从 Performance 中看出 Event Loop 执行的流程呢?,我们一起来看一下:,你会发现每隔一段时间就会有一个这种任务:,2023030600552364f814870bd6a50d8092417e291ba21b209e81484,放大一下是这样的:,20230306005523b81804253c77d3856ab554debcb46cb6fa9ed4152,执行了 Animation Frame 的回调,然后执行了回流重绘,最后执行渲染。,这种任务每隔 16.7 ms 就会执行一次:,20230306005523155ce47056d6757a1524498f99ff4223019c1d802,这就是网页里怎么执行渲染的。,所以说 requestAnimationFrame 的回调是在渲染前执行的,rAF 和渲染构成了一个宏任务。,为什么有的时候会掉帧、卡顿,就是因为阻塞的渲染的宏任务的执行:,20230306005759570a28983f1242ad3b73778d13f2021f8f8fa1540,(在 Performance 中宽度代表时间,超过 200ms 就被认为是 Long Task,会被标红),我们做性能分析,就是要找到这些 Long Task,然后优化掉它。,那除了 rAF 和渲染,还有哪些是宏任务呢?,看下分析的结果就知道了:,可以看到 requestIdleCallback 的回调是宏任务:,202303060055240334329417445310313780e49696790373b3a8307,垃圾回收 GC 是宏任务:,2023030600585216692de57438fd331b750230340c763457d92d219,requestAnimationFrame 的回调是宏任务:,20230306005525273f0e9927ca9ad035e727e854a7972357c8da920,html 中直接执行的 script 也是宏任务:,20230306005802f59897b388f9292a7986008721b3fcb430013a584,这些需要记么?,不需要,用 Performance 工具看下就知道了。,那微任务是怎么执行的呢?,2023030600552751149f4785c9a91560f340abcedb8e25bf3e26301,可以看到 micro task 只是 task 的一部分,宏任务执行完就会执行所有的微任务。,这就是这个网页的 Event Loop 执行过程。,当你对这些熟悉了之后,看到下面的火焰图,你就能分析出一些东西来了:,20230306005527a228d43701e582eee6f487679ec0af7d0195b3610,中间比较宽的标红的就是 Long Task,是性能优化的主要目标。,一些比较窄的周期性的 Task 就是 requestAnimationFrame 回调以及 reflow、rapaint 和渲染。,比较长的那个调用栈一般是递归,而且递归层数特别多。,当你展开看的时候,它也能展示完整的代码运行流程:,202303060055286520dc569feb1bc34c1517f698a3a3dcecb3e3895,而如果你打断点调试,只能看到其中的一个调用栈,这是用 Performance 工具分析代码流程比 debugger 断点调试更好的地方。,当你阅读源码的时候,也可以通过 Performance 看执行流程的全貌,然后再 debugger 某些具体的流程。,Performance 工具能够看到网页的 Event Loop 是怎么运行的,不同的颜色代表不同的含义:,其余的颜色都是用户自己的 JS。,宽度代表了执行的时间,超过 200ms 就被任务是长任务,需要优化。,长度代表了调用栈深度,一般特别长的都是有递归在。,用 Performance 工具可以分析出很多东西:,Performance 可以看到代码执行全貌,而断点调试的调用栈只能看到某一条流程。所以调试代码的时候可以 Performance 和 Debugger 结合来看。,总之,会用 Performance 工具,你就能深入理解 Event Loop,理清网页执行的全流程。

© 版权声明

相关文章