从年前就开始梳理浏览器的工做原理(主要对webkit内核的浏览器进行分析)到如今差很少快一个月了,本文意在帮助前端工程师了解浏览器的工做原理,并据此来优化咱们的网页性能。
主要查阅了WebKit技术内幕、MDN、W3C等网站资料,下文中有若干图片摘自于《WebKit技术内幕》,在此表示感谢。
本文略长,若有不适,实属意外。若有不正确的地方,还望指正,毕竟传播真理才不会误导其余同窗,共同进步才是目的。javascript
浏览器内核由渲染引擎和JS引擎组成,不一样的浏览器、即便同一浏览器不一样型号可能渲染引擎和JS引擎都不同。css
1)Trident渲染引擎 –> 老版本IE系列浏览器
2)Edge渲染引擎 -> Win10中IE浏览器
3)Gecko渲染引擎 –> Mozilla Firefox
4)Presto渲染引擎 –> Opera
5)KHTML渲染引擎 –> 早期的Safafi和Google Chrome
6)Webkit渲染引擎 -> 2001年后的Safari和Chrome以及国内的一些浏览器
7)Blink渲染引擎 -> 新版本的Chromium浏览器Google项目html
1)JScript引擎 –> IE系列浏览器
2)spiderMonkey引擎 –> Mozilla Firefox
3)V8引擎 –> Google Chrome
4)linear b/futhark引擎 –> Opera前端
为你们提供两个开发经常使用查询网站:
该浏览器对html5的支持程度
不一样与Can I usehtml5
上图中虚线部分表示渲染引擎所提供的功能。
这里渲染引擎包含了JavaScript引擎,许多时候二者都不太区分。
下面的内容大部分都是基于这张图来分析的,咱们将逐步解释从用户输入URL到页面展现给用户这个过程当中都发生了什么?
咱们先了解网页的基础知识。java
html – 结构
css – 样式
JavaScript – 行为
还须要一些静态资源:png、gif、webp、MP四、font、svg等等。
由上面几部分就构成咱们的网页。css3
读者不要太关心上图所标的顺序,在某些时候可能会有出入。git
HTML解释器:解释HTML文本的解释器,主要做用是将HTML文本解释成DOM树,DOM是一种文档表示方法。
CSS解释器:级联样式表的解释器,它的做用是为DOM中的各个元素对象计算出样式信息,从而为计算最后网页的布局提供基础设施。
布局:在DOM建立以后,webkit须要将其中的元素对象一样式信息结合起来,计算它们的大小位置等布局信息,造成一个可以表示这全部信息的内部比偶表示模型。
JavaScript引擎:使用JavaScript代码能够修改网页的内容,也能修改CSS的信息,JavaScript引擎能过解释JavaScript代码并经过DOM接口和CSSOM接口来修改网页内容和样式信息,从而改变渲染结果。
绘图:使用图形库将布局计算后的各个网页的节点绘制成图像结果。github
PS:这些模块依赖许多其余基础模块,其中包括网络、存储、2D/3D图形、音频视频和图片解码器等。这里就不对基础模块作相应说明了。web
下面,我就逐个过程进行分析,我这里省略一些非本文目的的过程,如DNS环节。
先来看看HTML解释器工做原理
字节流(Bytes)–> 字符流(Characters)–> 词语(Tokens)–> 节点 –> DOM树
首先是字节流,通过解码以后是字符流,而后经过词法分析器会被解释成词语(Tokens),时候通过分析器构建成节点,最后这些节点被组建成一棵DOM树。
词法分析:HTMLTokenizer 类(做用是词法分析,相似于状态机),输入的是字符串,输出的是一个个的词语。
XSSAuditor验证词语:XSSAuditor (验证词语流Token Stream)XSS指的是Cross Site Security,主要是针对安全方面的考虑。
词语到节点:webkit用来构建DOM节点,这一步骤由HTMLDocumentParser 类调用 HTMLTreeBuilder 类的 constructTree的函数来实现。
节点到DOM树:树中的元素节点建立属性节点等工做由HTMLConstructionSite类来完成,该类中包含一个 HTMLElementStack 做为保存元素节点的栈。
JavaScript的执行:webkit将DOM树建立过程当中须要执行得我Javascript代码交由HTMLScriptRunner类来负责。
DOM的事件机制:webkit中用EventTarget类来表示DOM规范中Events部分定义的事件目标,Node 节点继承自 EventTarget类,因此Node拥有EventTarget类的相关的方法。
这里须要提一下W3C新规范,影子(Shadow)DOM
Shadow DOM API的 ShadowRoot接口是一个DOM子树的根节点, 它与文档的主DOM树分开渲染。
MDN-影子节点
定义:Shadow DOM 为Web组件中的 DOM和 CSS提供了封装。Shadow DOM 使得这些东西与主文档的DOM保持分离。
ShadowRoot 类继承自 DocumentFragment 类。
PS:可使用document.createDocumentFragment 方法或者构造函数来建立一个空的 DocumentFragment.
先看看CSS怎么和DOM结合展现页面的呢?
css解释器和规则匹配处于DOM树创建以后,RenderObject树创建以前,css解释器解释后的结果会保存起来,而后RenderObject树基于该结果来进行规范匹配和布局计算。
CSSOM视图模块(CSSOM View Module)定义了一些 API,Web 开发人员使用这些 API 能够进行检查,也能够以编程方式更改文档及其内容的视觉属性,包括布局框定位、视区宽度和元素滚动。
document.styleSheets 能够查看当前页面的StyleSheetList对象,每一个link、style都会产生 CSSStyleSheet 做为 StyleSheetList对象的value。
DocumentStyleSheetCollection类(属于Document类),该类包含了全部CSS样式表,还包括了webkit的内部表示类CSSStyleSheet,它包含了CSS的href、类型、内容等信息。
CSS解释过程:css字符串通过css解释器处理后变成渲染引擎的内部规则的过程,使用CSSParser类来负责该过程。
在解释网页中自定义的CSS样式以前,实际上webkit渲染引擎会为每一个网页设置一个默认样式,这也是咱们为何要重置浏览器样式的根本缘由。
规则匹配:StyleResolver类为DOM的元素节点匹配样式,StyleResolver类根据元素的信息,例如标签名、类别等,从样式规则中查找最匹配的规则,而后将样式信息保存到新建的RenderStyle对象中。最后,这些RenderStyle对象被RenderObject类所管理和使用。
其中,规则的匹配则是由ElementRuleCollector类来计算并得到,它根据元素的属性等信息,并从DocumentRuleSets类中获取规则集合,依次按照ID、CLASS、标签等选择器信息逐次匹配得到元素的样式。
而后webkit对这些规则进行排序,对于该元素须要的样式属性,webkit选择从高优先级规则中选取,并将样式属性值返回。
这里,我引入一个不太相关的知识点,块格式化上下文(Block Formatting Context,BFC) 是Web页面的可视化CSS渲染的部分,是块级盒布局发生的区域,也是浮动元素与其余元素交互的区域。
不太了解的同窗,请异步MDN-BFC
当webkit建立RenderObject对象以后,每一个对象是不知道本身的位置、大小等信息的,webkit根据盒模型来计算他们的位置、大小等信息的过程称为布局计算/排版。
布局计算分类:第一类是对整个RenderObject树进行的计算;第二类是对RenderObject树中某个子树的计算,常见于文本元素或者overflow:auto块的计算。
布局计算:布局计算是一个递归的过程,这是由于一个节点的大小一般须要先计算它的子节点的位置、大小等信息。
咱们常说的reflow和repaint。涉及到元素的几何属性改变会形成reflow会下降性能(transform、opacity等属性不会形成reflow)。
扩展为何说transform实现动画较直接设置几何属性性能较好?
1.webkit渲染过程:style -> Layout(reflow发生在这) -> Paint(repaint发生在这) -> Composite,transform是位于’Composite(渲染层合并)‘,而width、left、margin等则是位于‘Layout(布局)’层,这一定致使reflow。
2.现代浏览器针对transform等开启GPU加速。
style -> Layout(reflow发生在这) -> Paint(repaint发生在这) -> Composite(transform发生在这个时候)
由这个过程咱们能够看出,这也是为何发生reflow一定会发生repaint的根本缘由。
CSS Animation性能优化
从重绘重排角度讲解transform的动画性能
RenderObject树同其余树(如RenderLayer树等),构成了webkit渲染的主要基础设施。
一个RenderObject对象保存了为绘制DOM节点所须要的各类信息,例如样式布局信息,通过webkit的处理以后,RenderObject对象知道如何绘制本身。
下列状况会使DOM树节点建立一个RenderObject对象(DOM和RenderObject并不是一一对应)。
1.DOM树的document节点。
2.DOM树种的可视节点,例如html、body、div等。而webkit不会为非可视化节点建立RenderObject节点,例如meta、script。
3.某些状况下webkit须要创建匿名的RenderObject节点,该节点不对应于DOM树种的任何节点,而是webkit处理上的须要,典型的例子例如匿名的RenderBlock节点。
在html组建页面结构时,webkit为了提高网页性能,会引入分层结构。
对于一个html文件webkit会为某些元素和它的子节点创建新层,这样webkit能够单独对某层操做提高性能,下列状况会产生新层。
1.video标签 – webkit在新层中有效的处理视频解码器和浏览器之间的交互和渲染问题。
2.div、p等普通标签 – 涉及到3D变换时。
3.canvas标签 – 复杂的2D和3D绘图操做。
webkit会为网页的层次建立相应的RenderLayer对象。当某些类型RenderObject的节点或者某些css样式的RenderObject节点出现的时候,webkit就会为这些节点建立RenderLayer对象。
RenderLayer树是基于RenderObject树创建起来的一棵新树。RenderLayer节点和RenderObject节点不是一一对应关系,而是一对多的关系。
哪些状况下的RenderObject节点须要创建新的RenderLayer节点呢?
1.DOM树的Document节点对应的RenderView节点。
2.DOM树中的Document的子节点,也就是HTML节点对应RenderBlock节点。
3.显式的制定css位置的RenderObject节点。
4.有透明效果的RenderObject节点。
5.节点有溢出(overflow)、alpha或者反射效果的RenderObject节点。
6.使用Canvas 2D和3D(WebGL)技术的RenderObject节点。
7.Video节点对应的RenderObject节点。
绘图上下文(绘图上下文能够分红两种类型):
第一种是用来绘制2D图形的上下文,称之为2D绘图上下文(GraphicsContext)。
第二种是绘制3D图形的上下文,称之为3D绘图上下文(GraphicsContext3D)。
网页的三种渲染方式:
1.软件渲染(CPU内存)
2.使用软件绘图的合成化渲染(GPU内存)css3D、WebGL
3.硬件加速的合成化渲染(GPU内存)
在不须要硬件加速内容的时候(包括但不限于css3 3D变形、css3 3D变换、WebGL和视频),webkit就可使用软件渲染技术来完成页面绘制。
对于每一个RenderObject对象,须要三个阶段绘制本身:
第一阶段是绘制该层中全部块的背景和边框。
第二阶段是绘制浮动内容。
第三阶段是前景(Foreground),也就是内容部分、轮廓、字体颜色、大小等(内嵌元素的背景、边框等发生在这一阶段)。
硬件加速技术是指使用GPU的硬件能力来帮助渲染网页(GPU的做用主要是用来绘制3D图形而且性能特别好)。
canvas开发,能够将画布分解为更小的画布,这样在更新时只须要更新小画布从而减小开销。
css3 3D变形技术,它能过让浏览器仅仅使用合成器来合成全部的层就能够达到动画效果(只触发Composite而不用触发style -> Layout(reflow发生在这) -> Paint)。
WebGL是Khronous组织提出的一套基于3D图形定义的javascript接口。
它基于canvas元素,跟canvas2D不一样的是,Web开发者可使用3D图形接口来绘制各类3D图形。
这里包括3D变形和动画。
webkit会创建一个新层来处理,从而提高性能。
推进JavaScript运行速度提升的利器JIT(Just-In-Time)。
JIT:就是代码在目标平台上运行的时候,实时的把代码编译为目标机器上的机器码。
编译原理:
C++:源代码 –> 抽象语法树 –> 本地代码
Java:源代码 –> 抽象语法树 –> 字节码(跨平台) –> JIT –> 本地代码
经常使用的javascript引擎有v8和JavaScriptCore
工做原理
在js中,基本数据类型Boolean、Number、String、Null、Undefined、Symbol,其余数据都是对象。
在V8中,数据的表示分红两个部分
第一部分是数据的实际内容,它们是变长的,并且内容的类型也不同,如String、对象等。
第二部分是数据的句柄,句柄的大小是固定的,句柄中包含指向数据的指针。
Handle:句柄类,主要用来管理基础数据和对象,以便被垃圾回收器操做。
主要有两个类型,一个Local类(继承自Handle类),表示本地栈上的数据,因此比较轻量。
另外一个是Persistent类(继承自Handle类)表示函数间的数据和对象访问。
对于整形数据,由Handle自己来存储,同时也为了快速访问。
其余的数据都是从堆中申请内存来存储它们,因为其余数据类型,受限于Handle的大小和变长等缘由,都存储在堆中。
V8的延迟(deferred)特性:它使的许多javascript代码的编译直到运行的时候被调用到才会发生,这样能够减小时间开销。
机器语言(它是计算机惟一能直接执行的语言,电子计算机的机器指令是一列二进制数字。)
汇编语言 汇编指令是机器指令便于记忆的书写格式,但他须要进过编译器转换为机器语言,这样机器才能执行。
时间间隔应该设置为多少才合适呢。
跟屏幕的分辨率有关吗(不一样浏览器存在一个极小值)。
设置的时间会按照会准确执行吗。
动画会被平滑地显示效果吗。
回调函数时复杂的好仍是简单的好呢。
window.requestAnimationFrame
在早期的浏览器能力十分有限,Web前端开发者们但愿可以经过一些机制来扩展浏览器的能力(插件机制如flash插件)。
NPAPI是当今最流行的插件架构,几乎全部浏览器都支持,不过存在很大的安全隐患,插件能够窃取系统底层权限,发起恶意攻击。
2010年,Google开发了新的PPAPI,将外挂插件所有放到沙盒里运行,2012年Windows、Mac版本的Chrome浏览器前后升级了PPAPI Flash Player,并但愿今年末以前完全淘汰NPAPI。
经过以下url参看当前chrome浏览器安装的extensions
chrome://extensions/
WebRTC实现了基于网页的视频会议,标准是WHATWG 协议,目的是经过浏览器提供简单的javascript就能够达到实时通信(Real-Time Communications (RTC))能力。
MDN-WebRTC
最重要的方法:navigator.mediaDevices.getUserMedia(constraints)
还有Video、Audio等。
第一部分是网页的安全,包括可是不限于网页数据安全传输、跨域访问、用户数据安全等。
第二部分是浏览器的安全,具体是指虽然网页或者Javascript代码有一些安全问题或者存在安全漏洞,浏览器也可以在运行它们的时候保证吱声的安全,不受到攻击从而泄漏数据或者使系统遭受破坏。
安全模型基础:
域(Same Origin Policy)XMLHttpRequest、cookie的读写、DOM对象操做等。
XSS(Cross Site Scripting)执行跨域的js脚本代码。开发者能够将用户输入的数据进行字符转换来避免。webkit经过XSSAuditor对象帮咱们过滤(默认开启)。
CSP (Content-Security-Policy)HTTP首部字段,内容安全策略(CSP)用于检测和减轻用于 Web 站点的特定类型的攻击,例如 XSS 和数据注入等。
CORS(Cross Origin Resource Sharing)跨域资源共享标准新增了一组 HTTP 首部字段,容许服务器声明哪些源站有权限访问哪些资源。
具体服务端代码设置
// 请求头
header('Access-Control-Allow-Origin: http://arunranga.com'); //
header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
header('Access-Control-Allow-Headers: X-PINGARUNER');
// 响应头
Access-Control-Allow-Origin、
Access-Control-Allow-Credentials、
Access-Control-Allow-Headers、
Access-Control-Expose-Headers、
Access-Control-Allow-Methods、
Access-Control-Max-Age复制代码
Cross Document Messaging 经过 window.postMessage 和 message 事件来通讯。
HTTPS(安全传输协议)
SPDY(读做“SPeeDY”)是Google开发的基于TCP的应用层协议,用以最小化网络延迟,提高网络速度,优化用户的网络使用体验。 SPDY核心思想为多路复用。
QUIC(Quick UDP Internet Connection)是谷歌制定的一种基于UDP的低时延的互联网传输层协议。
CSP定义了网页自身可以访问的某些域和资源。
CORS定义一个网页如何才能访问被同源策略禁止的跨域资源,并规定了二者交互的协议和方式。
浏览器的沙箱模型是利用系统提供的安全技术,让网页在执行过程当中不会修改操做系统或者是访问系统中的隐私数据,而须要访问系统资源或者说是系统调用的时候,经过一个代理机制来完成。
一下url直接输入在浏览器中,enter便可
URL | 做用 |
---|---|
chrome://inspect | 移动端网页调试 |
chrome://net-internals | net-internals是一套工具集合,用于帮助诊断网络请求与访问方面的问题,它经过监听和搜集 DNS,Sockets,SPDY,Caches等事件与数据来向开发者反馈各类网络请求的过程、状态以及可能产生影响的因素。如,查看DNS主机解析缓存chrome://net-internals/#dns |
chrome://view-http-cache/ | 查看内部存储内容及其详情 |
chrome://downloads/ | 下载内容管理,其快捷键是Ctrl+J |
chrome://extensions/ | 扩展管理 |
chrome://bookmarks/ | 书签管理 |
chrome://history | 访问历史管理 |
chrome://restart | 重启chrome浏览器 |
chrome://apps | chrome网上应用店 |
chrome://flags/ | 新特性管理 |
chrome://dns | 查看DNS预取命名(从超连接等处来预测) |
chrome://quota-internals | 查看浏览器所使用磁盘空间配额 |
chrome://settings | 浏览器的设置 |
chrome://sync-internals | 查看chrome 的同步状态 |
chrome://about/ | 查看全部chrome命令 |