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

开发 前端
但很多人对 Event Loop 的理解只是停留在概念层面,并没看过真实的 Event Loop 是怎样的。

网页加载后,浏览器会解析 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

图片

点击 Performance 面板的 reload,录制 3 s 的数据:

图片

其中 Main 这部分就是网页的主线程,也就是执行 Event Loop 的部分:

图片

这块区域包含了所有 task 执行的流程,每个 task 的调用栈,因为像燃烧的火焰,所以也叫做火焰图。

鼠标划到想看的部分,向下拖动,就可以放大那个区域:

图片

左右拖动可以调整看的位置:

图片

展示的信息中很多种颜色,这些颜色代表着不同的含义:

灰色就代表宏任务 task:

图片

蓝色的是 html 的 parse,橙色的是浏览器内部的 JS:

图片

紫色是样式的 reflow、repaint,绿色的部分就是渲染:

图片

其余的颜色都是用户 JS 的执行了,那些可以不用区分。

怎么从 Performance 中看出 Event Loop 执行的流程呢?

我们一起来看一下:

你会发现每隔一段时间就会有一个这种任务:

图片

放大一下是这样的:

图片

执行了 Animation Frame 的回调,然后执行了回流重绘,最后执行渲染。

这种任务每隔 16.7 ms 就会执行一次:

图片

这就是网页里怎么执行渲染的。

所以说 requestAnimationFrame 的回调是在渲染前执行的,rAF 和渲染构成了一个宏任务。

为什么有的时候会掉帧、卡顿,就是因为阻塞的渲染的宏任务的执行:

图片

(在 Performance 中宽度代表时间,超过 200ms 就被认为是 Long Task,会被标红)

我们做性能分析,就是要找到这些 Long Task,然后优化掉它。

那除了 rAF 和渲染,还有哪些是宏任务呢?

看下分析的结果就知道了:

可以看到 requestIdleCallback 的回调是宏任务:

图片

垃圾回收 GC 是宏任务:

图片

requestAnimationFrame 的回调是宏任务:

图片

html 中直接执行的 script 也是宏任务:

图片

这些需要记么?

不需要,用 Performance 工具看下就知道了。

那微任务是怎么执行的呢?

图片

可以看到 micro task 只是 task 的一部分,宏任务执行完就会执行所有的微任务。

这就是这个网页的 Event Loop 执行过程。

当你对这些熟悉了之后,看到下面的火焰图,你就能分析出一些东西来了:

图片

中间比较宽的标红的就是 Long Task,是性能优化的主要目标。

一些比较窄的周期性的 Task 就是 requestAnimationFrame 回调以及 reflow、rapaint 和渲染。

比较长的那个调用栈一般是递归,而且递归层数特别多。

当你展开看的时候,它也能展示完整的代码运行流程:

图片

而如果你打断点调试,只能看到其中的一个调用栈,这是用 Performance 工具分析代码流程比 debugger 断点调试更好的地方。

当你阅读源码的时候,也可以通过 Performance 看执行流程的全貌,然后再 debugger 某些具体的流程。

总结

Performance 工具能够看到网页的 Event Loop 是怎么运行的,不同的颜色代表不同的含义:

  • 灰色:task
  • 橙色:浏览器内部的 JS
  • 蓝色:html parse
  • 紫色:reflow、repaint
  • 绿色:渲染

其余的颜色都是用户自己的 JS。

宽度代表了执行的时间,超过 200ms 就被任务是长任务,需要优化。

长度代表了调用栈深度,一般特别长的都是有递归在。

用 Performance 工具可以分析出很多东西:

  • rAF 回调和 reflow、repaint 还有渲染构成一个宏任务,每 16.7 ms 执行一次。
  • rAF 回调、rIC 回调、GC、html 中的 script 等都是宏任务
  • 在任务执行完后,浏览器会执行所有微任务,也就是 runAllMicroTasks 部分

Performance 可以看到代码执行全貌,而断点调试的调用栈只能看到某一条流程。所以调试代码的时候可以 Performance 和 Debugger 结合来看。

总之,会用 Performance 工具,你就能深入理解 Event Loop,理清网页执行的全流程。

责任编辑:武晓燕 来源: 神光的编程秘籍
相关推荐

2022-10-12 07:53:46

并发编程同步工具

2016-12-08 15:36:59

HashMap数据结构hash函数

2020-07-21 08:26:08

SpringSecurity过滤器

2010-06-01 15:25:27

JavaCLASSPATH

2024-02-21 21:14:20

编程语言开发Golang

2017-08-15 13:05:58

Serverless架构开发运维

2020-09-23 10:00:26

Redis数据库命令

2017-01-10 08:48:21

2019-06-25 10:32:19

UDP编程通信

2013-09-22 14:57:19

AtWood

2009-09-25 09:14:35

Hibernate日志

2023-10-19 11:12:15

Netty代码

2021-02-17 11:25:33

前端JavaScriptthis

2013-10-24 15:23:40

Event Loop

2020-11-13 16:40:05

RocketMQ延迟消息架构

2021-07-26 07:47:37

无锁编程CPU

2019-04-08 16:50:33

前端性能监控

2024-04-15 00:00:00

技术Attention架构

2023-09-26 08:01:46

消费者TopicRocketMQ

2022-02-21 16:57:13

APIIDE构建系统
点赞
收藏

51CTO技术栈公众号