你所不知道css加载阻塞DOM或js的执行机制

1,829 阅读3分钟

前言

可能大家都知道js执行会阻塞DOM树的解析和渲染,那么大家有没有想过css加载会阻塞DOM树的解析和渲染或者会阻塞js的运行吗?

今天我们来谈谈一下css加载会不会阻塞DOM树的解析和渲染或者会阻塞js的运行

如何利用chrome来设置下载速度

我们打开打开chrome控制台(按下F12),可以看到下图,切换到Network可以看到我圈起来的地方,点击add ,从这里我们可以模拟设置当前的网络情况,

image.png

这样,我们对资源的下载速度上限就会被限制成5kb/s,好,那接下来就进入我们的正题

image.png

css加载会阻塞DOM树的解析渲染吗?

只有实践才出真理:

<!DOCTYPE html>
<html lang="en">

<head>
    <title>css阻塞测试</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <style>
        p {
            color: orange !important
        }
    </style>
    <script>
        function test() {
            console.log(document.querySelectorAll('p'))
        }
        setTimeout(test, 0)
    </script>
    <link href="https://cdn.bootcss.com/bootstrap/4.0.0-alpha.6/css/bootstrap.css" rel="stylesheet">
</head>

<body>
    <p>你好,css阻塞测试</p>
</body>

</html>

如果css阻塞DOM解析和渲染的话,在css还没加载完之前,下面的内容不会被解析渲染,那么我们一开始看到的应该是白屏,p不会显示出来。并且此时console.log的结果应该是一个空数组。

image.png
但是实际上在css没有加载完成之前,在控制台已经可以获取到p标签了,从这里我们可以得知,css加载是不会阻塞DOM解析的

但是我们可以看到,只有当css加载完之后,p标签才会显示你好,css阻塞测试的橙色文本。从这里我们得出CSS加载会阻塞DOM的渲染的

对于这种机制,我个人理解是对浏览器渲染的一种优化机制。因为加载css的时候,可能会修改下面DOM节点的样式,如果css加载不阻塞DOM树渲染的话,那么当css加载完之后,DOM树可能又得重新重绘或者回流了,这就造成了一些没有必要的损耗。所以干脆就先把DOM树的结构先解析完,然后等css加载完之后,在根据最终的样式来渲染DOM树,形成render树,这种做法明显提高性能。

css加载会阻塞js运行吗?

只有实践才出真理:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>css阻塞js</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <style>
        p {
            color: orange !important
        }
    </style>
    <script>
        console.log('before css')
        var startDate = new Date()
    </script>
    <link href="https://cdn.bootcss.com/bootstrap/4.0.0-alpha.6/css/bootstrap.css" rel="stylesheet">
</head>

<body>
    <p>你好,css阻塞测试</p>
    <script>
        var endDate = new Date()
        console.log('after css')
        console.log('经过了' + (endDate - startDate) + 'ms')
    </script>
</body>
</html>

image.png

由上图我们可以看出,位于css加载语句前的那个js代码先执行了,但是位于css加载语句后面的代码迟迟没有执行,直到css加载完成后,它才执行。这也就说明了,css加载会阻塞后面的js语句的执行。

总结

1.css加载不会阻塞DOM树的解析 2.css加载会阻塞DOM树的渲染 3.css加载会阻塞后面js语句的执行

如果想知道原理的话,可以查看之前写的文章juejin.cn/post/684490…