前言
复习经典面试题
浏览器从获取HTML文件直到浏览器以像素点的方式在屏幕中绘制出页面的内容,这期间所经历的一系列步骤,叫做关键渲染路径(Critial Rendering Path)。
简单说下浏览器渲染页面的过程
1. 根据HTML结构构建DOM树
当我们打开一个网页后,浏览器会去向服务器请求对应的HTML文件,然而浏览器得到的是字节内容的HTML文件,于是浏览器将字节转换为字符,也就是我们写的HTML代码
但是这些代码我们看得懂,但是计算机看不懂,需要转换为计算机看得懂的语言,于是浏览器将字符转换为Token,可以将这里的Token理解为标签,例如将
<div>转换为起始标签,将</div>转换为结束标签,这样字符就被Token化了,这样一来,计算机就能根据Token生成节点对象Node,将所有节点对象Node连在一起,就构成了一棵树,我们把它叫做DOM树
2. 构建CSSOM树
CSSOM是DOM结构上的样式的一种表示方式,浏览器在解析到<link>标签时,会根据href向服务器发送请求得到CSS文件,后面流程与DOM树的构建流程相似
3. 构建渲染树Render Tree
当构建完DOM和CSSOM后,浏览器就会将这两棵树整合为渲染树Render Tree
4. 布局(回流)
当构建完渲染树后,浏览器就会根据渲染树进行布局
浏览器会获取渲染树的结构、节点位置和大小,根据盒子模型进行排列和嵌套
5. 渲染
渲染树的任务就是匹配DOM和CSSOM的节点,并且捕获可见内容,将捕获到的可见内容渲染到页面中
解析遇到link、script、img等标签会不会阻塞浏览器渲染
遇到link标签请求CSS文件的同时不会阻塞html解析,但会阻塞渲染,因为渲染树的构建需要DOM和CSSOM,两者缺一不可
遇到script标签时会停止构建DOM,因为JS可以操作DOM和CSSOM,因此浏览器需要构建完DOM和CSSOM再执行JS,否则会出现某些元素出现了又消失的情况,这也就是为什么要将script标签放在body标签底部的原因
请求JS文件时,实际操作中先得到CSS文件还是JS文件要看具体情况,但如果先得到并且解析完成JS文件也会发生阻塞,因为我们必须等到CSSOM构建完成后才能执行JS文件,因为渲染树要DOM和CSSOM构建完成后才能构建,而且JS是能操控CSS样式的。
不过在解析CSS文件并且构建CSSOM的时候,浏览器是可以下载并解析JS文件,等CSSOM构建完成后就可以执行JS文件了。
解析遇到display: none;会不会进入渲染流程
渲染树是最终能渲染到页面的元素的树形结构表示。也就是说,浏览器在解析时遇到display: none;的元素会放入DOM树,但不会进入渲染树
什么叫重绘?什么叫回流?
重绘 (repaint)
重绘是当元素只需要更改外观、风格,而不会影响布局的。比如更改background-color,就叫做重绘
回流 (reflow)
回流是当元素需要更改尺寸、布局时,需要重新构建渲染树的过程
区别
- 回流一定会引发重绘,而重绘不一定会引发回流。比如只改变
color就只会发生重绘而不会引起回流 - 回流所需的开销比重绘多,渲染树上需要重新构建的节点越多,开销越大 也就是说重绘和回流在很大程度上影响了浏览器的性能
让文档脱离文档流有哪些方法?
- float
- absolute
- fixed
减少重绘和回流,提高性能
作为开发人员,应该尽可能节省内存,优化浏览器性能,提高用户体验度,不要为了一时的刺激搞一些花里胡哨的动画(说的就是你:产品经理)。答应我,对浏览器好一些
1. 用visibility: hidden; 代替 display: none;
它们两者的区别是:visibility: hidden;是隐藏某个元素,但隐藏的元素仍需占用位置,会进入渲染树。而display: none;是让某个元素彻底消失,不占用原来的位置,并且不会进入渲染树。
也就是说在使用display: none;切换显示时,页面会产生回流,重新构建节点,对性能影响很大,而我们使用visibility: hidden;在切换显示的时候只会引起重绘而不会引起回流,对浏览器较为友好。
2. 少用或不用表格<table></table>
表格元素总是牵一发而动全身,可能一个很小的改动会造成整个表格的重新布局,开销很大
3. CSS选择器避免层级过多
.nav-bar div p span {
font-size: 16px;
}
CSS的读取顺序为从右向左,也就是说:先找到所有的span,从第一个span开始沿着span的父元素查找p,如果中途找到了符合的节点就加入结果集,如果直到根元素html都没有符合条件的话,就从下一个span开始重复这个过程。如果层级过多则会增大浏览器的开销,所以应该尽量避免这种"套娃"的行为