1. 浏览器的每一帧都需要做什么
浏览器在一帧内需要做的任务有:
- 接受用户的输入事件
- 执行事件回调
- 开始一帧
- 执行
rAF回调来绘制动画 - 见下方 2. 页面渲染过程
- 当一帧内执行完上述任务仍有空余时间时,会执行
rIC回调。
(了解)浏览器的刷新率表示一秒绘制多少帧,浏览器大多在60HZ,一帧时间约为16ms(1000ms / 60hz = 16.6)。
2. 页面渲染过程
- 解析
HTML文件生成DOM Tree。解析CSS文件生成CSSOM Tree(两者是并行的)。 - 将
DOM树和CSSOM树合并生成渲染树Render Tree。 - 遍历渲染树开始
layout布局,计算每个节点的位置大小信息。 - 将渲染树每个节点绘制到屏幕上。
3. 网页的正常加载流程、异步加载方式
浏览器在解析 HTML 文件时,如果遇到<script>标签就会暂停解析,将控制权交给 JS 引擎,等待 JS 文件下载(引用外部脚本时、默认同步加载)并执行完成后才会继续解析 HTML。
<script src="path/to/myModule.js" defer></script>
<script src="path/to/myModule.js" async></script>
为了防止 JS 阻塞 DOM 的解析而出现页面卡顿问题,可以将<script>放在 HTML 底部,或者添加async或defer属性。
defer 和 async 都可以实现异步加载脚本,此时会并行解析 HTML,它们的区别在于脚本下载完成后的执行时机:
- defer:等到 HTML 解析完成后再执行脚本。因此多个
defer脚本会顺序执行。 - async:当脚本下载完成后就会立即执行,执行完成后再去解析 HTML。因此多个
async脚本的执行顺序不确定。
注意:浏览器会一边下载 HTML,一边开始解析 HTML,不会等待下载完才执行。
4. CSS 和 JS 的阻塞
- CSS 不会阻塞 DOM 的解析,但会阻塞 DOM 的渲染和后面
js脚本的执行。(从2. 页面渲染过程去理解)-
不阻塞
dom解析:他们两个的解析是并行的。 -
阻塞
dom的渲染:因为渲染树是依赖于dom树和cssom树的,所以它要等待cssom树构建完成。 -
阻塞
js的执行:因为<script>会触发页面渲染,可能需要css来获取元素的样式等,所以要等待css加载完成。
-
- JS 会阻塞 DOM 的解析和渲染。
- 阻塞
dom解析:可以将<script>放在 html 底部,或者添加async或defer属性。 - 阻塞
dom渲染:从 JS 线程和 GUI 线程互斥来理解。
- 阻塞
5. reflow 回流/重排、repaint 重绘,什么情况下会触发
当元素的尺寸或位置发生变化时需要重新计算布局、绘制渲染UI,这就是回流。
触发回流的操作有:
- dom 元素的移动、增加、减少。
- dom 元素的几何属性或某些样式
width/height/padding/margin/border改变。 - 元素中的内容(文本内容/图片)发生变化时。
- 浏览器窗口大小变化。
当元素的某些样式发生变化但没有影响它的几何属性时,只需要重新绘制渲染 UI 即可、不用计算布局,这就是重绘。例如color、background-color、visibility等。
因此,回流一定重绘,但重绘不一定回流。
6. 性能优化:回流与重绘
- 使用
class 选择器一次性修改样式,而不要用style一项项的修改。通过合并多次修改来减少重排重绘的发生次数。 - 当隐藏元素时使用
opacity:0 优先于 visibility: hidden 优先于 display: none。依次为不触发回流重绘、只触发重绘、触发回流。 - 避免使用
table布局,因为一个改动会导致整个 table 的重新布局。 - 对
scroll、resize等事件进行防抖节流,因为这两者会导致回流。 - 动画元素使用
absolute或fixed定位来使它脱离文档流,这样可以减少对其他元素的影响、只回流重绘该动画。 - 使用虚拟 DOM 库。
注意:因为回流还需要重新计算 layout,所以回流的损耗高于重绘。
7. 加快首屏速度
首屏时间是指浏览器从响应用户输入到首屏内容渲染完成的时间,此时整个网页不一定要全部渲染完成,但当前视窗需要渲染完成。加快首屏渲染速度的方法有:
- 对文件进行压缩合并,能够减少加载时间和 HTTP 请求个数。
- 静态资源使用 CDN。
- 使用浏览器缓存来缩短资源加载时间。
- 图片懒加载
script标签中使用defer或async,来避免加载脚本时阻塞 HTML 解析。
(了解)白屏时间是指浏览器从响应用户输入到网页开始显示内容的时间。
8. 性能优化
以上均包括,再加上:
- 性能优化:重排重绘
- 当有大量数据需要渲染时,使用虚拟化长列表技术。
-
页面很卡时怎么分析? 内存泄漏、页面渲染不及时、页面内存占用过多、垃圾回收机制。
-
CDN 内容分发网络:是一组分布在不同地理位置的服务器。将源网站的资源分发给距离用户最近的服务器节点,能够提高网站的响应速度、及时地响应用户请求。
-
图片懒加载:只有当
<img>元素在可视区域中时src 属性才会赋值,否则为空值。怎么知道元素是否在可视区域中呢? 当
元素距离视窗顶部的距离 小于 视窗高度时说明元素在可视区域中。 -
减少 HTTP 请求个数:将多个小文件合并成一个大文件发送。因为完整的 HTTP 请求需要经历 DNS解析、TCP 连接等过程,实际下载时间只占总执行时间的小部分比例,所以合并成一个大文件减少浪费的时间。