CSS/JS对首次渲染阻塞情形汇总

414 阅读2分钟

一年前自己学习浏览器渲染流程,和CSS/JS阻塞,虽然感觉自己懂了,却有些模糊。

最近一周又学习浏览器渲染流程、感觉对 CSS/JS的阻塞情形,理解加深了很多,这篇文章尝试对所有情形进行分类和尝试回答。如果您有不同的看法,非常感谢您的评论

零、浏览器首次渲染流程

  1. 构建 DOMTree
  2. 生成 CSSOM (体现为 document.stylesheets)
  3. 构建 LayoutTree (用于实际渲染页面)
  4. 构建 LayerTree (分层,比如 position:fixed 会单独占一层)
  5. 合成和渲染到页面

一、JS阻塞情形

1. JS执行阻塞 DomTree

需求如此:浏览器觉得 JS 可能会修改到 DOMTree,所以遇到 script 标签时,就会暂停 DOM 解析,等到 JS 执行完,再继续进行 DOM 解析

2. JS下载阻塞 DomTree

  • JavaScript 下载也会阻塞 DOM 解析

    为了降低JavaScript 下载,对阻塞 DOM 解析的影响

    Chrome 浏览器:++预解析++, 提前下载 JS 和 CSS。

    开发者:异步加载,使用 async 或 defer

二、CSS阻塞了什么?

1. CSS 不阻塞 DOMTree

CSS下载和解析 都不阻塞 DOMTree

具体:CSS 下载和解析,都不阻塞 DOMTree (CSS解析不阻塞 HTML解析、那么CSS下载也不会阻塞)

原因:因为 CSSParser 和 HTML Parser 是可以同时进行的。原理图如下

这个图的 Render Tree 也是 LayoutTree

2. CSS 阻塞 JS执行

CSS下载和解析 阻塞 JS执行(需求如此)

浏览器认为,开发者的 JS 会存在修改 CSS 的情况,所以干脆遇到 CSS 都等待 CSS 下载、解析完,再执行后面的 JS。所以说 CSS 解析会阻塞 JS执行。

由于 Chrome 浏览器有预加载机制,所以 JS下载不会被阻塞

CSS 可能阻塞 DOMTree

CSS下载和解析 可能阻塞 DOMTree

上面的结论1, 是有特殊情况的

如果实际存在 CSS解析 阻塞 JS执行的情况,而 JS 会阻塞 HTML 解析,那么这个时候的 CSS解析 也会间接的阻塞 HTML 解析,即 DOM Tree

3. CSS 阻塞 LayoutTree

CSS下载和解析 阻塞 LayoutTree

因为 LayoutTree 需要等待 CSS 下载和解析后得到的 CSSOM, 再根据 CSSOM 进行计算布局

参考资料

李兵老师-浏览器工作原理与实践