这里是修真学院的前端小教室。每篇文章分享自【背景介绍】【知识分析】【常见问题】【解决方案】【编码实践】【扩展思考】【更多讨论】【参考文献】八篇深入剖析前端这方面的知识/技能,本文分享:【浏览器是如何渲染页面的?】一、背景介绍浏览器对于前端工程师或者页面重构师的工作来说是必不可少的。WEB页面运行在各种浏览器中,浏览器加载和渲染页面的速度直接影响用户体验。尤其是浏览器渲染页面的原理。页面渲染是按照CSS定义的规则在浏览器窗口中显示HTML代码的过程。如果理解了原理,就会更容易理解前端优化的一些准则。二、知识分析2.1回流(reflow)说到页面为什么慢?那是因为浏览器需要时间和精力去渲染,尤其是当它发现某个部分发生了变化,影响了布局时,就需要返回去重新渲染。这个过程称为回流(reflow)。回流几乎是不可避免的。界面上一些流行的效果,比如树状目录的折叠和展开(本质上是元素的显示和隐藏)等,都会导致浏览器回流。鼠标悬停、点击……这些行为只要引起页面上某些元素的占用区域、定位方式、边距等属性发生变化,就会引起其内部、周围乃至整个页面的重新渲染.通常我们无法预测浏览器会回流代码的哪一部分,它们都是相互影响的。2.2重绘(repaint)如果只是改变一个元素的背景颜色、文字颜色、边框颜色等,而不影响其周围或内部的布局属性,只会引起浏览器重绘(repaint)。repaint的速度明显比reflow快(IE下需要改,reflow比repaint慢)。下面是维基百科打开时的Layout/reflow视频(注意:HTML在初始化的时候也会做一次reflow,称为initialreflow),大家可以感受一下:Video3.FAQ浏览器是如何渲染页面的?4.解决方案4.1浏览器工作过程先看图1)浏览器会解析三样东西:一是HTML/SVG/XHTML。实际上,Webkit有三个C++类分别对应这三种类型的文档。解析这三个文件会生成一个DOMTree。CSS,解析CSS会生成一个CSS规则树。Javascript,脚本,主要通过DOMAPI(ApplicationProgrammingInterface)和CSSOM(CSSObjectModel)API来操作DOMTree和CSSRuleTree。2)解析完成后,浏览器引擎会通过DOMTree和CSSRuleTreeRenderingTree来构建。注意:RenderingTree渲染树不等同于DOM树,因为像Header或者display:none这样的东西不一定放在渲染树中。CSS的RuleTree主要是完成匹配,将CSSRule附加到RenderingTree上的每个Element上。那就是DOM节点。这就是所谓的框架。然后,计算出每个Frame(也就是每个Element)的位置,也称为layout和reflow过程。3)最后调用操作系统NativeGUI的API进行绘制。4.2DOM解析上面的HTML会这样解析:这里再用SVG标签来解析:4.3CSS解析CSS解析大概如下(下面主要是玩火狐),假设我们有如下HTML文档:所以DOM树看起来像这样然后我们的CSS文档看起来像这样:/rule1/doc{display:block;文本缩进:1em;}/rule2/title{display:block;字体大小:3em;}/rule3/para{display:block;}/rule4/[class="emph"]{font-style:italic;所以我们的CSS规则树将如下所示:注意:CSS匹配HTML元素是一件非常复杂且性能有问题的事情。所以,你会在很多地方看到很多人告诉你,DOM树要小,CSS尽量用id和class,不要过渡到向下层叠……通过这两棵树,我们可以得到一个样式名为Style的ContextTree如下(将CSSRule节点附加到DOMTree):所以,基本上,Firefox通过CSS解析生成CSSRuleTree,然后通过比较DOM生成StyleContextTree,以及然后Firefox通过将StyleContextTree与其RenderTree(FrameTree)关联起来生成StyleContextTree就完成了。注意:RenderTree会移除一些不可见的节点。Firefox中所谓的Frame就是一个DOM节点,不要被它的名字搞混了。4.4渲染渲染过程基本如下(黄色四步):1)计算CSS样式;2)构建渲染树;3)Layout——定位坐标和大小,是否换行,各种position,overflow,z-index属性……;4)正式图纸;注意:上面的过程中有很多连线,说明Javascript动态修改DOM属性或者CSS属性会导致重新布局,有些变化不会发生,就是那些指向天空的箭头,比如,修改后的CSS规则不匹配等。5.编码练习请参考视频。点这里六、延伸思考1、影响页面渲染速度的主要因素有哪些?回流(reflow)和重绘(repaint)2、什么情况下会发生回流?改变窗口的大小;更改文字大小;添加/删除样式表;改变内容,比如用户在输入框里打字;激活伪类,如:hover(在IE中激活一个兄弟节点的伪类);操纵类属性;脚本操作DOM;计算偏移宽度和偏移高度;设置样式属性。3、如何避免回流焊(reflow)?回流是不可避免的,回流对性能的影响只能降到最低。1、尽可能限制回流范围。需要改变元素的样式,不要通过父元素影响子元素。最好直接添加到子元素中。2.如果通过设置style属性改变节点样式,每次设置都会引起回流。所以最好设置类。3.减少不必要的DOM层次(DOM深度)。更改DOM树中的一个级别会导致所有级别的更改,上至根节点,下至更改节点的子节点。这导致大量时间花在执行回流上。4、避免不必要的复杂CSS选择器,尤其是后代选择器(descendantselectors),因为匹配选择器会消耗更多的CPU。7.参考资料参考资料1:浏览器渲染原理介绍参考资料2:为什么每个前端开发者都需要了解网页渲染?8.更多讨论1.还有哪些提高浏览器性能的方法?2、浏览器的主要功能有哪些?3.哪个浏览器的综合性能最好?》我们相信人人都可以成为工程师,现在就开始,找个师兄指导你入门,学习的路上不再迷茫,这里是技能树。IT修真学院:http:///www.jnshu.com,适合初学者切换到互联网行业的聚集地。”欢迎加入IT交流群565734203与大家一起探讨交流
