阅读更多

13顶
1踩

Web前端

转载新闻 浏览器的渲染原理简介

2013-05-22 11:41 by 副主编 WnouM 评论(3) 有17509人浏览
本文转载自酷壳,原文内容如下:

看到这个标题大家一定会想到这篇神文《How Browsers Work》,这篇文章把浏览器的很多细节讲得很细,而且也被翻译成了中文。为什么我还想写一篇呢?因为两个原因,

  • 这篇文章太长了,阅读成本太大,不能一口气读完。
  • 花了大力气读了这篇文章后可以了解很多,但似乎对工作没什么帮助。
所以,我准备写下这篇文章来解决上述两个问题。希望你能在上班途中,或是坐马桶时就能读完,并能从中学会一些能用在工作上的东西。

浏览器工作大流程

废话少说,先来看个图:



从上面这个图中,我们可以看到那么几个事:

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

  • 一个是HTML/SVG/XHTML,事实上,Webkit有三个C++的类对应这三类文档。解析这三种文件会产生一个DOM Tree。
  • CSS,解析CSS会产生CSS规则树。
  • Javascript,脚本,主要是通过DOM API和CSSOM 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绘制。

DOM解析

HTML的DOM Tree解析如下:

<html>
<html>
<head>
    <title>Web page parsing</title>
</head>
<body>
    <div>
        <h1>Web page parsing</h1>
        <p>This is an example Web page.</p>
    </div>
</body>
</html>

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




下面是另一个有SVG标签的情况。





CSS解析

CSS的解析大概是下面这个样子(下面主要说的是Gecko也就是Firefox的玩法),假设我们有下面的HTML文档:

<doc>
<title>A few quotes</title>
<para>
  Franklin said that <quote>"A penny saved is a penny earned."</quote>
</para>
<para>
  FDR said <quote>"We have nothing to fear but <span>fear itself.</span>"</quote>
</para>
</doc>


于是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会是这个样子:



注意,图中的第4条规则出现了两次,一次是独立的,一次是在规则3的子结点。所以,我们可以知道,建立CSS Rule Tree是需要比照着DOM Tree来的。CSS匹配DOM Tree主要是从右到左解析CSS的Selector,好多人以为这个事会比较快,其实并不一定。关键还看我们的CSS的Selector怎么写了。
注意: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结点,不要被其名字所迷惑了。





注:Webkit不像Firefox要用两个树来干这个,Webkit也有Style对象,它直接把这个Style对象存在了相应的DOM结点上了。

渲染

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

  • 计算CSS样式
  • 构建Render Tree
  • Layout – 定位坐标和大小,是否换行,各种position, overflow, z-index属性 ……
  • 正式开画





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

这里重要要说两个概念,一个是Reflow,另一个是Repaint。这两个不是一回事。

  • Repaint——屏幕的一部分要重画,比如某个CSS的背景色变了。但是元素的几何尺寸没有变。
  • Reflow——意味着元件的几何尺寸变了,我们需要重新验证并计算Render Tree。是Render Tree的一部分或全部发生了变化。这就是Reflow,或是Layout。(HTML使用的是flow based layout,也就是流式布局,所以,如果某元件的几何尺寸发生了变化,需要重新布局,也就叫reflow)reflow 会从<html>这个root frame开始递归往下,依次计算所有的结点几何尺寸和位置,在reflow过程中,可能会增加一些frame,比如一个文本字符串必需被包装起来。
附上一个打开Wikipedia时的Layout/reflow的视频(注:HTML在初始化的时候也会做一次reflow,叫intial reflow),你可以感受一下。视频地址:http://v.youku.com/v_show/id_XMzI5MDg0OTA0.html

Reflow的成本比Repaint的成本高得多的多。DOM Tree里的每个结点都会有reflow方法,一个结点的reflow很有可能导致子结点,甚至父点以及同级结点的reflow。在一些高性能的电脑上也许还没什么,但是如果reflow发生在手机上,那么这个过程是非常痛苦和耗电的。

所以,下面这些动作有很大可能会是成本比较高的。

  • 当你增加、删除、修改DOM结点时,会导致Reflow或Repaint
  • 当你移动DOM的位置,或是搞个动画的时候。
  • 当你修改CSS样式的时候。
  • 当你Resize窗口的时候(移动端没有这个问题),或是滚动的时候。
  • 当你修改网页的默认字体时。

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

