《不同内核浏览器的差异以及浏览器渲染简介》
前⾔
转⾃博客园
原⽂
⼀、简单介绍⼀下什么是浏览器内核。
浏览器最重要或者说核⼼的部分是“Rendering Engine”,可⼤概译为“解释引擎”,不过我们⼀般习惯将之称为“浏览器内核”。负责对⽹页语法的解释(如HTML、JavaScript)并渲染(显⽰)⽹页。
所以,通常所谓的浏览器内核也就是浏览器所采⽤的渲染引擎,渲染引擎决定了浏览器如何显⽰⽹页的内容以及页⾯的格式信息。
不同的浏览器内核对⽹页编写语法的解释也有不同,因此同⼀⽹页在不同的内核的浏览器⾥的渲染(显⽰)效果也可能不同,这也是⽹页编写者需要在不同内核的浏览器中测试⽹页显⽰效果的原因。
浏览器内核很多,如果加上所有的⼏乎没有什么⼈在⽤的⾮商业的免费内核,那么可能⼤约有10款以上甚⾄更多,不过通常我们⽐较常见的⼤约只有以下四种,下⾯先简单介绍⼀下。
Trident:
IE浏览器使⽤的内核,该内核程序在1997年的IE4中⾸次被采⽤,是微软在Mosaic代码的基础之上修 改⽽来的,并沿⽤到⽬前的IE9。
Trident实际上是⼀款开放的内核,其接⼝内核设计的相当成熟,因此才有许多 采⽤IE内核⽽⾮IE的浏览器涌现(如 Maxthon、The World 、TT、GreenBrowser、AvantBrowser等)。
此外, 为了⽅便也有很多⼈直接简称其为IE内核(当然也不排除有部分⼈是因为不知道内核名称⽽只好如此说)。
由于IE本⾝的“垄断性”(虽然名义上IE并⾮垄断,但实际上,特别是从Windows 95年代⼀直到XP初期,就市场占有率来说IE的确借助Windows的东风处于“垄断”的地位)⽽使得Trident内核的长期⼀家独⼤,微软很长时间都并没有更新Trident内核,这导致了两个后果——⼀是Trident内核曾经⼏乎与W3C标准脱节(2005年),⼆是Trident内核的⼤量 Bug等安全性问题没有得到及时解决,然后加上⼀些致⼒于开源的开发者和⼀些学者们公开⾃⼰认为IE浏览器不安全的观点,也有很多⽤户转向了其他浏览器,Firefox和Opera就是这个时候兴起的。⾮Trident 内核浏览器的市场占有率⼤幅提⾼也致使许多⽹页开发⼈员开始注意⽹页标准和⾮IE浏览器的浏览效果问题。
Gecko:
Netscape6开始采⽤的内核,后来的Mozilla FireFox (⽕狐浏览器) 也采⽤了该内核,Gecko的特点 是代码完全公开,因此,其可开发程度很⾼,全世界的程序员都可以为其编写代码,增加功能。
因为这是个开源 内核,因此受到许多⼈的青睐,Gecko内核的浏览器也很多,这也是Geckos内核虽然年轻但市场占有率能够迅速 提⾼的重要原因。 
事实上,Gecko引擎的由来跟IE不⽆关系,前⾯说过IE没有使⽤W3C的标准,这导致了微软内部⼀些开发⼈员的不满;他们与当时已经停⽌更新了的 Netscape的⼀些员⼯⼀起创办了Mozilla,以当时的Mosaic内核为基础 重新编写内核,于是开发出了Geckos。
不过事实上,Gecko 内核的浏览器仍然还是Firefox (⽕狐) ⽤户最多, 所以有时也会被称为Firefox内核。
此外Gecko也是⼀个跨平台内核,可以在Windows、 BSD、Linux和Mac OS X 中使⽤。
Presto:
⽬前Opera采⽤的内核,该内核在2003年的Opera7中⾸次被使⽤,该款引擎的特点就是渲染速度的优化达到了极致,也是⽬前公认⽹页浏览速度最快的浏览器内核,然⽽代价是牺牲了⽹页的兼容性。  实际上这是⼀个动态内核,与前⾯⼏个内核的最⼤的区别就在脚本处理上,Presto 有着天⽣的优势,页⾯的
全部或者部分都能够在回应脚本事件时等情况下被重新解析。此外该内核在执⾏Javascrīpt的时候有着最快的速度,根据在同等条件下的测试,Presto内核执⾏同等Javascrīpt所需的时间仅有Trident和Gecko内核的约1/3(Trident内核最慢,不过两者相差没有多⼤)。 那次测试的时候因为Apple机的硬件条件和普通PC机不同所以没有测试WebCore内核。
只可惜Presto是商业引擎,使⽤Presto的除开Opera以外,只剩下NDSBrowser、Wii Internet Channle、Nokia 770⽹络浏览器等,这很⼤程度上限制了Presto的发展。
Webkit:
苹果公司⾃⼰的内核,也是苹果的Safari浏览器使⽤的内核。
Webkit引擎包含WebCore排版引擎及JavaScriptCore解析引擎,均是从KDE的KHTML及KJS引擎衍⽣⽽来,它们都是⾃由软件,在GPL条约下授权,同时⽀持BSD系统的开发。 所以Webkit也是⾃由软件,同时开放源代码。在安全⽅⾯不受IE、Firefox的制约,所以Safari浏览器在国内还是很安全的。  限于Mac OS X的使⽤不⼴泛和Safari浏览器曾经只是Mac OS X的专属浏览器,这个内核本⾝应该说市场范围并不⼤;但
为什么要单独拿出来说呢?因为它涉及到跑分。经常看见很多⽂章在报道说哪个浏览器更快,其实⼤部分说的就是JavaScript的渲染速度,⽽不是页⾯的载⼊速度。在⽹速许可的情况下,其实各个浏览器的页⾯载⼊速度差别不⼤(Opera逊⾊⼀些)。那是不是说对⽐JavaScript的渲染速度其实没有意义?也不是这么说,因为现在JavaScript在页⾯中的⽐重会越来越⼤,越来越多的动态页⾯开始⼤量借助JavaScript,⽐如现在主流的SNS、邮箱、⽹页游戏,所以JavaScript的渲染速度也是⼀个很重要的指标。
JavaScript的渲染速度越快,动态页⾯的展⽰也越快。Opera在JavaScript引擎的跑分上⾯⼀直都是很⽜逼的,⼀般来说最新测试版之间
PK,Opera基本都会夺冠。
1、Chakra
查克拉,IE9启⽤的新的JavaScript引擎。
2、SpiderMonkey/TraceMonkey/JaegerMonkey
SpiderMonkey应⽤在Mozilla Firefox 1.0-3.0,TraceMonkey应⽤在Mozilla Firefox 3.5-3.6版本,JaegerMonkey应⽤在Mozilla Firefox 4.0及后续的版本。
3、V8
应⽤于Chrome、傲游3。
4、Nitro
应⽤于Safari 4及后续的版本。
ie9浏览器手机版5、Linear A/Linear B/Futhark/Carakan
Linear A应⽤于Opera 4.0-6.1版本,Linear B应⽤于Opera 7.0~9.2版本,Futhark应⽤于Opera 9.5-10.2版本,Carakan应⽤于Opera 10.5及后续的版本。
6、KJS
KHTML对应的JavaScript引擎。
三、⼏个测试
四、⼏个奇葩
1、IETab
在没有第三⽅编译版本的时候,IETab⼀直是Mozilla Firefox、Chrome等⾮Trident内核的浏览器的安装量最⼤的扩展之⼀,⽅便⽤户在不开启IE的情况下调⽤Trident内核访问⼀些兼容性⽐较差的⽹站。
2、Trident/Gecko双核浏览器
虽然IETab能实现部分需求,但是深度订制的毕竟还是不⼀样,所以Trident/Gecko双核浏览器就诞⽣了,Sleipnir、Avant 12(Orca)是这类⾥⾯⽐较常见的。Avant 12因为有Orca的前期积累,所以轻车熟路,后⾯还打算加⼊Chromium,变成三核浏览器,但是偏偏现在Mozilla Firefox和Chrome都在疯狂刷版本号,肯定有⼀部分精⼒要花在跟进版本上。
3、Trident/WebKit双核浏览器
现在国内最主流的“双核”浏览器基本都是这个架构,360极速浏览器、世界之窗浏览器极速版、傲游3搜狗浏览器3、QQ浏览器、枫树浏览器、快快浏览器、百度浏览器、阿云浏览器(后期版本)、太阳花浏览器,其中最奇葩的是傲游3。其它双核浏览器都是基于Chromium的,⽽傲游是基于WebKit的,但是偏偏⼜⽤的是V8引擎。
4、Trident/Gecko/WebKit三核浏览器
⽬前能见的应该就是⽇本的Lunascape,Avant增加了WebKit内核之后也会归类到这⾥。说实话,Lunas
cape真的很难⽤,真的很奇葩。各个内核相对独⽴,外壳本⾝不够强化,稳定性不⾼,所以还不如⽤回单核浏览器。
五、⼏个⼩点
----------------- 隔 ----------------
⼆、浏览器渲染原理
Web页⾯运⾏在各种各样的浏览器当中,浏览器载⼊、渲染页⾯的速度直接影响着⽤户体验简单地说,页⾯渲染就是浏览器将html代码根据CSS 定义的规则显⽰在浏览器窗⼝中的这个过程。
先来⼤致了解⼀下浏览器都是怎么⼲活的: 
1. ⽤户输⼊⽹址(假设是个html页⾯,并且是第⼀次访问),浏览器向服务器发出请求,服务器返回html⽂件;
2. 浏览器开始载⼊html代码,发现<head>标签内有⼀个<link>标签引⽤外部CSS⽂件;
3. 浏览器⼜发出CSS⽂件的请求,服务器返回这个CSS⽂件;
4. 浏览器继续载⼊html中<body>部分的代码,并且CSS⽂件已经拿到⼿了,可以开始渲染页⾯了;
5. 浏览器在代码中发现⼀个<img>标签引⽤了⼀张图⽚,向服务器发出请求。此时浏览器不会等到图⽚下载完,⽽是继续渲染后⾯的代码;
6. 服务器返回图⽚⽂件,由于图⽚占⽤了⼀定⾯积,影响了后⾯段落的排布,因此浏览器需要回过头来重新渲染这部分代码;
7. 浏览器发现了⼀个包含⼀⾏Javascript代码的<script>标签,赶快运⾏它;
8. Javascript脚本执⾏了这条语句,它命令浏览器隐藏掉代码中的某个(style.display=”none”)。杯具啊,突然就少了这么⼀个元素,浏览
器不得不重新渲染这部分代码;
9. 终于等到了</html>的到来,浏览器泪流满⾯……
10. 等等,还没完,⽤户点了⼀下界⾯中的“换肤”按钮,Javascript让浏览器换了⼀下<link>标签的CSS路径;
11. 浏览器召集了在座的各位<span><ul><li>们,“⼤伙⼉收拾收拾⾏李,咱得重新来过……”,浏览器向服务器请求了新的CSS⽂件,重新渲染
页⾯。
浏览器每天就这么来来回回跑着,要知道不同的⼈写出来的html和css代码质量参差不齐,说不定哪天跑着跑着就挂掉了。
好在这个世界还有这么⼀⼈——页⾯重构⼯程师,平时挺不起眼,也就帮视觉设计师们切切图啊改改字,其实背地⾥还是⼲了不少实事的。
说到页⾯为什么会慢?那是因为浏览器要花时间、花精⼒去渲染,尤其是当它发现某个部分发⽣了点变化影响了布局,需要倒回去重新渲染,内⾏称这个回退的过程叫reflow。
不同内核浏览器的差异以及浏览器渲染简介
reflow⼏乎是⽆法避免的。现在界⾯上流⾏的⼀些效果,⽐如树状⽬录的折叠、展开(实质上是元素的显⽰与隐藏)等,都将引起浏览器的reflow。
⿏标滑过、点击……只要这些⾏为引起了页⾯上某些元素的占位⾯积、定位⽅式、边距等属性的变化,都会引起它内部、周围甚⾄整个页⾯的重新渲染。
通常我们都⽆法预估浏览器到底会reflow哪⼀部分的代码,它们都彼此相互影响着。
不同内核浏览器的差异以及浏览器渲染简介
  ** reflow问题是可以优化的,我们可以尽量减少不必要的reflow。
