前言
可能大家都知道js执行会阻塞DOM树的解析和渲染,那么大家有没有想过css加载会阻塞DOM树的解析和渲染或者会阻塞js的运行吗?
今天我们来谈谈一下css加载会不会阻塞DOM树的解析和渲染或者会阻塞js的运行
如何利用chrome来设置下载速度
我们打开打开chrome控制台(按下F12),可以看到下图,切换到Network可以看到我圈起来的地方,点击add ,从这里我们可以模拟设置当前的网络情况,

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

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的结果应该是一个空数组。

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>

由上图我们可以看出,位于css加载语句前的那个js代码先执行了,但是位于css加载语句后面的代码迟迟没有执行,直到css加载完成后,它才执行。这也就说明了,css加载会阻塞后面的js语句的执行。
总结
1.css加载不会阻塞DOM树的解析 2.css加载会阻塞DOM树的渲染 3.css加载会阻塞后面js语句的执行
如果想知道原理的话,可以查看之前写的文章juejin.cn/post/684490…