多说两句关于滚屏的事,通常来说,如果在滚屏的时候,我们的页面上的所有的像素都会跟着滚动,那么性能上没什么问题,因为我们的显卡对于这种把全屏像素往上往下移的算法是很快。但是如果你有一个fixed的背景图,或是有些Element不跟着滚动,有些Elment是动画,那么这个滚动的动作对于浏览器来说会是相当相当痛苦的一个过程。你可以看到很多这样的网页在滚动的时候性能有多差。因为滚屏也有可能会造成reflow。

基本上来说,reflow有如下的几个原因:

  • Initial。网页初始化的时候。
  • Incremental。一些Javascript在操作DOM Tree时。
  • Resize。其些元件的尺寸变了。
  • StyleChange。如果CSS的属性发生变化了。
  • Dirty。几个Incremental的reflow发生在同一个frame的子树上。

好了,我们来看一个示例吧:

var bstyle = document.body.style; // cache
 
bstyle.padding = "20px"; // reflow, repaint
bstyle.border = "10px solid red"; //  再一次的 reflow 和 repaint
 
bstyle.color = "blue"; // repaint
bstyle.backgroundColor = "#fad"; // repaint
 
bstyle.fontSize = "2em"; // reflow, repaint
 
// new DOM element - reflow, repaint
document.body.appendChild(document.createTextNode('dude!'));


当然,我们的浏览器是聪明的,它不会像上面那样,你每改一次样式,它就reflow或repaint一次。一般来说,浏览器会把这样的操作积攒一批,然后做一次reflow,这又叫异步reflow或增量异步reflow。但是有些情况浏览器是不会这么做的,比如:resize窗口,改变了页面默认的字体,等。对于这些操作,浏览器会马上进行reflow。

但是有些时候,我们的脚本会阻止浏览器这么干,比如:如果我们请求下面的一些DOM值:

  • offsetTop, offsetLeft, offsetWidth, offsetHeight
  • scrollTop/Left/Width/Height
  • clientTop/Left/Width/Height
  • IE中的 getComputedStyle(), 或 currentStyle

因为,如果我们的程序需要这些值,那么浏览器需要返回最新的值,而这样一样会flush出去一些样式的改变,从而造成频繁的reflow/repaint。

减少reflow/repaint

下面是一些Best Practices:

1)不要一条一条地修改DOM的样式。与其这样,还不如预先定义好css的class,然后修改DOM的className。

// bad
var left = 10,
top = 10;
el.style.left = left + "px";
el.style.top  = top  + "px";
 
// Good
el.className += " theclassname";
 
// Good
el.style.cssText += "; left: " + left + "px; top: " + top + "px;";


2)把DOM离线后修改。如:

  • 使用documentFragment 对象在内存里操作DOM
  • 先把DOM给display:none(有一次repaint),然后你想怎么改就怎么改。比如修改100次,然后再把他显示出来。
  • clone一个DOM结点到内存里,然后想怎么改就怎么改,改完后,和在线的那个的交换一下。

3)不要把DOM结点的属性值放在一个循环里当成循环里的变量。不然这会导致大量地读写这个结点的属性。

4)尽可能的修改层级比较低的DOM。当然,改变层级比较底的DOM有可能会造成大面积的reflow,但是也可能影响范围很小。

5)为动画的HTML元件使用fixed或absoult的position,那么修改他们的CSS是不会reflow的。

6)千万不要使用table布局。因为可能很小的一个小改动会造成整个table的重新布局。

引用
In this manner, the user agent can begin to lay out the table once the entire first row has been received. Cells in subsequent rows do not affect column widths. Any cell that has content that overflows uses the ‘overflow’ property to determine whether to clip the overflow content.
Fixed layout, CSS 2.1 Specification

This algorithm may be inefficient since it requires the user agent to have access to all the content in the table before determining the final layout and may demand more than one pass.
Automatic layout, CSS 2.1 Specification


几个工具和几篇文章

有时候,你会也许会发现在IE下,你不知道你修改了什么东西,结果CPU一下子就上去了到100%,然后过了好几秒钟repaint/reflow才完成,这种事情以IE的年代时经常发生。所以,我们需要一些工具帮我们看看我们的代码里有没有什么不合适的东西。

  • Chrome下,Google的SpeedTracer是个非常强悍的工作让你看看你的浏览渲染的成本有多大。其实Safari和Chrome都可以使用开发者工具里的一个Timeline的东东。
  • Firefox下这个基于Firebug的叫Firebug Paint Events的插件也不错。
  • IE下你可以用一个叫dynaTrace的IE扩展。