⽐如开头的例⼦中的<img>图⽚载⼊问题,这其实就是⼀个可以避免的reflow——给图⽚设置宽度和⾼度就可以了。
这样浏览器就知道了图⽚的占位⾯积,在载⼊图⽚前就预留好了位置。
另外,有个和reflow看上去差不多的术语:repaint,中⽂叫重绘**。
如果只是改变某个元素的背景⾊、⽂字颜⾊、边框颜⾊等等不影响它周围或内部布局的属性,将只会引起浏览器repaint。
repaint的速度明显快于 reflow(在IE下需要换⼀下说法,reflow要⽐repaint 更缓慢)。
三、从浏览器的渲染原理讲CSS性能
平时我们⼏乎每天都在和浏览器打交道,写出来的页⾯很有可能在不同的浏览器下显⽰的不⼀样。苦逼的前端攻城师们为了兼容各个浏览器⽽不断地去测试和调试,还在脑⼦中记下各种遇到的BUG及解决⽅案,⽽我们好像并没有去主动地关注和了解下浏览器的⼯作原理。
如果我们对此做⼀点了解,我想在项⽬过程中就可以根据它有效的避免⼀些问题以及对页⾯性能做出相应的改进。
今天我们主要根据浏览器的渲染原理对CSS的书写性能做⼀点改进(当然还有JS本篇⽂章暂不考虑,后⾯的⽂章会做介绍),下⾯让我们⼀起来揭开浏览器的渲染原理这⼀神秘的⾯纱吧:
最终决定浏览器表现出来的页⾯效果的差异是:渲染引擎 Rendering Engine(也叫做排版引擎),也就
是我们通常所说的“浏览器内核”,负责解析⽹页语法(如HTML、JavaScript)并渲染、展⽰⽹页。相同的代码在不同的浏览器呈现出来的效果不⼀样,那么就很有可能是不同的浏览器内核导致的。
我们来看⼀下加载页⾯时浏览器的具体⼯作流程(图⼀):
(图⼀)
1、解析HTML以重建DOM树(Parsing HTML to construct the DOM tree ):渲染引擎开始解析HTML⽂档,转换树中的标签到DOM节点,它被称为“内容树”。
2、构建渲染树(Render tree construction):解析CSS(包括外部CSS⽂件和样式元素),根据CSS选择器计算出节点的样式,创建另⼀个树 —- 渲染树。
3、布局渲染树(Layout of the render tree): 从根节点递归调⽤,计算每⼀个元素的⼤⼩、位置等,给每个节点所应该出现在屏幕上的精确坐标。
4、绘制渲染树(Painting the render tree) : 遍历渲染树,每个节点将使⽤UI后端层来绘制。
主要的流程就是:构建⼀个dom树,页⾯要显⽰的各元素都会创建到这个dom树当中,每当⼀个新元素加⼊到这个dom树当中,浏览器便会通过css引擎查遍css样式表,到符合该元素的样式规则应⽤到这个元素上。
注意了:css引擎查样式表,对每条规则都按从右到左的顺序去匹配。
看如下规则:
1
li {}
nav li {}
nav
看起来很快,实际上很慢,尽管这让⼈有点费解#_#。
我们中的⼤多数⼈,尤其是那些从左到右阅读的⼈,可能猜想浏览器也是执⾏从左到右匹配规则的,因此会推测这条规则的开销并不⾼。
在脑海中,我们想象浏览器会像这样⼯作:到唯⼀的ID为nav的元素,然后把这个样式应⽤到直系⼦元素的li元素上。
我们知道有⼀个ID为nav的元素,并且它只有⼏个Li⼦元素,所以这个CSS选择符应该相当⾼效。
事实上,CSS选择符是从右到左进⾏匹配的。了解这⽅⾯的知识后,我们知道这个之前看似⾼效地规则实际开销相当⾼,浏览器必须遍历页⾯上每个li元素并确定其⽗元素的id是否为nav。
1
*{}
额,这种⽅法我刚写CSS的也写过,殊不知这种效率是差到极点的做法,因为*通配符将匹配所有元素,所以浏览器必须去遍历每⼀个元素,这样