一、页面渲染过程
(1)总体过程
(2)页面渲染五步
1. HTML → DOM树 (解析html)
浏览器会将HTML解析成一个DOM树,DOM树的构建过程是一个深度遍历过程,当前节点的所有子节点都构建好后才会去构建当前节点的下一个兄弟节点。
[1]解码:浏览器从磁盘或网络读取HTML的原始字节,然后将其转换为相应字符
[2]令牌化:浏览器把字符转化成W3C、HTML5 标准指定的各种确切的令牌(标签)
[3]词法分析:生成的令牌转化为对象
[4]DOM树构建:最后,创建的对象在树状的数据结构中互相链接
2. CSS → CSSOM树(解析CSS样式)
CSSOM全称为CSS对象模型CSS Object Model,CSSOM告诉了浏览器元素在渲染时是什么样的。我们重复与处理 HTML 非常相似的过程:
Bytes -> Characters -> Tokens -> Nodes -> CSSOM
3. 生成渲染树Render Tree (计算可见节点和样式)
Render Tree有如下特点:
-
不包括Header 、 script 、meta 等不可见的节点;
-
某些通过 CSS 隐藏的节点在渲染树中也会被忽略,比如应用了 display:none 规则的节点,而visibility: hidden只是视觉不可见,仍占据空间,不会被忽略。
4. layout布局
根据render树,浏览器可以计算出网页中有哪些节点,各节点的CSS以及从属关系,然后可以计算出每个节点在屏幕中的位置
5. painting绘制
遍历render树进行绘制页面中的各元素
二、display:none visibility:hidden opacity:0 区别
display: none;
-
DOM 结构:浏览器不会渲染 display 属性为 none 的元素,不占据空间;
-
事件监听:无法进行 DOM 事件监听;
-
性能:动态改变此属性时会引起重排,性能较差;
visibility: hidden;
-
DOM 结构:元素被隐藏,但是会被渲染不会消失,占据空间;
-
事件监听:无法进行 DOM 事件监听;
-
性能:动态改变此属性时会引起重绘,性能较高;
opacity: 0;
-
DOM 结构:透明度为 100%,元素隐藏,占据空间;
-
事件监听:可以进行 DOM 事件监听;
-
性能:提升为合成层,不会触发重绘,性能较高;
三、js和css是否阻塞dom的渲染
1、CSS 不会阻塞 DOM的解析,但会阻塞DOM渲染:
【1】**CSS 不会阻塞 DOM的解析:**浏览器是解析DOM生成DOM Tree,结合CSS生成的CSSOM Tree,最终组成Render Tree,再渲染页面。由此可见,在此过程中CSS完全无法影响DOM Tree的解析。
【2】**CSS会阻塞DOM渲染:**如果没有这个策略,页面首先会呈现出一个原始的模样,待CSS下载完之后又突然变了一个模样,用户体验可谓极差,而且渲染是有成本的。
2、JS代码阻塞 DOM 解析,但浏览器会预先下载相关资源
四、defer和async的区别
defer 和 async 在网络读取(下载)这块儿是一样的,都是异步的(相较于 HTML 解析),它俩的差别在于脚本下载完之后何时执行:
[1]defer是“渲染完再执行”;如果有多个defer脚本,会按照它们在页面出现的顺序加载.
[2]async是“下载完就执行”;多个async脚本是不能保证加载顺序的,脚本的加载和执行是紧紧挨着的,所以不管你声明的顺序如何,只要它加载完了就会立刻执行
因此若前后js文件存在依赖关系时,利用async推迟脚本执行时间可能会出现问题!!!!!