浏览器显示及交互背后的原理

浏览器显示及交互背后的原理

引子

由于笔者( 爱编程的光头强)近期在写一本关于小程序入门的书籍。其中有一章是介绍虚拟DOM的,它是位于Javascript和真正DOM之间的一层缓存层。为何引入它,为何它这么流行,前端三大框架,小程序等,随处可见它的身影。其背后原理是什么。不基于浏览器背后的运行原理,是很难说清楚虚拟DOM被引入的真正缘由和最大好处的。

为了弄清楚浏览器背后运行的逻辑,我查了大量资料,不得不吐槽一下,互联网知识尽管多,鱼龙混杂、良莠不齐、错漏百出,基本是常态,能找到一篇含金量十分高的文章是不容易的。很幸运,关于这个问题,我还真找到了一篇,本文就是对它的解读。好记性不如烂笔头。css

注:本文全部网址都是通过百度短网址处理过的,便于排版及美观。html

原文引用

正文

本文至关于一篇读书笔记,咱们按照原文顺序来一点点深刻。
浏览器市场份额占比:
Chrome
63.34%
Safari
15.06%
Firefox
4.48%
Samsung Internet
3.77%
UC Browser
3.58%
Opera
2.58%
从以上浏览器份额,能够看出,chrome占绝对比,因此咱们的测试就基于它。前端

1、浏览器引擎

引擎的通俗解释就是驱动器、发动机,在软件中是以一套组件或者扩展程序、包存在的核心代码,至关于计算机的CPU。Wikipedia的解释是浏览器引擎即布局引擎,排版引擎,渲染引擎等。Chrome、Safari使用的是Webkit引擎,Mozilla使用的是Gecho引擎,有时候也叫内核。参考:Https://Dwz.Cn/Tr3rrt8mcss3

以上定义对大众是足够的,但对于想搞清楚浏览器运行机制的人来讲,不够。很显然,它笼统的将浏览器几块核心程序(引擎)统称为一个了,并使用其中一个做为所有核心的代称,这很容易让人混淆。web

