当前位置: 移动技术网 > IT编程>开发语言>JavaScript > 浏览器如何渲染页面?

浏览器如何渲染页面?

2018年12月13日  | 移动技术网IT编程  | 我要评论
这里是修真院前端小课堂,每篇分享文从 【背景介绍】【知识剖析】【常见问题】【解决方案】【编码实战】【扩展思考】【更多讨论】【参考文献】 八个方面深度解析前端知识/技能,本篇分享的是: 【浏览器如何渲染页面?】 一、背景介绍浏览器是前端工程师或页面重构师工作中必不可少的,WEB页面运行在各种各样的浏览 ...

这里是修真院前端小课堂,每篇分享文从

【背景介绍】【知识剖析】【常见问题】【解决方案】【编码实战】【扩展思考】【更多讨论】【参考文献】

八个方面深度解析前端知识/技能,本篇分享的是:

【浏览器如何渲染页面?】

 
一、背景介绍
浏览器是前端工程师或页面重构师工作中必不可少的,web页面运行在各种各样的浏览器当中,浏览器载入、渲染页面的速度直接影响着用户体验,特别是浏览器渲染页面的原理,页面渲染就是浏览器将html代码根据css定义的规则显示在浏览器窗口中的这个过程,理解了原理就更会容易理解前端优化的一些准则。

二、知识剖析
2.1 reflow(回流)

说到页面为什么会慢?那是因为浏览器要花时间、花精力去渲染,尤其是当它发现某个部分发生了点变化影响了布局,需要倒回去重新渲染, 该过程称为reflow(回流)。

reflow几乎是无法避免的。现在界面上流行的一些效果,比如树状目录的折叠、展开(实质上是元素的显 示与隐藏)等,都将引起浏览器的reflow。鼠标滑过、点击……只要这些行为引起了页面上某些元素的占位面积、定位方式、边距等属性的变化,都会引起它内部、周围甚至整个页面的重新渲 染。通常我们都无法预估浏览器到底会reflow哪一部分的代码,它们都彼此相互影响着。

2.2 repaint(重绘)

如果只是改变某个元素的背景色、文 字颜色、边框颜色等等不影响它周围或内部布局的属性,将只会引起浏览器repaint(重绘)。repaint的速度明显快于reflow(在ie下需要换一下说法,reflow要比repaint更缓慢)。

下面是一个打开wikipedia时的layout/reflow的视频(注:html在初始化的时候也会做一次reflow,叫intial reflow),你可以感受一下:视频

三、常见问题
浏览器如何渲染页面?

四、解决方案
4.1浏览器工作大流程

先看图

 

 

1)浏览器会解析三个东西:

一个是html/svg/xhtml,事实上,webkit有三个c++的类对应这三类文档。解析这三种文件会产生一个dom tree。

css,解析css会产生css规则树。

javascript,脚本,主要是通过dom api(application programming interface)和cssom(css对象模型) api来操作dom tree和css rule tree.

2)解析完成后,浏览器引擎会通过dom tree和css rule tree来构造rendering tree。注意:

rendering tree渲染树并不等同于dom树,因为一些像header或display:none的东西就没必要放在渲染树中了。css的rule tree主要是为了完成匹配并把css rule附加上rendering tree上的每个element。也就是dom结点。也就是所谓的frame。然后,计算每个frame(也就是每个element)的位置,这又叫layout和reflow过程。

3)最后通过调用操作系统native gui的api绘制。

4.2 dom解析

 

 

上面这段html会解析成这样:

 

 

下面是另一个有svg标签的情况:

 

 

4.3 css解析

css的解析大概是下面这个样子(下面主要说的是firefox的玩法),假设我们有下面的html文档:

 

 

于是dom tree是这个样子

 

然后我们的css文档是这样的:

/* rule 1 */ doc { display: block; text-indent: 1em; }

/* rule 2 */ title { display: block; font-size: 3em; }

/* rule 3 */ para { display: block; }

/* rule 4 */ [class="emph"] { font-style: italic; }

于是我们的css rule tree会是这个样子:

 

 

注意:css匹配html元素是一个相当复杂和有性能问题的事情。所以,你就会在n多地方看到很多人都告诉你,dom树要小,css尽量用id和class,千万不要过渡层叠下去,……

通过这两个树,我们可以得到一个叫style context tree,也就是下面这样(把css rule结点attach到dom tree上):

 

 

所以,firefox基本上来说是通过css解析 生成css rule tree,然后,通过比对dom生成style context tree,然后firefox通过把style context tree和其render tree(frame tree)关联上,就完成了。注意:render tree会把一些不可见的结点去除掉。而firefox中所谓的frame就是一个dom结点,不要被其名字所迷惑了。

 

 

4.4渲染

渲染的流程基本上如下(黄色的四个步骤):

1)计算css样式;2)构建render tree;3)layout –定位坐标和大小,是否换行,各种position, overflow, z-index属性……;4)正式开画;

 

注意:上图流程中有很多连接线,这表示了javascript动态修改了dom属性或是css属会导致重新layout,有些改变不会,就是那些指到天上的箭头,比如,修改后的css rule没有被匹配到,等。

5.编码实战
详见视频

 

六、扩展思考
1.影响页面渲染速度主要因素有哪些?

reflow(回流)和repaint(重绘)

2.哪些情况下会导致reflow发生?

改变窗囗大小;改变文字大小;添加/删除样式表;内容的改变,如用户在输入框中敲字;激活伪类,如:hover (ie里是一个兄弟结点的伪类被激活);操作class属性;脚本操作dom;计算offsetwidth和offsetheight;设置style属性。

3.如何避免reflow(回流)?

reflow是不可避免的,只能将reflow对性能的影响减到最小。

1.尽可能限制reflow的影响范围。需要改变元素的样式,不要通过父级元素影响子元素。最好直接加在子元素上。

2.通过设置style属性改变结点样式的话,每设置一次都会导致一次reflow。所以最好通过设置class的方式。

3.减少不必要的dom层级(dom depth)。改变dom树中的一级会导致所有层级的改变,上至根部,下至被改变节点的子节点。这导致大量时间耗费在执行reflow上面。

4.避免不必要的复杂的css选择器,尤其是后代选择器(descendant selectors),因为为了匹配选择器将耗费更多的cpu。

七、参考文献
参考一:

参考二:

八、更多讨论
1.提高浏览器性能的方法还有哪些?

2.浏览器的主要功能有哪些?

3.哪款浏览器的综合性能最优?

 

 

“我们相信人人都可以成为一个工程师,现在开始,找个师兄,带你入门,学习的路上不再迷茫。

这里是技能树.it修真院:http://www.jnshu.com,初学者转行到互联网行业的聚集地。"

欢迎加it交流群565734203与大家一起讨论交流

 

如您对本文有疑问或者有任何想说的,请 点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网