轻松明白 CSS 和 JS 对页面渲染的阻塞

简介: 前言前面有分析过页面的渲染逻辑(老生常谈之从输入URL到页面呈现的过程(全)),从上至下解析 HTML,构建 DOM 树和 Style Rules,其中构建 DOM 和解析 Style 是并行的,之后 DOM 树和 Style Rules 结合成 Render Tree。

前言

前面有分析过页面的渲染逻辑(老生常谈之从输入URL到页面呈现的过程(全)),从上至下解析 HTML,构建 DOM 树和 Style Rules,其中构建 DOM 和解析 Style 是并行的,之后 DOM 树和 Style Rules 结合成 Render Tree。


108.png


下面我们来分析分析 CSS 和 JS 对 HTML 解析(DOM,Style Rules,Render Tree)的阻塞性


运行以下 Demo 的时候需要将浏览器控制台的网络先设置为 Slow 3G


CSS 的阻塞性


  1. 不阻塞 DOM 树的解析,但会阻塞 Style Rules 的解析,进而阻塞 Render Tree (因为渲染树需要等待 Style Rules,减少不必要的回流重绘)

<!DOCTYPE html>
<html>
<head>
  <script>
    setTimeout(() => {
      console.log(document.getElementById('app'))
    })
  </script>
  <link href="https://cdn.bootcdn.net/ajax/libs/animate.css/4.1.1/animate.compat.css" rel="stylesheet">
</head>
<body>
  <div id="app">
    666
  </div>
</body>
</html>
复制代码

  1. 阻塞在 CSS 之后的 JS 的解析执行(因为某些 JS API 如 getComputedStyle 需要最新的样式数据)

<!DOCTYPE html>
<html>
<head>
  <link href="https://cdn.bootcdn.net/ajax/libs/animate.css/4.1.1/animate.compat.css" rel="stylesheet">
  <script>
    console.log(1)
  </script>
</head>
<body>
  <div id="app">
    666
  </div>
</body>
</html>
复制代码


JS 的阻塞性


  1. JS 会阻塞在其后的 DOM 树的构建,进而影响 Render Tree。(因为 JS 经常操作 DOM API,为确保 DOM 一致性)。

<!DOCTYPE html>
<html>
<head>
</head>
<body>
  <div id="app1">
    333
  </div>
  <script>
    console.log(document.getElementById('app1'))
    console.log(document.getElementById('app2'))
  </script>
  <script src="https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.20/lodash.js"></script>
  <div id="app2">
    555
  </div>
</body>
</html>
复制代码


异步脚本的阻塞性


前面我们其实说的是同步脚本的阻塞性,下面来看看异步脚本的阻塞性


109.png


从网上找的这幅图描述的相当的一目了然


  1. script


立即下载执行,下载执行的过程中阻塞 HTML 解析(DOM 构建)


  1. async script

立即下载执行,但是下载过程不影响 HTML 解析(DOM 构建)(也就不影响渲染),仅在执行过程阻塞 HTML 解析(DOM 构建)


执行不按顺序

  1. defer script


立即下载,延迟执行(HTML 解析完成后),不阻塞 HTML 的解析(DOM 构建)((也就不影响渲染)


执行按顺序


总结


知道了 CSS 与 JS 的阻塞性及其阻塞背后的设计思想,有助于提升自己对页面渲染流程的认知,并且可以给页面的性能优化提供思路,知其然知其所以然,一起加油。


参考



相关文章
|
23小时前
|
前端开发 JavaScript UED
CSS顶部与JS后写:网页渲染的奥秘
CSS顶部与JS后写:网页渲染的奥秘
|
2天前
|
前端开发 数据安全/隐私保护
利用 HBuilderX 设置CSS样式会员注册页面
利用 HBuilderX 设置CSS样式会员注册页面
10 1
|
2天前
|
前端开发 JavaScript UED
由于JavaScript是单线程的,因此在处理大量异步操作时,需要确保不会阻塞UI线程
【5月更文挑战第13天】JavaScript中的Promise和async/await常用于处理游戏开发中的异步操作,如加载资源、网络请求和动画帧更新。Promise表示异步操作的结果,通过.then()和.catch()处理回调。async/await作为Promise的语法糖,使异步代码更简洁,类似同步代码。在游戏循环中,使用async/await可清晰管理资源加载和更新,但需注意避免阻塞UI线程,并妥善处理加载顺序、错误和资源管理,以保证游戏性能和稳定性。
12 3
|
2天前
|
前端开发 JavaScript 索引
CSS常见用法 以及JS基础语法
CSS常见用法 以及JS基础语法
13 0
|
2天前
|
JavaScript 前端开发
JS实现网页页面的框架(demo)
JS实现网页页面的框架(demo)
10 1
|
2天前
|
JavaScript 前端开发
js和css以及js制作弹窗
js和css以及js制作弹窗
12 1
|
2天前
|
JavaScript UED
js得禁止页面滚动
js得禁止页面滚动
13 1
|
2天前
|
JavaScript 前端开发
js选取页面元素的方法
js选取页面元素的方法
14 2
|
21小时前
|
设计模式 存储 前端开发
JS的几种设计模式,Web前端基础三剑客学习知识分享,前端零基础开发
JS的几种设计模式,Web前端基础三剑客学习知识分享,前端零基础开发
|
2天前
|
XML Web App开发 前端开发
字节FE:JavaScript学习路线图
字节FE:JavaScript学习路线图
10 0