果真,stackoverflow就有人提到了这样的混淆(https://dwz.cn/7ccPJcX6), 本文引用的以色列那位女工程师文章中,将浏览器组件分为了7个,用户界面(UI),浏览器引擎,呈现引擎,网络,用户界面后端,JavaScript 解释器,数据存储等。chrome

ui,浏览器引擎,渲染引擎等之间关系图

ui,浏览器引擎,渲染引擎等之间关系图

各浏览器使用的渲染/layout引擎及js引擎表

各浏览器使用的渲染/layout引擎及js引擎表

这里的浏览器引擎到底指什么呢,很显然它并非wikipedia里的大众解释,stackoverflow有个答案我以为比较靠谱,它的解释基于chrome浏览器的多进程架构,笔者(爱编程的光头强)使用chrome自带的中文翻译,翻译了这段,供你们参考:编程

回答一:
我不知道如何用“引擎”来解释。让我经过在具备多进程架构的chrome浏览器的上下文中使用的“【

浏览器主进程:管理渲染器进程的主浏览器进程。
渲染器进程:基本上可理解为一个标签卡(chrome)。小程序

可能由于恶意Web内容,致使整个浏览器崩溃或危及宿主机系统,为了防止这种状况发生,浏览器进程委托单独的渲染进程(Renderer进程(选项卡进程))处理每一个请求的Web内容,它没有用户权限(即对OS系统调用的访问权限有限)。后端

当请求网站时,渲染进程将请求转发到浏览器进程,进而发起对导航网站的网络请求。在Web内容到达以后,浏览器进程将内容发送回渲染进程。渲染器进程解析HTML,CSS文件,准备DOM,CSSOM,维护JS运行时(V8实例)并将内容做为位图格式发送到浏览器进程以在UI上显示它。浏览器

浏览器进程将渲染器进程视为黑盒子,指望渲染器进程将某种格式的Web内容转换为所需格式,其中包括几个子组件,布局引擎(进程,layout(chrome)/reflow(mozilla)是其中一个。

所以,浏览器进程处理用户特权资源/请求,例如访问文件系统,网络等,其中沙盒渲染器进程负责将网页转换为浏览器进程能够将其显示在OS窗口管理器中的格式。

这其中涉及到两个概念,一个是浏览器进程,一个是渲染进程。

回答二:
我认为答案取决于咱们在这里讨论的背景。

背景1:若是你正在和一个只知道网络基本知识的朋友交谈......

此上下文中的浏览器引擎是指为您的浏览器提供内容并负责在屏幕上显示内容的软件。若是您在维基百科中搜索浏览器引擎,它会告诉您流行的浏览器引擎包括Webkit,Gecko,Trident等(https://en.wikipedia.org/wiki...)。

在这种状况下,估计不多有人知道有渲染引擎这个东西存在。

背景2:若是你正在和知道浏览器如何工做的朋友以及他们背后的全部疯狂魔法交谈......

此上下文中的浏览器引擎是指浏览器进程,主要负责管理全部I/o进程和显示UI及跟渲染引擎通讯等。

浏览器引擎:在UI和渲染引擎之间编组操做。

这也是正确的。若是你看一下Chromium的架构,你会发现浏览器进程/引擎使用渲染进程来协调页面内容。

此上下文中的渲染引擎是指构造DOM,执行JavaScript和布局网页的程序,例如Webkit,Gecko,Trident。渲染引擎由两个主要组件组成:WebCore包含核心布局功能,JavaScriptCore包含JavaScript解释器V8。

您的朋友彷佛是专家,还必须了解渲染过程,该过程负责构建网页。渲染引擎只是渲染过程当中的关键部分。

下图显示了Chromium体系结构的高级体系结构概述(Google Chrome开源版本)。若是您想了解更多有关现代浏览器背后的魔力的信息,能够查看如下文章:https://medium.com/@zicodeng/...

浏览器进程/线程通讯示意图

2、渲染引擎(呈现引擎)

对文档或其余资源进行解析后,渲染到浏览器窗口显示。它是浏览器的核心部分。一般包含dom解析,css解析,生成render树,layout/reflow,repaint,直至呈现给用户。

3、内容8000个chunck(块)

文中提到“内容的大小通常限制在 8000 个chunck块之内”,解释:Web服务器生成HTTP Response时没法在Header就肯定消息大小的,这时通常来讲服务器将不会提供Content-Length的头信息,而采用Chunked编码动态的提供body内容的长度。进行Chunked编码传输的HTTP Response会在消息头部设置:
Transfer-Encoding: chunked

4、渲染过程

浏览器请求到HTML代码后,在生成DOM的开始阶段,并行发起css、图片、js的请求。CSS文件下载完成后开始构建CSSOM。CSSOM构建完成后和DOM合并生成Render Tree(attachment)。浏览器计算出每一个节点在屏幕的位置进行布局。布局完成后,经过显卡,将内容画到屏幕上。JS修改了DOM或者CSS属性后,Layout和Paint也会被重复执行。图片下载完成后也须要调用Layout和Paint来更新网页。

5、dom+cssom -> render tree

从dom,cssom到渲染树(frame树)的过程不一样的内核树的概念不太同样的,不过所作的工做都大同小异,就是计算造成若干能用于布局的矩形盒子(宽度、高度和位置等几何信息,该计算过程具体实如今layout或reflow阶段),box模型。

Gecko 将视觉格式化元素组成的树称为“框架树”。每一个元素都是一个框架。WebKit 使用的术语是“呈现树”,它由“呈现对象”组成。对于元素的放置,WebKit 使用的术语是“布局”,而 Gecko 称之为“重排”。对于链接 DOM 节点和可视化信息从而建立呈现树的过程,WebKit 使用的术语是“附加”。有一个细微的非语义差异,就是 Gecko 在 HTML 与 DOM 树之间还有一个称为“内容槽”的层,用于生成 DOM 元素。

6、树及DOM节点

树包含 DOM 节点,指的树是由实现了某些DOM 接口的元素构成的。每一个元素都有一条原型链,标准定义了每一个DOM节点或元素必需要实现的DOM接口(属性,方法,事件)。

7、添加defer,async的脚本预解析

一般html被解析的时候遇到js会阻塞执行,为了优化体验和速度,采用延迟或异步的方式,此时就存在了资源的预解析或异步执行的过程了。

8、共享样式

共享样式数据
WebKit 节点会引用样式对象 (RenderStyle)。这些对象在某些状况下能够由不一样节点共享。这些节点是同级关系,而且:

这些元素必须处于相同的鼠标状态(例如,不容许其中一个是“:hover”状态,而另外一个不是)
任何元素都没有 ID
标记名称应匹配
类属性应匹配
映射属性的集合必须是彻底相同的
连接状态必须匹配
焦点状态必须匹配
任何元素都不该受属性选择器的影响,这里所说的“影响”是指在选择器中的任何位置有任何使用了属性选择器的选择器匹配
元素中不能有任何 inline 样式属性
不能使用任何同级选择器。WebCore 在遇到任何同级选择器时,只会引起一个全局开关,并停用整个文档的样式共享(若是存在)。这包括 + 选择器以及 :first-child 和 :last-child 等选择器。

代码:

<div>
    <ul>
        <li>11</li>
        <li>22</li>
        <li>33</li>
    </ul>
</div>
div ul li{
    color: red;
    width: 100px;
    height: 36px;
}

以上代码就属于符合要求的公共样式。

Dirty 位系统

为避免对全部细小更改都进行总体布局,浏览器采用了一种“dirty 位”系统。若是某个呈现器发生了更改,或者将自身及其子代标注为“dirty”,则须要进行布局。

有两种标记:“dirty”和“children are dirty”。“children are dirty”表示尽管呈现器自身没有变化,但它至少有一个子代须要布局。

在浏览器层面已经考虑到了由于某些细小改动而发生全局从新计算和布局的状况。因此虚拟DOM的出现只是为了不不少人为的行为致使的没必要要重排,从而提高性能。

优化及虚拟DOM优化的基础

若是布局是由“大小调整”或呈现器的位置(而非大小)改变而触发的,那么能够从缓存中获取呈现器的大小,而无需从新计算。
在某些状况下,只有一个子树进行了修改,所以无需从根节点开始布局。这适用于在本地进行更改而不影响周围元素的状况,例如在文本字段中插入文本(不然每次键盘输入都将触发从根节点开始的布局)。

Tali Garsiel and Paul Irish的这篇文章很长,也颇有深度,适合反复阅读,几回是很难彻底理解的,并且涉及的知识面很是之广,要完全弄明白,至少也成了半个浏览器专家和排版专家了。不过这是有意义的。本文是针对其中部分疑点作了扩展阅读,还有不少不明白的地方,以后抽时间深刻涉猎。

做者:爱编程的光头强(JM20110222)版权声明:转载请注明出处,理解做者码字的辛苦,谢谢!

相关文章
相关标签/搜索