浏览器渲染及脚本阻塞原理

本文涉及

  • CSS 加载阻塞
  • JS 加载阻塞
  • 阻塞优化
  • DOMContentLoaded 事件
  • 浏览器渲染步骤及原理

Css 的加载会造成阻塞吗

浏览器渲染过程

浏览器渲染过程

  1. 解析HTML文件,生成DOM Tree;解析CSS文件,生成CSSOM Tree(这两个过程是并行的)
  2. DOM TreeCSSOM Tree结合,生成RenderTree
  3. RenderTree渲染到屏幕上。
  • 由于解析HTMLCSS是并行的,所以css加载不会阻塞 DOM 解析
  • 由于CSSOM TreeDOM Tree需要结合,才能生成Render Tree。所以 css 加载会阻塞 DOM 渲染

那 CSS 加载会阻塞 JS 运行吗?

我理解是可以的,并且实际操作也是可以的。我们已知:js是可以操作DOM树,也可以改变Style

  • 如果css不阻塞js运行。那RenderTree还为渲染出来时,js 已经并行的运行了,操作了Dom或Style。那么此时的RenderTree就是旧版本。着就会造成一个结果跟操作不匹配的情况。

那 JS 又会怎么阻塞呢?

JS 不仅会阻塞HTML解析,还会阻塞HTML渲染。

  • 原因也很简单,因为 JS 可能会操作DOM树,如果不阻塞 DOM 的解析,也会造成操作后的DOM树已经解析出来的DOM树版本不匹配的情况。

综上,浏览器不允许出现已经解析/渲染出来的内容,跟实际操作过的内容不一致的情况,所以

  • CSS 加载会阻塞 DOM 渲染。
  • CSS 加载会阻塞 JS 运行。
  • JS 加载与执行都会阻塞 DOM 解析与渲染。

这里所有的阻塞,都是指,阻塞下面的代码,因为我们知道浏览器解析代码,是从上到下解析的,如果遇到了 CSS,就会阻塞下面引入的 JS 运行

多提一嘴优化

CSS 会阻塞 DOM 渲染,所以为了减少用户白屏时间,可以

  • 使用 CDN,CDN 会根据你的网络环境,挑选一个最近的缓存内容的节点提供资源,这样减少请求时间。
  • CSS 打包压缩,使用打包工具,webpack,glup 等。减少注释与空格等方法,从而减少文件大小减少请求时间。
  • 使用缓存。如Cache-ControlLast-Modified, ETag等操作,增加 Http 缓存。
  • 多个 CSS 合并,减少 http 请求。

我们还知道 JS 会阻塞 DOM 解析与渲染,优化这一块可以

  • 将 JS 文件放再 HTML 文件最后引入
  • 使用defer或者async延迟加载或异步加载
    • defer会告诉浏览器,不用等待脚本加载。继续加载 HTML 构建 DOM,然后再后台异步加载 js 脚本。具有defer属性的脚本会在文档解析完成开始执行,并且在DOMContentLoaded事件之前执行完成
    • asyncdefer类似,也是异步加载脚本,但是在加载完成后就会开始执行,不会等到文档解析完成后才开始执行。
1
2
<script src="XXXX" defer></script>
<script src="XXXX" async></script>

其实还有很多优化方法,但是笔者觉得确实太麻烦了,以上两种最简单方便。所以就只列下这两种哦。

DOMCotentLoaded

DOMContentLoaded是一个事件,当初始 HTML 文档被完全加载和解析完成之后,DOMContentLoaded就会被触发,无需等待样式表、图像、子框架等被完全加载。

跟他相似的是一个我们常接触的事件load

load 应该仅用于检测一个完全加载的页面 当一个资源及其依赖资源已完成加载时,将触发load事件。

但是要注意涉及到上面阻塞的情况,如果 js 脚本阻塞了 html 的加载,DOMContentLoaded也是不会触发的。所以DOMContentLoaded也有可能在所有脚本执行完毕后触发。

再深入一下!

既然都讲到了客户端对文件加载渲染原理,不如直接把浏览器从 0-1 渲染一个网页讲清楚吧!
浏览器渲染页面的过程可以简单概括为下面几步:

  • DNS 查询:通过形如https://example.com的 url 地址,找到对应的 ip 地址
    • 初次 DNS 查找,通过域名服务器查找,然后会将 ip 地址缓存一段时间。
    • 通过主机名加载一个页面通常仅需要 DNS 查找一次。但是, DNS 需要对不同的页面指向的主机名进行查找。如果fonts, images, scripts, 等都是不同的主机名,DNS 会对每一个进行查找。
  • TCP 连接
    • 三次握手
    • 四次挥手
    • TLS 协商(https 建立安全连接)
  • HTTP 请求
  • 服务器响应
  • 客户端渲染

参考链接

-------------本文结束感谢您的阅读-------------