【编者按】其实,有关网页渲染的文章很多,但是相关信息比较分散,且论述并不是很完整。如果要想对这个主题有个大致的了解,我们还得学习很多知识。因此,Web开发者Alexander Skutin决定写一篇文章。他相信,这篇文章不仅能帮助初学者,也能对那些想要刷新知识结构的高级前端开发者有所裨益。
以下为译文
网页渲染必须在很早的阶段进行,可以早到页面布局刚刚定型。因为样式和脚本都会对网页渲染产生关键性的影响。所以专业开发者必须了解一些技巧,从而避免在实践的过程中遇到性能问题。
这篇文章不会研究浏览器内部的详细机制,而是提出一些通用的规则。毕竟,不同浏览器引擎的工作机制各不相同,这无疑会让开发者对浏览器特性的研究变得更加复杂。
浏览器是如何完成网页渲染?
首先,我们回顾一下网页渲染时,浏览器的动作:
当用户与网页交互,或者脚本程序改动修改网页时,前文提到的一些操作将会重复执行,因为网页的内在结构已经发生了改变。
Repaint
当改变那些不会影响元素在网页中的位置的元素样式时,譬如background-color(背景色),border-color(边框色),visibility(可见性),浏览器只会用新的样式将元素重绘一次(这就是重绘,或者说重新构造样式)。
Reflow
当改变影响到文本内容或结构,或者元素位置时,重排或者说重新布局就会发生。这些改变通常由以下事件触发:
浏览器如何优化渲染?
浏览器尽可能将repaint/reflow限制在被改变元素的区域内。比如,对于位置固定或绝对的元素,其大小改变只影响元素本身及其子元素,然而,静态定位元素的大小改变会触发后续所有元素的重流。
另一种优化技巧是,在运行几段JavaScript代码时,浏览器会缓存这些改变,在代码运行完毕后再将这些改变经一次通过加以应用。举个例子,下面这段代码只会触发一个reflow和repaint:
然而,如前所述,改变元素的属性会触发强制性的重排。如果我们在上面的代码块中加入一行代码,用来访问元素的属性,就会发生这种现象。
其结果就是,重排发生了两次。因此,你应该把访问元素属性的操作都组织在一起,从而优化网页性能。([你可以在JSBin查到更为详细的例子](http://jsbin.com/duhah/2/edit?html,css,js,output))
有时,你必须触发一个强制性重排。比如,我们必须将同样的属性(比如左边距)两次赋值给同一个元素。起初,它应该设置为100px,且不带动效。接着,它必须通过过渡(transition)动效改变为50px。你现在可以在[JSbin](http://jsbin.com/duhah/2/edit?html,css,js,output)上学习这个例子,不过我会在这儿更详细地介绍它。
首先,我们创建一个带过渡效果的CSS类:
然后继续执行:
然而,这个执行无法奏效。所有改变都被缓存,只在代码块末尾加以执行。我们需要的是强制性的重排,我们可以通过以下更改加以实现:
现在代码如预期那样执行了。
有关性能优化的实际建议
总结现有的资料,我提出以下建议:
你应该记住,浏览器在处理选择器时依照从右到左的原则,因此最右端的选择器应该是最快的:#id或则.class:
关于译者:张超,OneAPM前端工程师,负责Browser Insight产品开发。深度了解浏览器内核,前端技术“死忠粉”,具备多年浏览器性能优化经验。
想了解更多的细节问题,大家也可以看看这两篇文章: