浏览器解析过程

一:浏览器高层结构

1.1:浏览器结构图

在这里插入图片描述

  • 1:user interface :浏览器交互界面
  • 2:browser engine:浏览器引擎:接收用户界面指令传给解析引擎
  • 3:render engine:呈现引擎:负责显示请求的内容。如果请求的内容是 HTML,它就负责解析 HTML和 CSS 内容,并将解析后的内容显示在屏幕上
  • 4:network:网络,传输网络资源
  • 5:js :javascript interprete js解析器
  • 6:ui backend:用于绘制基本的窗口小部件
  • 7:database :数据存储引擎
1.2:浏览器render引擎

firefox是以gekco引擎,chrome和safari是以webkit引擎
在这里插入图片描述

二:浏览器渲染页面到屏幕上的主流程

2.1:两种引擎的渲染过程很相似,本文以webkit为例,过程如下:

在这里插入图片描述

2.2:如何在浏览器中查看上面的过程呢?

结合 chrome的timeline,可以看到网页解析的过程如下:
在这里插入图片描述
1:receive response,receive data:接收请求返回资源
2:parse html:html dom节点的解析
3:recalculate style :生成渲染树(渲染树与dom树不同的地方在于,dom树会把所有的dom节点都展示出来,渲染树只会展示display非none的元素)
4:layout :将渲染树上的节点,根据它的高度,宽度,位置,为节点生成盒子(layout)。
5:paint:确定渲染树上的节点的大小和位置后,便可以对节点进行涂鸦(paint)
6:composite layer:合成层;当渲染树上的节点涂鸦完毕后,便生成位图(bitmap),浏览器把此位图从CPU传输到GPU
跟css相关的部分从layout开始,经过paint,最终再composite layer 生成位图。

三:影响渲染过程的css属性

3.1 layout:布局

影响layout布局的css属性如图
在这里插入图片描述

1:盒子盒模型,所以跟盒模型相关的属性的修改都会触发layout
2:位置(postition,float)相关
3:跟获取client的属性:clientHeight,clientWidth,clientTop,clientLeft
4:跟获取offset的属性:offsetHeight,offsetWidth,offsetTop,offsetLeft
5:跟获取scroll的属性:scrollHeight,scrollWidth,scrollTop,scrollLeft

3.2 paint步骤:绘制

3.2.1 paint

paint顾名思义,涂鸦,绘制,所以跟color(fontcolor,background-color)相关
打开chrome的开发者工具,按下“esc”,会弹出如下界面
在这里插入图片描述

  • 勾选show paint rectangles选项
  • 可以看到页面上绘制区域。
3.2.2 主要有2大类交互可触发paint

在这里插入图片描述

  1. 页面滚动(scroll,实际上跟layout有关系,layout的改变必定会触发paint阶段:即重绘)
  2. 互动操作
  • Dom节点被Javascript改变,导致Chrome重新计算页面的layout。

解析:dom节点增加,删除,位置移动,展示与否等操作,会引起DOM树变化(html parse阶段)或 CSS 树变化(dom + css
render阶段);

  • 用户交互/激活 CSS 伪类

解析:如hover导致某些元素页面样式的变化。而若样式中有跟paint阶段相关的,则会触发重绘

  • 调整窗口大小 和 改变字体

解析:窗口大小改变时,可看到绿色的重绘区域在变化,截图如下:

  • 内容变化

简单脑补(根据 W3C 的 HTML DOM 标准,HTML 文档中的所有内容都是节点,dom节点中的文本成为文本节点)
解析:比如用户在input框中输入文字,修改的是DOM结构,所以触发的layout,paint和composite layer三个阶段

  • 计算 offsetWidth 和 offsetHeight 属性

解析:offsetxxx,scrollxxx,clientxxx跟元素的位置相关,所以首先触发的是layout阶段,再触发paint,compostie
layer。

  • 增加或者移除样式表

解析:若修改的样式表跟css盒模型相关的,会触发layout阶段,paint,composite layer随即触发。

3.3 composite layer: 合成图层

3.3.1 如何创建layer

在这里插入图片描述

1):3D 或透视变换(perspective transform) CSS 属性
2):使用加速视频解码的
3):拥有 3D (WebGL) 上下文或加速的 2D 上下文的
4):混合插件(如 Flash)
5):对自己的 opacity 做 CSS 动画或使用一个动画 webkit 变换的元素
6):拥有加速 CSS 过滤器的元素
7):元素有一个包含复合层的后代节点(换句话说,就是一个元素拥有一个子元素,该子元素在自己的层里)
8):元素有一个 z-index 较低且包含一个复合层的兄弟元素(换句话说就是该元素在复合层上面渲染)
9):在webkit内核的浏览器中,如果有上述情况,则会创建一个独立的layer。

3.3.2 拒绝layer泛滥

当对元素创建layer之后,会节省layout和paint阶段,但是layer不能泛滥。
layer跟psd中图层很像,我们知道在psd中图层越多,psd图片就会越大。
同理,layer越多,占用的内存就越多,当在内存有限的移动设备上(手机),过多的渲染带来的开销超过了它在性能上的改善,得不偿失;
白白的给元素添加layer,一般通过* {-webkit-transform: translateZ(0);}为元素添加layer
但创建layer的原则:当且仅当需要的时候才为元素创建渲染层。

四:渲染三阶段分别注意的事项

渲染分为三阶段:layout,paint,composite layer,修改不同的css属性会触发不同的阶段,触发的阶段越靠前,渲染的代价越高。

1:尽量避免触发layout(位置相关的可通过transform代替 top left),paint。 除写css属性外,读取css的位置大小相关属性会导致触发layout阶段,要分离读写,减少layout。
2:应该尽量避免重绘,并且尽可能的使绘制区域最小,以提升页面性能。 但是有些必须使用的样式效果还是要用的,比如fixed等重要的是作为前端人员,能够预估这些代码所带来的性能损耗及所造成的影响。
3:避免组合触发 比如滚动和hover效果,hover中若使用border-shadow,border-style修改,则会损耗较大的性能,有可能会触发丢帧的现象。 改进办法:在滚动时,增加计时器,可先把hover效果禁掉,滚动结束后再打开hover效果。

五:setTimeout/setInterval PK requestAniamtionFrame(rAF)

requestAnimationFrame是一个监听帧的API,即每绘制完一帧后就执行一下requestAnimationFrame函数。

 //setTimeout/setInterval使用方法
var loop = setInterva(function(){
        if(){
            clearInterval(loop);
            loop = null;
        }else{
           //to do
        }
    }, 20);

rAF使用方法

var loop = function(){
        if(){
            // to do
            requestAnimationFrame(loop);//有没有超简单?
        }
    };

rAF何时执行下一帧即何时执行回调? rAF不是自己指定回调函数运行的时间,而是跟着浏览器内建的刷新频率来执行回调,这当然就能达到浏览器所能实现动画的最佳效果 rAF PK setTimeout/setInterval?
在这里插入图片描述

六:GPU硬件加速

6.1如何开启GPU硬件加速

CSS的 animations, transforms 以及 transitions 不会自动开启GPU加速,而是由浏览器的缓慢的软件渲染引擎来执行。

大部分的浏览器提供了触发GPU加速的CSS规则, 浏览器检测到页面中某个DOM元素应用了这些CSS规则时就会开启GPU硬件加速,最显著的css规则是元素的3D变换。 所以,网站上会看到某些节点有下面的似乎没有用的属性出现:

transformZ(0); transform3d(0,0,0)不要小看这些属性,他们可以让拥有这个属性的元素生成单独的composite layer。这样,不管这个元素的大小,位置等变换,都不会触发layout和paint阶段,直接执行composite layers (合成图层)阶段,浏览器会把这个合成图层layer当做位图上传到GPU。 GPU硬件加速后节省的时间:

1:cpu进行layout,paint的时间;
2:CPU向GPU传输位图的时间

七:如何查看页面中最耗性能的节点

打开chrome调试工具,再按esc键,出现以下界面
在这里插入图片描述

1:show paint rectangle :显示可绘制区域
2:show composited layer borders:显示layer
3:show FPS borders:显示一帧耗费的时间(60帧/秒是最优效果,即一帧16.6ms)
4:enable continuous page repainting:使页面持续重绘
5:show potential scoll bottlenecks:(shows areas of the page that slow down scrolling)展示可能会减慢页面滚动的区块

勾选4:enable continuous page repainting

1):打开Elements面板,使用上下左右来切换选择DOM,然后按下快捷键H来hide或者显示元素,同时观察每帧渲染时间。

2):如何某个元素按下H键后,帧时间会突然下降,则说明这个元素中有比较耗时的css属性,找到节点中css属性。

3):依次取消面板中的CSS样式再观察每帧渲染时间,找出影响元素渲染帧时间的css属性。

实践:用上面的方法,找出这个页面http://css3exp.com/moon/ 中最消耗性能的节点及样式

答案:body:background wrap:box-shadow

八:参考资料

浏览器引擎工作机制:http://www.cnblogs.com/luluping/archive/2013/04/05/3000461.html render树与css:http://www.cnblogs.com/luluping/archive/2013/04/05/3000460.html 浏览器工作原理:http://www.html5rocks.com/zh/tutorials/internals/howbrowserswork/

原文来自:https://www.cnblogs.com/quincyWang/p/6932382.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值