满足则不辱,知止则不殆。——老子javascript
咱们在看一些前端优化规则的时候,好比雅虎军规等等,都有看到 style 写在 head 中,可是外链 script 写在 body 的最后,以优化性能,都知道应该怎么作,可是不知道其中的原理。 若是还不知道浏览器渲染的原理的,看一看浏览器渲染原理这一篇文章。其实这个就是考验你们对 html 中的 css、javascript、dom 之间的解析和相互阻塞关系。java
当咱们把 script 标签写到页面的顶部时,dom 树在解析的时候检测到 script 标签是,会加载 script 里面的内容而且执行。咱们假设在执行javascript 会阻塞 dom的解析和渲染,阻塞 css的解析和加载。node
在验证以前咱们先把 chrome 的网速调到 40kb 每秒的下载和上传数据 第一步jquery
咱们来验证这个结论: html 代码以下chrome
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script> console.log('start load'); function h () { console.log(document.querySelectorAll('h1')) }; setTimeout(h, 0); </script>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
<style> h1 { color: red; } </style>
<script> console.log('end load'); setTimeout(h, 0); </script>
</head>
<body>
<h1>测试阻塞加载</h1>
</body>
</html>
复制代码
在加载到jquery 文件后,会先下载远程的 jquery 而且执行他,他会阻塞 dom 的解析和渲染,css 解析和渲染,一直是白屏,等 jquery执行完成了才接着解析 Dom 和 cssom 而且渲染,console.log 打印 h1 标签也是空数组。 以下图所示: 数组
javascript 加载会阻塞 css 解析和渲染浏览器
javascript 加载会阻塞 dom 解析和渲染
由于上面咱们已经验证过 JavaScript
会阻塞 Dom
的解析和渲染,同时也会解析 cssom
的解析和渲染,因此咱们假设 css 的加载会阻塞Dom 的解析和渲染,会阻塞JavaScript 的加载和执行。
在上面的代码基础上修改代码以下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script> console.log('start load'); function h () { console.log(document.querySelectorAll('h1')) }; setTimeout(h, 0); </script>
<link href="https://cdn.bootcss.com/jqueryui/1.12.1/jquery-ui.css" rel="stylesheet">
<style> h1 { color: red; } </style>
<script> console.log('end load'); </script>
</head>
<body>
<h1>测试阻塞加载</h1>
</body>
</html>
复制代码
执行结果以下图所示
若是按咱们假设的 css 加载会阻塞 Dom 的解析和渲染,那么执行的结果,应该是首先是白屏,而后** h1 标签**的 nodeList
应该是为空数组的,可是在执行的时咱们看到 h1 标签的 nodeList
是有值的,注(还有 setTimeout 的做用是为了在下一个 Task 最早执行,感受并不会影响咱们的实验的结果。) 这表示咱们一开始的假设是有问题的,css 加载会阻塞 Dom 的渲染有阻塞,可是并不会阻塞 Dom 的解析。
css 加载会对后续的 JavaScript 的执行会形成阻塞。
若是还不了解总体的渲染流程能够看之前我前面的文章,浏览器渲染原理 (一)在网址中输入一个网站后面都作了什么