关于CSS堵塞和JS堵塞

2021-12-22  本文已影响0人  辉夜真是太可爱啦

前言

大家好,我是辉夜真是太可爱啦

在上一文中,我们大致描述了浏览器的渲染过程。但是,由于 HTML 文档的解析过程,也是挺复杂的。所以我们专门将它抽离了出来。

先来说加载的意义:下载 + 执行。

CSS

1. CSS 文件是并行下载的

2. CSS 并不会阻塞构建 DOM树

3. CSS 的下载不会阻塞后面 JS 的下载,但是 JS 下载完成后,被阻塞执行

但是, CSS 加载会影响 JS 代码的执,这个起初我也感觉很不可思议,让我们来看个例子:

为了方便测试,大家可以把谷歌浏览器的网速进行设置

网速设置.png 网速设置.png
<!DOCTYPE html>
<html lang="en">
<head>
    <title>css阻塞</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script>
        alert('文档开始解析了!');
    </script>
    <link href="https://cdn.bootcss.com/bootstrap/4.0.0-alpha.6/css/bootstrap.css" rel="stylesheet">
</head>
<body>
<h1>这是红色的</h1>
</body>
<script>
    alert('文档解析结束了!');
</script>
</html>

文档会从上往下进行解析,先执行 alert('文档开始解析了!'); ,然后,遇到 link 标签,加载外链 CSS ,直到加载完成之后,才会执行下面的 alert('文档解析结束了!');

这是由于 JS 可能会获取或者改变元素的样式,所以浏览器会按照顺序,等上面的 CSS 加载解析完成之后,再执行下面的 JS 。

JS

  1. 现代浏览器会并行加载 JS 文件,但是按照书写顺序执行代码

  2. 加载或者执行 JS 时会阻塞构建 DOM树,只有等到js执行完毕,浏览器才会继续解析 DOM 。没有 DOM树 ,浏览器就无法渲染,所以当加载很大的 JS 文件时,可以看到页面很长时间是一片空白。

这是因为加载的 JS 中可能会创建,删除节点等,这些操作会对 DOM树 产生影响,如果不阻塞,等浏览器解析完标签生成 DOM树后, JS 修改了某些节点,那么浏览器又得重新解析,然后重新生成 DOM树,性能比较差。

如果你不想 JS 阻塞你的 DOM树 生成,也是有方法的。

defer / async

deferasync 都是作用于 外链JS 的。对于 内部JS 是没有效果的。

deferasync 都是异步的,主要的区别在于执行顺序以及执行的时间。

async 标志的脚本文件一旦加载完成就会立即执行,并且不会按照书写顺序,谁下载好了就直接执行。所以适用于那些没有代码依赖顺序,并且没有 DOM操作 的脚本文件。

defer 标志的脚本文件会严格按照书写顺序执行,并且,会在 DOMContentLoaded 事件之前(也就是页面DOM加载完成时)执行。适用于有 DOM操作 ,或者是有代码依赖顺序的脚本文件。

上一篇下一篇

猜你喜欢

热点阅读