通过 Performance 证明,网页的渲染是一个宏任务

网页的渲染是一个宏任务。 这是我下的一个结论。

别着急反驳,后面我会给出证据。

我们先来聊下什么是调试:

调试是通过工具获取运行过程中的某一时刻或某一段时间的各方面的数据,帮助开发者理清逻辑、分析性能、排查问题等。 JS 的各种运行环境都会提供调试器,除此以外我们也会自己做一些埋点上报来做调试和统计。

我们最常用的调试工具是 JS Debugger,它支持断点,可以在某处断住,查看当前上下文的变量、调用栈等,这对于理清逻辑很有帮助。

但是性能分析的调试工具却不能这样做,不能用断住的方式实时查看,因为会影响数据的真实性。所以这类工具都是通过录制一段时间的数据,然后作事后的统计和分析的方式,常用的是 Chrome Devtools 里的 Performance 工具。(甚至为了避免浏览器插件的影响,还要用无痕模式来运行网页)

点击录制按钮 record 开始录制(如果想录制从页面加载开始的数据,就点击 reload 按钮),Performance 会记录下录制时间内各方面的数据。

有哪些数据呢?

网页的运行是有多个线程的,主线程负责通过 Event Loop 的方式来不断的执行 JS 和渲染,也有一些别的线程,比如合成渲染图层的线程,Web Worker 的线程等,渲染的每一帧会绘制到界面上。

网页是这样运行的,那记录的自然也都是这些数据:

Performance 会记录网页的每个线程的数据,其中最重要的是主线程,也就是图中的 Main,这部分记录着 Event Loop 的执行过程,记录着 JS 执行的调用栈和页面渲染的流程。

看到图中标出的一个个小灰块了么,那就是一个个 Task,也就是宏任务。Event Loop 就是循环执行宏任务。每个 Task 都有自己的调用栈,可以看到函数的执行路径,耗时等信息。图中宽度代表了耗时,可以直观的通过块的宽窄来分析性能。

执行完宏任务会执行所有的微任务,在图中也可以清晰的看到:

点击每一个块可以看到代码的位置,可以定位到对应代码,这样就可以分析出哪块代码性能不好。

这些是 Main 线程的执行逻辑,也就是通过 Event Loop 来不断执行 JS 和渲染。

当然,还有其他线程,比如光栅化线程,也就是负责把渲染出的图层合并成一帧的线程:

总之,就像 Debugger 面前,JS 的执行过程没有秘密一样,在 Performance 面前,网页各线程的执行过程也没有秘密。

说了这么多,就是为了讲清楚调试工具和 Performance 都是干啥的,它记录了哪些信息。

我们想知道渲染是不是一个宏任务,自然可以通过 Performance 来轻易的分析出来。

我们继续看 Main 线程的 Event Loop 执行过程:

你会看到一个个很小的灰块,也就是一个个 Task,每隔一段时间都会执行,点击它,就会看到其实他做的就是渲染,包括计算布局,更新渲染树,合并图层、渲染等。

这说明了什么,不就说明了渲染是一个宏任务么。

所以,我们得到了结论:渲染是一个宏任务,通过 Event Loop 来做一帧帧的渲染。

通过 Performance 调试工具,我们可以看到 Main 线程 Event Loop 的细节,看到 JS 执行和渲染的详细过程。

有时你可能会看到有的 Task 部分被标红了,还警告说这是 Long Task。

因为渲染和 JS 执行都是在同一个 Event Loop 内做的,那如果有执行时间过长的 Task,自然会导致渲染被延后,也就是掉帧,用户感受到的就是页面的卡顿。

避免 Long Task,这是网页性能优化的一个重点。这也是为什么 React 使用了 Fiber 架构的可打断的组件树渲染,替代掉了之前的递归渲染整个组件树的方式,就是为了不产生 Long Task。

总结

本文目的为了证明渲染是不是一个宏任务,但其实更重要的是想讲清楚调试工具的意义。

调试工具可以分析程序运行过程中某一刻或某一段时间的各方面的数据,有两种方式:一种是 Debugger 那种断点的方式,可以看到上下文变量的值、调用栈,可以帮助理清逻辑、定位问题。而性能分析工具则是另一种方式,通过录制一段时间内的各种数据,做事后的分析和统计,这样能保证数据的真实性。

网页的性能分析工具 Performance 可以记录网页执行过程中的各个线程的执行情况,主要是主线程的 Event Loop 的执行过程,包括 JS 执行、渲染等。

通过 Performance,我们可以轻易的得出“渲染是一个宏任务”的结论。

就像在 Debugger 面前,JS 执行过程没有秘密一样。在 Performance 面前,网页的执行过程也同样没有秘密。

猜你喜欢

转载自juejin.im/post/7037839989018722340