最后,别忘了下面这几篇提高浏览器性能的文章:

参考

  • 大小: 57.6 KB
  • 大小: 36.7 KB
  • 大小: 44.1 KB
  • 大小: 17.9 KB
  • 大小: 13.2 KB
  • 大小: 24.1 KB
  • 大小: 10 KB
  • 大小: 68.2 KB
来自: 酷壳
13
1
评论 共 3 条 请登录后发表评论
3 楼 jueyue 2013-05-23 16:48
灰常经典.....................
2 楼 wingsrao 2013-05-23 15:13
good 。。太棒了。。
1 楼 linder0209 2013-05-23 11:20
不错不错,可以更好的理解浏览器的渲染过程。

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • Citrix-XenServer服务器虚拟化介绍.pptx

    " - Info-Tech Research Group,2011年 魔力象限"领导者" – 以先进特性和性价比闻名业界 - Gartner,2011年 Citrix-XenServer服务器虚拟化介绍全文共66页,当前为第8页。 Xen: 开源参考标准 Xen Citrix, Intel, AMD...

  • 信息检索服务系统的智能化与个性化(学习笔记)

    由于诸如以下原因致使目前一些搜索引擎并不有效:(1)Internet自身的动态性(2)Internet上信息的动态性(3)Internet上的信息与信息服务的多样性   1.搜索引擎的智能化智能化的搜索引擎与一般的搜索引擎的区别:(1)对用户提交的关键字的要求不同用户不仅可以提供搜索关键字,还可以加一些描述。(2)搜索引起的网络负荷不同

  • 《中国人工智能学会通讯》——4.11 智能信息服务应用领域

    4.11 智能信息服务应用领域 智能信息服务是信息化时代信息服务的趋势,在我们的日常生活中也不乏各种智能信息服务的例子。各领域的专家和领导人已经充分认识到智能信息服务为当今社会带来的不可估量的效益与便捷,并将其运用在所能服务的各个领域。 智能交通信息服务 社会交通公共基础建设的发展和不断完善为人们的出行带来了巨大便利,快捷的高速和四通八达的各级道路连接了...

  • 《电子商务概论》期末考试题总结

    一、填空 (每空1分,共15分) 1、互联网最基本的特征是 、 与廉价。 2、计算机网络系统由__________________、终端设备(Terminal)、___________________ 和通信线路四大部分构成。 3、随着计算机技术的发展,电子支付的工具越来越多,这些支付工具可以分为三大类:电子货币类、 ...

  • 2018软工实践第六次作业——团队选题报告

    "Jarvis For Chat"团队选题报告 组长博客链接 本次作业链接 NABCD在项目中的使用 N(Need,需求) QQ和微信已经成为人们社交的必需品,在QQ有7.8亿活跃用户,微信更是有10亿的活跃用户,这中间伴随着巨大的信息流,在大数据时代,信息是潜在的财富,监控和分析如此庞大的信息流无疑会带来巨大的收益。与此同时我们又要意识到,我们是普通人,我们不是腾讯,我们也不是网络警...

  • ESP32-CAM高性价比温湿度监控系统

    第一篇:ESP32-CAM高性价比WIFI图传方案快速入门教程 第二篇:ESP32-CAM第一个无线点灯程序 第三篇:ESP32-CAM智能网关的设计与实现 第四篇:ESP32-CAM创建热点构成并发式DNS服务器 第五篇:ESP32-CAM高性价比温湿度...

  • CSP-J复赛复习题目(NOIP普及组2000-2011)

    CSP-J复赛复习题目(NOIP普及组2000-2011) NOIP普及组复赛(某个不存在的比赛)2000-2011年的题面和样例 可以用来复习CSP-J 建议去OJ上查看并提交 祝大家CSP RP++ 文章目录CSP-J复赛复习题目(NOIP普及组2000-...

  • 微语录(2011-01-10---2011-01-16)

    我这周发布了34条微博,下面是我通过博客微语录应用筛选出来的微博 2011/0116 转发微博 11:22 任志强 :《明》王阳明《传习录》云:“凡人为学,终身只为这一事,自少至老,自朝自暮,不论有事无事,只是做得这一件...

  • Python双均线策略回测(2021-10-12)

    回测说明 回测标的:贵州茅台(600519.SH) 回测区间:2011.01.01-2021.10.08 代码说明:回测代码分成两块,一块是策略函数(Strategy),一块是评价函数(Performance),策略函数通过指数的收盘价构造信号,计算策略...

  • 一款高性价比的电力载波通信模块ES1642-C在物联网领域应用与设计

    总结一下这样一个性价比很高的电力载波模块非常适合在物联网应用,但是需要一个12V和3.3V的供电,3.3V供电需要使用MP2451DT芯片,应为提供2M的开关频率降低对载波模块的干扰,或者使用LDO也是不错的选择。...

  • 2021-10-08

    10月16日,阿里巴巴集团宣布,已向优酷土豆公司董事会发出非约束性要约,拟以每ADS(美国存托凭证)26.60美元的价格,现金收购除阿里巴巴集团已持有优酷土豆股份外,该公司剩余的全部流通股。 11月3日晚,阿里巴巴...

  • HCIA-IoT V2.5 华为物联网认证笔记

    尽管Cat.4支持更高速率,但对于物联网而言,性价比不如Cat.1 蜂窝通信对比 LPWA(Low Power Wide Area) 无线通信技术对比 2.3 NB-IoT技术及解决方案(重点) 2.3.1 NB-IOT商用情况 全球LPWA技术选择分布 全球NB-IoT...

  • 读书笔记《推荐系统实践》- 个性化推荐系统总结

    对于推荐系统,本文总结内容,如下图所示: 推荐系统.png 文章很长,你可以跳着看你感兴趣的部分。 一、什么是推荐系统 1. 为什么需要推荐系统 结论是,为了解决互联网时代下的信息超载问题。 看个数据: ...

  • 2021年中国1,4-丁二醇(BDO)市场供需分析,“限塑令”背景需求与价格持续提升「图」

    (对比近10年自产顺酐法BDO和炔醛法BDO两种方法的盈利情况,2010年附近,自产顺酐法BDO具备一定的盈利能力,尚有部分自产顺酐法BDO产能存在。2012年之后,自产顺酐法BDO长期处于盈亏平衡线以下,2014年以后自产顺酐法...

  • 微语录(2011-02-07---2011-02-13)

    我这周发布了82条微博,下面是我通过博客微语录应用筛选出来的微博 2011/0213 我刚加入了“51CTO”微群 http://sinaurl.cn/hbLUVq 推荐大家也来看看~ 18:18 Mark 18:10 Huihoo :Khan学院开放教育视频,超过2000多个...

  • Network 之三 Ethernet(以太网)物理介质(10Base、100Base-T、100Base-TX等)介绍

    为降低 10base5 的安装成本和复杂性而设计的。   10BASE2 这个名字来源于物理介质的几个特性:10 来自 10 Mbit/s 的传输速度; BASE 代表基带信令;2 代表最大段长度接近200米(实际最大长度为185米)。   其...

  • Wi-Fi理论基础概述

     Wi-Fi(Wireless Fidelity),在中文里又称作“行动热点”, 是Wi-Fi联盟(Wi-Fi Alliance,缩写为WFA)的商标,Wi-Fi联盟限制使用Wi-Fi认证这一术语来成功完成互操作性认证测试。严格得说,Wi-Fi是一个认证的名称...

  • IAP-应用内购买

    [-] In App Rage管理 In App PurchasesRetrieving Product List提取产品列表Subclassing for Your App添加帮助类代码显示产品列表给我钱看看In App Purchases Accounts and the Sandbox何去何从 ...

  • 【4-11】读书笔记 |《推荐系统实践》- 个性化推荐系统总结

    推荐系统实践 对于推荐系统,本文总结内容,如下图所示: 推荐系统.png 文章很长,你可以跳着看你感兴趣的部分。 一、什么是推荐系统 1. 为什么需要推荐系统 结论是,为了解决互联网时代下的信息超载问题...

  • 以太网详解(二)-物理介质(100base-TX等)介绍

    为降低10base5的安装成本和复杂性而设计的。   10BASE2这个名字来源于物理介质的几个特性:10来自10 Mbit / s的传输速度; BASE代表基带信令;2代表最大段长度接近200米(实际最大长度为185米)。   其使用...

Global site tag (gtag.js) - Google Analytics