返回

JS阻碍渲染?过时的误解!揭开真相!

前端

打破误区:深入剖析浏览器渲染机制

你是否曾疑惑过,为何你的网站有时在加载时会出现停顿?

多年来,一种流传甚广的说法认为,JavaScript(JS)线程负责执行 JS 代码,而 GUI 渲染线程负责渲染页面,这两者是相互排斥的,即当 JS 执行时,它会阻塞渲染。

然而,随着开发人员工具的广泛使用,我们开始对这一说法产生怀疑。让我们深入探究浏览器的渲染机制,揭开真相吧!

浏览器渲染机制的真相

当浏览器接收到一个 HTML 文档时,它会将其解析成一个 DOM(文档对象模型)树,一个表示页面结构的可视化表示。接着,浏览器会构建一个渲染树,它是 DOM 树的可视表示,包含页面上所有可见元素及其样式信息。

浏览器使用 主线程 ,一个单线程,来处理所有任务,包括解析 HTML、构建 DOM 树、计算渲染树和执行 JS 代码。这意味着 JS 代码确实可以在主线程上执行。

但是,并非所有 JS 代码都会阻塞渲染。 只有 同步 JS 代码才会阻塞渲染,而 异步 JS 代码则不会。

同步 JS 代码

同步 JS 代码是在主线程上立即执行的。它会阻止渲染,直到代码执行完毕。例如,以下代码段会阻塞渲染:

for (var i = 0; i < 100000; i++) {
  // 计算密集型操作
}

异步 JS 代码

异步 JS 代码是在主线程之外执行的,不会阻塞渲染。浏览器使用 Web API(例如 setTimeout() 和 requestAnimationFrame())将异步代码安排到一个称为 事件队列 的队列中。这些 API 允许代码稍后执行,而不会阻塞主线程。

例如,以下代码段是异步的,不会阻塞渲染:

setTimeout(() => {
  // 计算密集型操作
}, 0);

现代浏览器的优化

现代浏览器已经采取了多种措施来最大程度地减少 JS 对渲染的影响。这些优化包括:

  • 增量布局和绘制: 浏览器会将页面分成多个部分,并仅在需要时对可见部分进行重新布局和绘制。
  • 惰性加载: 浏览器只会加载当前可见部分的 JS 代码,延迟加载其余代码,以避免对渲染造成不必要的阻塞。
  • Web Workers: Web Workers 是在主线程之外运行的单独线程,允许 JS 代码在不阻塞渲染的情况下执行。

结论

JS 阻塞渲染的说法已经过时了。 虽然同步 JS 代码确实可以阻塞渲染,但异步 JS 代码和现代浏览器的优化措施使得它不再是浏览器性能的主要瓶颈。通过了解浏览器的渲染机制,我们可以编写出不会阻碍渲染的优化 JS 代码。

常见问题解答

  1. 为什么某些 JS 代码会阻塞渲染,而其他则不会?
    同步 JS 代码阻塞渲染,因为它是在主线程上立即执行的,而异步 JS 代码是在主线程之外执行的,不会阻塞渲染。

  2. 如何避免 JS 阻塞渲染?
    尽可能使用异步 JS 代码,并考虑使用 Web Workers 来处理计算密集型任务。

  3. 现代浏览器如何优化 JS 渲染?
    现代浏览器通过增量布局和绘制、惰性加载和 Web Workers 等技术来优化 JS 渲染。

  4. 什么是 DOM 树和渲染树?
    DOM 树是 HTML 文档的可视化表示,而渲染树是 DOM 树的可视表示,包含页面上所有可见元素及其样式信息。

  5. 如何编写不会阻碍渲染的 JS 代码?
    遵循最佳实践,例如使用异步 JS 代码、避免计算密集型任务和利用浏览器优化措施,可以编写不会阻碍渲染的 JS 代码。