浏览器内核
浏览器内核主要由两个部分组成。
分别为 渲染引擎、JavaScript引擎
现在有四大渲染引擎在线:WebKit、Blink、Trident 和 Gecko。
如今人们说的浏览器内核通常指的是渲染引擎。
渲染引擎的主要作用就是渲染页面。
渲染过程如下:
- HTML解析器解析DOM树
- 渲染树结构(具有一定的视觉效果,并按照一定顺序排列在屏幕上)
- 布局渲染树(为每个节点分配固定坐标)
- 绘制DOM树(渲染引擎会遍历所有的节点,由UI后端绘制)
解析HTML文档并生成DOM树,同时遇到css文件发出请求并解析为CSSOM(渲染树)
DOM树和CSSOM树都生成好之后,就可以开始渲染了。
当遇到 <script> 标签会先执行其内代码,因为JavaScript可以操纵DOM和样式的缘故
所以每次修改DOM或修改样式,结构就会发生变化,就需要重新使用渲染引擎进行渲染;重新开始生成DOM树和CSSOM树
所以操作DOM节点对渲染会造成很大影响,因此各大框架为解决此问题,引入了 Virtual DOM (虚拟DOM)
主流渲染引擎如下:
- Trident (IE内核)
微软已经确认IE11为最后一个版本。即表示以后将不会再有IE内核被应用到浏览器中。(太棒了,这是微软做出的最棒的决定) - Blink (谷歌内核)
Blink脱胎于WebKit,本质上是Webkit的分支。 后来因为开发理念背道而驰,故而在2013年谷歌开发团队脱离Webkit开源项目。 对WebKit源码进行重构,删除了冗余的代码。有更好的性能表现。2013年4月3日,谷歌在Chromium Blog上发表博客,称将与苹果的开源浏览器核心Webkit分道扬镳,在Chromium项目中研发Blink渲染引擎(即浏览器核心),内置于Chrome浏览器之中。
- Gecko (火狐内核)
Gecko的特点是代码完全公开,因此,其可开发程度很高,全世界的程序员都可以为其编写代码,增加功能。 Gecko引擎的由来跟IE不无关系,IE没有使用W3C的标准,这导致了微软内部一些开发人员的不满。 他们与当时已经停止更新了的 Netscape的一些员工一起创办了Mozilla,以当时的Mosaic内核为基础重新编写内核,于是开发出了Gecko。 - Webkit(苹果内核)
它是苹果公司自己的内核,也是苹果的Safari浏览器使用的内核。 Webkit引擎包含WebCore排版引擎及JavaScriptCore解析引擎,均是从KDE的KHTML及KJS引擎衍生而来,它们都是自由软件。 所以Webkit也是自由软件,同时开放源代码。在安全方面不受IE、Firefox的制约,所以Safari浏览器在国内还是很安全的。
JavaScript引擎是一个专门处理JavaScript脚本的虚拟机,一般会附带在网页浏览器之中。
JavaScript引擎如下:
-
Chakra引擎(IE内核)
JScript(IE3.0-IE8.0) / Chakra(IE9+之后) IE已经不再更新 -
V8引擎(谷歌内核)
大名鼎鼎的V8引擎,第二次浏览器大战用碾压的实力击败了当时拥有大约80%市场份额的IE浏览器 众所周知的Node.js也是基于V8引擎开发出的JavaScript运行环境 引擎由C++编写 -
Nitro引擎(苹果内核)
JavaScriptCore引擎是WebKit中默认的引擎,在早期阶段,它的性能不是特别突出。 特别是,它只有解释器来解释执行JavaScript代码。 从2008年开始,JavaScriptCore引擎开始一个新的优化工作,苹果内部代号为”Nitro”的JavaScript引擎也是基于JavaScriptCore项目的 2008年6月2日,WebKit开发团队声明了SquirrelFish——一个新的JavaScript引擎能极大地提升Safari解释脚本的速度。 该引擎是Safari 4其中一个新特性,在2008年6月11日发布给程序员使用;最终此JavaScript引擎被称为Nitro。 -
JaegerMonkey(火狐内核)
SpiderMonkey(1.0-3.0)/ TraceMonkey(3.5-3.6)/ JaegerMonkey(4.0-) SpiderMonkey是第一款JS引擎,JavaScript之父Brendan Eich在网景的时候写的
如今人们常说的不兼容ES6就是因为客户端上的JS引擎版本太低所导致的。
浏览器渲染原理
Web页面运行在各种各样的浏览器当中,浏览器载入、渲染页面的速度直接影响着用户体验简单地说,页面渲染就是浏览器将html代码根据CSS定义的规则显示在浏览器窗口中的这个过程。
以下内容取自 【不同内核浏览器的差异以及浏览器渲染简介】
**先来大致了解一下浏览器都是怎么干活的: **
-
用户输入网址(假设是个html页面,并且是第一次访问),浏览器向服务器发出请求,服务器返回html文件;
-
浏览器开始载入html代码,发现
<head>标签内有一个<link>标签引用外部CSS文件; -
浏览器又发出CSS文件的请求,服务器返回这个CSS文件;
-
浏览器继续载入html中
<body>部分的代码,并且CSS文件已经拿到手了,可以开始渲染页面了; -
浏览器在代码中发现一个
<img>标签引用了一张图片,向服务器发出请求。此时浏览器不会等到图片下载完,而是继续渲染后面的代码; -
服务器返回图片文件,由于图片占用了一定面积,影响了后面段落的排布,因此浏览器需要回过头来重新渲染这部分代码;
-
浏览器发现了一个包含一行Javascript代码的
<script>标签,赶快运行它; -
Javascript脚本执行了这条语句,它命令浏览器隐藏掉代码中的某个(style.display=”none”)。杯具啊,突然就少了这么一个元素,浏览器不得不重新渲染这部分代码
-
终于等到了
</html>的到来,浏览器泪流满面…… -
等等,还没完,用户点了一下界面中的“换肤”按钮,Javascript让浏览器换了一下标签的CSS路径;
-
浏览器召集了在座的各位
<span><ul><li>们,“大伙儿收拾收拾行李,咱得重新来过……”,浏览器向服务器请求了新的CSS文件,重新渲染页面。
浏览器每天就这么来来回回跑着,要知道不同的人写出来的html和css代码质量参差不齐,说不定哪天跑着跑着就挂掉了。
好在这个世界还有这么一群人——页面重构工程师,平时挺不起眼,也就帮视觉设计师们切切图啊改改字,其实背地里还是干了不少实事的。
说到页面为什么会慢?那是因为浏览器要花时间、花精力去渲染,尤其是当它发现某个部分发生了点变化影响了布局,需要倒回去重新渲染,内行称这个回退的过程叫reflow。
reflow几乎是无法避免的。现在界面上流行的一些效果,比如树状目录的折叠、展开(实质上是元素的显示与隐藏)等,都将引起浏览器的 reflow。
鼠标滑过、点击……只要这些行为引起了页面上某些元素的占位面积、定位方式、边距等属性的变化,都会引起它内部、周围甚至整个页面的重新渲染。
通常我们都无法预估浏览器到底会reflow哪一部分的代码,它们都彼此相互影响着。
reflow问题是可以优化的,我们可以尽量减少不必要的reflow。
比如开头的例子中的<img>图片载入问题,这其实就是一个可以避免的reflow——给图片设置宽度和高度就可以了。
这样浏览器就知道了图片的占位面积,在载入图片前就预留好了位置。
另外,有个和reflow看上去差不多的术语:repaint,中文叫重绘。
如果只是改变某个元素的背景色、文字颜色、边框颜色等等不影响它周围或内部布局的属性,将只会引起浏览器repaint。
repaint的速度明显快于 reflow(在IE下需要换一下说法,reflow要比repaint 更缓慢)。
回流(reflow)
当DOM元素的结构或者位置发生改变(删除、增加、改变位置、改变大小...)
都会引发回流,所谓回流,就是浏览器抛弃原有计算的结构和样式,从新进行DOM TREE或者RENDER TREE,非常非常非常...消耗性能。
重绘(repaint)
当某一个DOM元素样式更改(位置没变只是样式更改,例如:颜色变为红色...)浏览器会重新渲染这个元素。