Web渲染及性能优化
发布于 2018-06-23
作为一名 web 开发工程师,开发一个网页很简单,但是想开发出一个性能强加载速度快的网页却不是那么简单,涉及到的方面很多,比如服务端的响应,客户端加载、渲染,开发者代码的组织等等,很多因素都可能使你的页面性能不佳,今天根据我最近的学习,着重总结一下客户端渲染相关的优化建议和相关原理。
浏览器的渲染过程
浏览器的渲染过程非常的复杂,如果想讲清楚大概可以写一本书,比如《WebKit技术内幕》,但是长话短说,把浏览器的渲染过程总结一下可以分为下面几个步骤:
- DOM Tree生成:通过网络加载到浏览器的本地,经过HTML解析器处理,生成 DOM Tree
- CSS 规则生成:CSS 样式表经过 CSS 解析器的处理计算,生成最终的 CSS 规则
- javascipt的解析和执行:由于浏览器渲染是单线程的,javascript 的解析执行是在浏览器解析 HTML 过程中进行的,包括词法分析、抽象语法树、字节码以及本地代码的生成等过程
- 布局 Layout生成: DOM Tree 和 CSS ruler 经过一顿糅合的布局样式计算,形成 renderTree
- 绘制: 根据计算得来的renderTree,绘制每个元素的大小、边框、位置、阴影等效果,绘制的过程是分层进行的,比如图片和一些 Transform 效果都在不同的层进行绘制
- 合并:将绘制的各层进行合并渲染,最终体现在屏幕像素中
那么在这几个步骤中,我们怎样优化才能使性能有一个更好的提升呢?
性能优化建议
在页面渲染过程中,1到3的过程可能只执行一次,但是后面的4到6至少执行一次,所以为了更好的性能,应尽量减少后面的渲染触发
在 DOM Tree 生成阶段,我们应尽量减少 DOM 的层级
在 CSS 规则生成阶段,同理,为了更快的解析和计算,尽量简化规则样式
在 JavaScript 解析执行阶段,除了通过优化代码的编写,执行时机,对于计算量庞大的模块,应放在 Web Worker 中执行,避免因 javascript 的执行而导致 UI 渲染的卡顿与延迟
在布局阶段,除了上面提到的优化,尽量将 JavaScript 代码置于 body 标签底部,除了可以减少页面渲染的卡顿,还可以减少页面的不必要回流计算
在绘制合成阶段,我们要将频繁变动的组件或者动画提升至合成层进行渲染,并且动画尽量使用 css 的 transform 进行描述,而不是对元素的大小、位置属性进行重新赋值,导致多次回流与重绘,使用transform的原理是将这部分的渲染交给 GPU 来进行处理,极大的增强了渲染性能。
以上就是我对渲染相关的优化总结,上面的优化可以让浏览器更『轻松』的处理我们的 UI 效果,当然 web 的优化还有很多方面,单单是对浏览器内部的优化还不足以让用户有很大的感知,所以全方位的实际问题定位才是解决 web 体验的良方。