最近看了本书,叫《web 高效编程与优化实践》,看的过程当中激发了我对 Chrome Devtools 的兴趣,刚好看到了关于性能优化和网页渲染的那部分,又想起了以前看过各大论坛你们对于浏览器渲染的理解,因此打算本身再看看这部分的知识点,解决一些疑问。css
本文的试验都是基于 Chrome 浏览器,版本:75.0.3770.100(正式版本)(64 位)html
先上连接:前端
这几篇部分是在这个过程当中看到的感受比较细致且靠谱的文章,虽然文章的写做时间都不算早,可是原理基本不会有太大变化,你们若是看完个人文章以为不过瘾的话,能够看看这些文章。html5
先简单归纳一下浏览器渲染的步骤:node
以上步骤说的比较简略,并且没有带上 reflow 和 repaint,主要是帮你们梳理一下这个过程,便于后面的阅读。web
终于说到文章正题,想必标题你们也看到了,是想研究一下 link 标签和 script 标签对页面渲染的影响,既然是影响,确定是不理想的状况。至于对页面渲染的影响,这里主要讨论的是对页面首次绘制时的影响。chrome
下面让咱们先整理一下不理想的状况,而后一个一个来试验下:express
这就是本文试验的一些状况,正常位置固然是咱们平时总说的 link 标签要放在首部 head 中,script 标签放在 body 底部,加载时间过长经过服务器端延时 5000 毫秒来处理。编程
本次为了快速开发,用到了一些快速搭建的工具,先推荐给你们:浏览器
行了,就用到这些东西,废话很少说,咱们开始吧。
先来看看咱们用到的文件:
html:
<!DOCTYPE html>
<html lang="zh-cmn-Hans">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="IE=edge, chrome=1">
<title>debounce</title>
<style> img { width: 500px; } .block { width: 300px; height: 200px; border: 1px solid #000; } </style>
<link href="http://127.0.0.1:3000/public/css/common.css" rel="stylesheet">
</head>
<body>
<div class="block">
<h2 class="title">我是一段没有感情的测试文案</h2>
</div>
<div class="pic">
<img src="https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=4215863670,261223381&fm=26&gp=0.jpg">
</div>
<script src="http://127.0.0.1:3000/public/js/test.js"></script>
</body>
</html>
复制代码
common.css:
.block {
width: 500px;
background-color: red;
border: none;
}
复制代码
test.js:
document.querySelector('.title').innerHTML = '我被修改了';
复制代码
app.js:
const express = require('express')
const app = express()
const fs = require('fs')
const path = require('path');
app.use('*',function(req, res){
if (req.params[0] === '/public/css/common.css') {
// setTimeout(() => {
res.setHeader('content-type', 'text/css');
res.send(fs.readFileSync(path.join(__dirname, req.params[0])));
// }, 5000)
} else if(req.params[0] === '/public/js/test.js') {
// setTimeout(() => {
res.send(fs.readFileSync(path.join(__dirname, req.params[0])));
// }, 5000)
} else {
res.send('success');
}
})
app.listen(3000, () => console.log('working'))
复制代码
这个页面打开之后是这个样子的:
让咱们先把 js 标签放到 head 的底部,也就是 link 标签下面(这里为了避免把每次改完标签位置的html都帖出来,我每次说的位置都是以初始位置为基准),并把服务器端延时的代码加上来看看效果:
能够看到页面由于 js 脚本的延迟加载,致使页面白屏长达数秒,这确定不是咱们平时开发中想要的,还有由于脚本位置过前致使操做的 dom 元素也没法找到。
再让咱们看看控制台中这个页面具体经历了什么:
经过 performance 咱们能够看到页面的在 5s 后才开始首次绘制,timeline 上也很容易看出前面页面一直处于白屏阶段。
如今让咱们把 js 放到初始的位置,一样加上延迟,再看下效果:
此次咱们能够看到虽然 js 文件延迟加载了,可是 js 文件以前的元素很快就渲染出来了,再看下控制台:
此次就很快了,页面没有由于 js 的加载阻塞前面元素的渲染,js 文件加载后由于修改了 dom 元素又绘制了一次。因此说把 js 文件放在页面底部这个作法仍是比较合理的,可是也须要分状况讨论,好比有些页面较长,图片较多,可能首屏只展示了部分 dom,这时若是把全部的 js 都放在页面底部,反而可能会影响 js 脚本对 dom 操做的实时性。
看完了 script 标签,如今让咱们看下 link 标签的表现,首先把 script 标签的延迟去掉,让 link 标签待在它原来的位置,在服务端加上延迟试一下:
很差意思,这里没有动图。。。
此次的状况动图能够参考动图一,由于第一次正经写文章,因此 gif 图是先录屏,而后截视频,再上传视频作 gif。有点麻烦,就懒得再搞一个了,小伙伴有好的软件或者方法欢迎评论区推荐。 至于网页的 performance 和第一种状况也是基本无差,我们直接进入到下一种状况吧。
此次咱们把 link 标签放到 body 的底部,其实前三种的状况和我想象中的基本没差,我试这个就是想看看最后一种状况,来直接看图吧:
诶,貌似和我预想的不太同样,咱们先来看下控制台确认下:
咱们能够看到浏览器此次并无像 script 脚本延迟时同样,等到 css 加载完才开始绘制,而是很早就把 dom 画出来了,等 css 加载完后,又再次绘制了一遍。后来我多试了几回,若是把css文件放到dom中间位置,发现css文件的延迟一样会阻塞后面元素的渲染,这个是我以前没有想到的。
其实,若是网速足够快,在资源的加载这一块,咱们根本无需考虑优化,由于脚本自己不会大的离谱,因此在网速超快的状况下,固然是想放哪里放哪里。可能在5年、10年之后的开发者回过头来我这篇文章,没准会对我如今考虑的这些问题不屑一顾,hhh。