这是去年看过 pagespeed insights 以后做的一个简单的分享,重新整理发布。
回顾浏览器渲染过程
- 加载HTML
- 加载资源
- 解析
- 渲染
页面HTML结构 (http://jslab.pro/demo/critical_rendering_path/index.html)
页面加载过程
(注:紫色是 DomContentLoaded,红色是 Load)
DOM树解析过程,Document Object Model (DOM)
- Conversion:字节码根据编码转换成字符
- Tokenizing:将字符串转化为特殊的标签,如“<html>”、“<body>”
- Lexing:将标签转换成“对象”,定义他们的属性和规则
- DOM construction:根据HTML定义的不同标签的关系(嵌套等),将创建的对象链接到一个树形的数据结构中:HTML对象是Body对象的父级,Body是P的父级等。
最终生成的DOM树
CSSOM 构建过程 CSS Object Model (CSSOM)
页面CSS样式
CSSOM 构建过程
CSSOM
生成渲染树,Render tree
- 从DOM树根节点开始,遍历每个可见节点。
- 每个可见节点找到并应用对应的CSSOM规则。
- 返回计算好样式的内容
Reflow(Gecko)或 Layout(webkit)
根据设备的 viewport 计算每个元素该怎样展示。
<meta name="viewport" content="width=device-width,initial-scale=1">
最后一步,绘制页面,Paint
总结解析渲染步骤:
- 处理HTML标签构建DOM树。
- 处理CSS标签构建CSSOM树。
- DOM和CSSOM树被组合形成 Render tree 渲染树(渲染树只包含需要显示在页面的节点)。
- Layout(reflow)计算每个对象的确切位置和大小。
- 最后是绘制(Paint),把最终的渲染树对象渲染成屏幕像素。
优化关键渲染路径,Critical Rendering Path
- Critical:必需的,关键的
- Render:渲染
- Path:浏览器显示网页(初始视图initial view )所必须的一系列过程。(初始视图也称为首屏 above the fold,用户不需要滚动就能看到的内容)
所以关键渲染路径的定义就是:浏览器显示网页所必须的一系列事件。
路径(the Path)
- 浏览器下载HTML文件
- 浏览器读取HTML,看到有CSS文件、JavaScript文件、图像(解析HTML,遇到CSS资源,加载CSS、解析CSS,继续解析HTML;遇到JavaScript过程相同)
- 浏览器开始下载资源
- 浏览器决定没有获取CSS和JavaScript的时候不能显示网页
- 浏览器下载到CSS文件并读取,并且没有调用其他内容
- 浏览器得到JavaScript之前,仍不会展示网页
- 浏览器下载JavaScript并读取,并且没有调用其他内容
- 浏览器现在决定可以显示网页
这只是一个最简单的网页加载过程,如果页面有很多资源加载过程就会很复杂。
渲染(the Render)
只有很少的资源会阻塞网页渲染,最常见的就是 CSS 和 JavaScript 文件。
浏览器必须把这些资源全部加载并解析完毕才回开始渲染页面。
举个例子:
1,页面有10个CSS文件,浏览器渲染前,会等待这10个CSS文件全部下载、解析完毕。此时浏览器在等待“关键”的步骤时空白页面。
2,页面还有20个JS文件,CSS都下载解析后,也不会开始渲染,还需要等待这20个JS的加载和解析。
(其他还有什么会阻塞?HTML,字体文件等)
(浏览器会逐步解析、逐步渲染,这就是首屏内容可以单独优化的原因)
关键内容(the Critical)(above the fold)(初始视图initial view )
关键内容 = 初始内容 = 首屏
只要保证首屏尽可能快的显示出来,就算页面有1000张图片,100个JavaScript也没有问题。
怎样优化关键渲染路径?
首先找到渲染(首屏)必需的步骤。然后尽可能的:
- 减少关键的资源;
- 减少关键的字节数;
- 减少关键的路径长度。
1,HTML:精简、压缩、缓存
2,CSS:Render blocking CSS,media query 只加载需要的样式,内联CSS
3,Javascript:Parser blocking Javascript,延时执行,async
渲染步骤 DOM->CSSOM->运行(内联)JS->重新构建DOM
外链JS,要先等待下载,执行再继续解析页面。
<script src=”…” async></script> 不阻塞DOM和CSSOM构建
- Blocking: <script src=”anExteralScript.js”></script>
- Inline: <script>document.write(“this is an inline script”)</script>
- Async: <script async src=”anExternalScript.js”></script>
另外:图片不阻塞DOM构建
下面来看一个实际的例子
<html> <head> <meta name="viewport" content="width=device-width,initial-scale=1"> <link href="style.css" rel="stylesheet"> </head> <body> <p>Hello <span>web performance</span> students!</p> <div><img src="awesome-photo.jpg"></div> <script src="app.js"></script> </body> </html>
第一次修改
<script src=”app.js” async></script>
第二次修改
<link href=”style.css” rel=”stylesheet” media=”print”>
不加载或者内联CSS
(PS:实际上,浏览器会提前下载资源,但是执行还是按照定义的顺序)
(PPS:浏览器会逐步解析、逐步渲染,这就是首屏内容可以单独优化的原因)
案例,分析一个网站的关键渲染路径
http://jslab.pro/demo/critical_rendering_path/index.html
http://jslab.pro/demo/critical_rendering_path/async.html
总结
关键渲染路径的定义
浏览器显示网页所必须的一系列事件。
优化方法
- 减少关键的资源
- 减少关键的字节数
- 减少关键的路径长度
附录
下面是收集的一些其他优化方法还有最佳实践。
优化步骤
先测量,找到瓶颈,再优化。
not all requests are made equal
not all bytes are made equal—— Paul Irish https://www.igvita.com/
优化技巧:
图片——就算页面有1000张图片,只加载关键的(首屏所需的)3张。其他的9997张都可以延迟加载或者滚屏加载(lazy Load)。
JavaScript文件——可以有100个JS文件,但是渲染头部只需要一个,就延迟加载剩下的99个。
CSS文件——可以有多种做法,合并请求、压缩文件、内联首屏样式
其他手段
异步加载HTML、HTML延迟渲染、内联CSS的缓存处理,减少首屏需要加载的字节数,控制首屏所需字节先加载(第一个14KB)
网页速度的度量
网页速度并不是页面展示下载的字节数,也不是整个页面的大小。要关注的是用户的体验,网页最快可用时间,或者首屏开始渲染时间,才是最重要的。
天猫首页源代码——2016年11月16日,首屏以外的DOM节点动态生成
淘宝首页源代码——2016年11月16日,inline关键CSS,其他CSS异步加载
参考链接:
Chrome Dev tools 查看页面加载
https://developers.google.com/web/tools/chrome-devtools/network-performance/resource-loading
学会看Chrome Dev tools 的 timeline
https://developers.google.com/web/tools/chrome-devtools/evaluate-performance/timeline-tool
一个资源的请求过程
above the fold 定义
https://en.wikipedia.org/wiki/Above_the_fold
https://www.smashingmagazine.com/2009/09/10-useful-usability-findings-and-guidelines/
延迟加载图片
https://varvy.com/pagespeed/defer-images.html
都有谁在阻塞渲染
https://www.keycdn.com/blog/blocking-the-dom/
阻塞渲染的CSS
https://varvy.com/pagespeed/render-blocking-css.html
阻塞渲染的JavaScript
https://varvy.com/pagespeed/render-blocking.html
async的支持情况(IE10+)
http://caniuse.com/#search=async
网络字体阻塞渲染
http://ianfeather.co.uk/web-fonts-and-the-critical-path/
优化首屏显示
https://varvy.com/pagespeed/prioritize-visible-content.html
First RTT 14KB
speed index 速度指标
https://sites.google.com/a/webpagetest.org/docs/using-webpagetest/metrics/speed-index
谷歌的 pagespeed insights 对图片有损压缩