浏览器渲染页面流程

下面是渲染引擎在取得内容之后的基本流程:

解析HTML以构建dom树-构建render树-布局render树-绘制render树

下面是 浏览器渲染页面的具体过程:

1.浏览器解析html源码,然后创建一个 DOM树。(所谓dom树指:浏览器将HTML解析成树形的数据结构。
在DOM树中,每一个HTML标签都有一个对应的节点,并且每一个文本也都会有一个对应的文本节点。DOM树的根节点就是 documentElement,对应的是html标签。

2.浏览器解析CSS代码,计算出最终的样式数据。构建CSSOM树。(CSS Rule Tree:浏览器将CSS解析成树形的数据结构。
对CSS代码中非法的语法它会直接忽略掉。解析CSS的时候会按照如下顺序来定义优先级:浏览器默认设置 < 用户设置 < 外链样式 < 内联样式 < html中的style。

3.DOM Tree + CSSOM --> 渲染树(rendering tree)。(DOM和CSSOM合并后生成Render Tree。
渲染树和DOM树有点像,但是是有区别的。DOM树完全和html标签一一对应,但是渲染树会忽略掉不需要渲染的元素,比如head、display:none的元素等。而且一大段文本中的每一个行在渲染树中都是独立的一个节点。渲染树中的每一个节点都存储有对应的css属性。

4.有了Render Tree,浏览器已经能知道网页中有哪些节点、各个节点的CSS定义以及他们的从属关系,从而去计算出每个节点在屏幕中的位置。

5.最后按照算出来的规则,通过显卡,把内容画到屏幕上。

以上五个步骤并不是一次性顺序完成的。如果DOM或者CSSOM被修改,以上过程会被重复执行。实际上,CSS和JavaScript往往会多次修改DOM或者CSSOM。

这也就是行内常说的重绘和重排,所以怎么解释重绘和重排呢?

重绘和重排(repaints and reflow)

reflow(回流):回流即重排哈、当浏览器发现某个部分发生了点变化影响了布局,需要倒回去重新渲染,内行称这个回退的过程叫 reflow。reflow 会从 <html> 这个 root frame 开始递归往下,依次计算所有的结点几何尺寸和位置。reflow 几乎是无法避免的。现在界面上流行的一些效果,比如树状目录的折叠、展开(实质上是元素的显 示与隐藏)等,都将引起浏览器的 reflow。鼠标滑过、点击……只要这些行为引起了页面上某些元素的占位面积、定位方式、边距等属性的变化,都会引起它内部、周围甚至整个页面的重新渲 染。通常我们都无法预估浏览器到底会 reflow 哪一部分的代码,它们都彼此相互影响着。

repaint(重绘):改变某个元素的背景色、文字颜色、边框颜色等等不影响它周围或内部布局的属性时,屏幕的一部分要重画,但是元素的几何尺寸没有变。

每个页面至少在初始化的时候会有一次重排操作。任何对渲染树的修改都有可能会导致下面两种操作:
1.重排就是渲染树的一部分必须要更新 并且节点的尺寸发生了变化。这就会触发重排操作。
2.重绘部分节点需要更新,但是没有改变他的集合形状,比如改变了背景颜色,这就会触发重绘。什么情况下会触发重绘或重排
记住,重排必然会引起重绘

下面任何操作都会触发重绘或者重排:

  • 增加或删除DOM节点设置 display: none;(重排并重绘) 或visibility: hidden(只有重排)
  • 移动页面中的元素)(重绘并重排)
  • 增加或者修改样式用户(重绘并重排)
  • 改变浏览器的字体大小(重绘并重排)
  • 改变浏览器的字体颜色或元素的背景颜色(只重绘,不重排)
  • 改变窗口大小(重绘并重排)
  • 滚动页面等(重绘并重排)

注意:(1)display:none 的节点不会被加入Render Tree,而visibility: hidden 则会,所以,如果某个节点最开始是不显示的,设为display:none是更优的。

     (2)display:none 会触发 reflow,而 visibility:hidden 只会触发 repaint,因为没有发现位置变化。

   (3)有些情况下,比如修改了元素的样式,浏览器并不会立刻reflow 或 repaint 一次,而是会把这样的操作积攒一批,然后做一次 reflow,这又叫异步 reflow 或增量异步 reflow。但是在有些情况下,比如resize 窗口,改变了页面默认的字体等。对于这些操作,浏览器会马上进行 reflow。

既然了解了重绘和重排之后,那么怎样通过减少重绘和重排进而提高页面的性能呢?其实这个我之前有看过雅虎军规,所以想要了解更多的请点击雅虎前端35条军规

那我们就稍微提一嘴,增强理解同时也可以更好的记忆吧

减少重绘和重排

 (1)不要一条一条地修改 DOM 的样式。与其这样,还不如预先定义好 css 的 class,然后修改 DOM 的 className。
var left = 10,    top = 10;
el.style.left = left + "px";
el.style.top  = top  + "px"; 
// 上面的是不提倡的,建议使用下面的方法
el.className += " theclassname";

 (2)不要把 DOM 结点的属性值放在一个循环里当成循环里的变量。 
 (3)为动画的 HTML 元件使用 fixed 或 absoult 的 position,那么修改他们的 CSS 是不会 reflow 的。 
 (4)千万不要使用 table 布局。因为可能很小的一个小改动会造成整个 table 的重新布局。

我记得雅虎军规中有一条:建议将js代码放在最后也就是body的前面,将css样式表放在head中,当时还不理解,现在终于明白了,请看

Javascript的加载和执行的特点: 
(1)载入后马上执行; 
(2)执行时会阻塞页面后续的内容(包括页面的渲染、其它资源的下载)。原因:因为浏览器需要一个稳定的DOM树结构,而JS中很有可能有 代码直接改变了DOM树结构,比如使用 document.write 或 appendChild,甚至是直接使用的location.href进行跳转,浏览器为了防止出现JS修 改DOM树,需要重新构建DOM树的情况,所以 就会阻塞其他的下载和呈现。

减少 JavaScript 对性能的影响的方法:

  1. 将所有的script
  2. 标签放到页面底部,也就是body闭合标签之前,这能确保在脚本执行前页面已经完成了DOM树渲染。
  3. 尽可能地合并脚本。页面中的script标签越少,加载也就越快,响应也越迅速。无论是外链脚本还是内嵌脚本都是如此。
  4. 采用无阻塞下载 JavaScript 脚本的方法: 
    (1)使用script标签的 defer 属性(仅适用于 IE 和 Firefox 3.5 以上版本); 
    (2)使用动态创建的script元素来下载并执行代码;




  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值