CRP:critical rendering path 关键渲染路径
围绕渲染的机制和步骤,去详细的进行每一步的优化,以此来提高页面的渲染速度和运行性能
1.从服务器基于HTTP网络请求回来的数据
16进制的文件流<br />浏览器把它解析为字符串(HTML字符串)<br />按照w3c规则识别成为一个个的节点<br />生成DOM树
访问页面:首先请求回来的是HTML文档,浏览器开始自上而下渲染
进程:一般指一个程序(浏览器打开一个页面,相当于开了一个进程)
线程:进程中具体去执行事物的东西,一个线程同时只能干一件事情
一个进程中可能会包含一到多个线程
同步编程:
一般只有一个线程去处理事情,上面的事情处理不完,下面的事情无法处理「一件一件去干」
异步编程:
多线程异步编程
单线程异步编程 「js是Eventqueue+EvenLoop机制完成单线程异步编程」
浏览器是可以开启多个线程和进程的
GUI渲染线程:渲染页面
JS引擎线程:显然JS代码
HTTP网络线程,可以开辟N多个,从服务器获取资源和数据
定时器监听线程
DOM监听线程
渲染页面过程中
遇到style内嵌样式:GUI直接渲染即可「同步」
如果css代码量比较少,直接内嵌式即可,拉取HTML的时候,同时css也回来了,渲染的时候直接渲染了
但是如果css代码量比较多,如果还用内嵌,一方面会影响HTML的拉取速度,也不利于代码维护,此时还是外链比较好
遇到link:浏览器开辟一个HTTP线程去请求资源文件信息,同时GUI继续向下渲染「异步」
浏览器同时发送的HTTP请求数量是有限的(谷歌 5~7)
超过最大限制的HTTP请求需要排队等待
HTTP请求越少越好。。。
遇到@inport:浏览器也是开辟HTTP线程去请求资源,但是此时也暂停了,(导入式样式会阻碍GUI线程的渲染)当资源请求回来后,GUI才能继续渲染「同步」
真实项目中应该避免使用@import
遇到js
,会阻碍GUI的渲染,所以我们要把js放在底部
async:请求资源是异步的 [单独开辟HTTP去请求],此时GUI继续渲染;但是一但当JS请求回来,会立即处理GUIde处理,接下来去渲染js
defer:和link是类似的机制,不会阻碍GUI渲染当GUI渲染完,才会把请求回来的js去渲染
假如有5个js的请求,不设置任何属性,肯定是按照顺序请求和渲染js的,[依赖关系是有效的,但是如果设置async,谁先请求回来就渲染谁,依赖关系是无效的,如果使用defer是可以建立依赖关系的,(浏览器内部在GUI渲染完后,等待所有设置defer的资源都请求回来,在按照编写的依赖顺序去加载渲染js)]
注:如果你的js写在html末尾了,不需要加上面两个,如果写在开头和中间了,可以用
真实项目开发我们一般把link放在页面头部,目的为了在没有渲染dom的时候,就通知http去请求css了,这样DOM渲染完,css也差不多回来了,更有效的利用时间,提高页面的渲染速度;
我们一般把js放在页面的底部,防止其阻碍GUI的渲染,如果不放在底部,我们最好设置上async/defer
避免阻塞,解决阻碍问题:
window.addEventListener(‘load’, function(){
// 等待页面所有资源都加载完,才会触发执行
let box = document.getElementById(‘box);
console.log(box)
})
window.addEventListener(‘DOMContentLoaded’, function(){
// 等待DOM树渲染完即可,优先load触发
// 等同于 $(function(){}) / $(document).ready(function(){})
let box = document.getElementById(‘box);
console.log(box)
})
渲染流程及性能分析:
BOM TREE(DOMContentLoaded事件触发)=> [执行js] => CSSOM TREE => RENDER TREE渲染树[浏览器未来是按照这个树来控制页面的] => Layout布局计算「回流/重绘] Painting绘制 「分成绘制」
1.页面第一次渲染,必然会引发一次回流和重绘
2.如果我们改变了元素的位置和大小,浏览器会重新计算元素在是口中的位置和大小信息,重新计算的过程是回流/重排,一旦发生了回流操作,一定也会触发重绘 [ 很消耗新歌能,90%说的都是它 ]
3.但是如果只是一些普通样式的改变,位置和大小不变,只需要重绘即可
优化方案:
- 标签语义化和避免深层次嵌套
- css选择器渲染是从右到左
- 尽早尽快的把css下载到客户端(充分利用http多请求并发机制)
- style
- link
- @import
- 放到顶部
- 避免阻塞的js加载
- async
- defer
- 放到底部(推荐使用)
- 建设DOM得回流和重绘
transform 操作性能很高