现在我们主要接触的主流浏览器有:IE, FireFox, Safari, Chrome,Opera; 你真的了解它们吗?
1. 浏览器的主要功能
- 向服务器发出请求,在浏览器窗口中展示你选择的网络资源;(一般指HTML文档,也可以是PDF,图片,或其他的类型)资源的位置由用户使用的URL(统一资源标示符)指定。 浏览器解释并显示HTML文件的方式是在HTML和CSS规范中指定的。这些规范由网络标准化组织W3C(万维网联盟)进行规定。
2. 浏览器的主要组件
- 用户界面:(包括地址栏,前进/后退按钮,书签菜单等)。除了浏览器主窗口显示的各个部分都属于用户界面
- 浏览器引擎:在用户界面和呈现引擎之间传送指令
- 呈现引擎/渲染引擎/浏览器内核/排版引擎/解释引擎:负责显示请求的内容,并将解析后的内容显示在浏览器屏幕上
- 网络:用于网络调用,比如HTTP请求,其接口与平台无关,并为所有平台提供底层实现。
- 用户界面的后端:用于绘制基本的窗口小部件,比如组合框和窗口。其公开了与平台无关的通用接口,而在底层 使用操作系统的用户界面方法。
- JavaScript解释器:用于解析和执行JavaScript代码
主流浏览器 js引擎
IE -> Edge JScript(IE3.0-IE8.0) / Chakra
Chrome V8(大名鼎鼎)
Safari Nitro(4-)
Firefox SpiderMonkey(1.0-3.0)/ TraceMonkey(3.5-3.6)
Opera Linear A(4.0-6.1)/ Linear B(7.0-9.2)
复制代码
- 数据存储:(持久层);浏览器需要在硬盘上保存各种数据,例如Cookie。HTML5定义了”网络数据库“(完整且轻便的浏览器内数据库)
3. 渲染引擎/浏览器内核解析
- 默认情况下,呈现引擎可显示HTML和XML文档与图片,通过插件(或浏览器扩展程序)显示,eg:PDF查看器插件就可以显示PDF文档。
- 不同的浏览器浏览器内核不相同
主流浏览器 内核
IE -> Edge trident->EdgeHTML
Chrome webkit->blink
Safari webkit
Firefox Gecko
Opera Presto->blink
复制代码
4.浏览器渲染基本流程
从网络层获取请求文档的内容(内容的大小一般限制在8000个块以内)--->
解析HTML构造DOM树和CSSOM树--->构建渲染树(把DOM树中的一些不可视元素去掉,
然后与CSSOM合成一棵render树)--->渲染DOM树布局(计算出各个节点(元素)在屏幕的位置)
-->渲染树绘制(浏览器根据渲染树将页面渲染到屏幕)
复制代码
(1). 解析HTML文档一边边构建DOM树一边构建CSS规则树(CSSOM)
-
解析HTML/XHTML文档时,将各标记逐个转化成"内容树"上的DOM节点,遇到css标签或JS脚本标签就下载和解析(其中css是异步下载同步执行);
-
在构建DOM树过程中,当遇到css元素{包括外部CSS样式以及内联样式},浏览器会开启一个异步请求线程,在该线程上,浏览器会去请求相应的css文件,并且根据该文件去构建CSSOM树(也叫css rule),css的加载并不会导致html解析和渲染的停止,即不会阻塞dom树的构建;该线程会阻塞 JavaScript引擎线程(即css后 面的js模块的解析会在css解析完毕后执行),因为js脚本不仅可以读取修改到dom,也可以读取修改到cssom。故在js脚本执前,browser必须保证到css文件完全加载并解析完成,即cssom树完全构建好。这就导致了js执行的延迟,也因此导致html解析和渲染延迟。(这就是css阻塞js执行,阻塞渲染的根本原因)
-
构建DOM树过程中,浏览器渲染和 JS 执行是共用一个线程,即单线程工作,多线程会产生渲染 DOM 冲突。如果遇到当遇到JS元素时,HTML解析器就会将控制权转让给JavaScript引擎线程,该线程会阻断HTML解析器的运行,就阻塞了DOM树的构建 当js加载并且执行完毕后,JavaScript引擎线程会将控制权还给HTML解析器,让其去继续构建dom树。也就是说,如果你想首屏渲染的越快,就越不应该在首屏就加载 JS 文件,这也是都建议将 script 标签放在 body 标签底部的原因。当然,并不是说 script 标签必须放在底部,因为你可以给 script 标签添加 defer 或者 async 属性
-
JS文件不只是阻塞DOM的构建,它会导致CSSOM也阻塞DOM的构建。原本DOM和CSSOM的构建是互不影响,井水不犯河水,但是一旦引入了JavaScript,CSSOM也开始阻塞DOM的构建,只有CSSOM构建完毕后,再恢复DOM树构建。这是因为JavaScript不只是可以改DOM,它还可以更改样式,也就是它可以更改CSSOM。因为不完整CSSOM是无法使用的,如果JavaScript想访问CSSOM并更改它,那么在执行JavaScript时,必须要能拿到完整的CSSOM。所以就导致了一个现象,如果浏览器尚未完成CSSOM的下载和构建,而我们却想在此时运行脚本,那么浏览器将延迟脚本执行和DOM构建,直至其完成CSSOM的下载和构建。也就是说,在这种情况下,浏览器会先下载和构建CSSOM,然后再执行JavaScript,最后在继续构建DOM。
-
CSS规则树中的元素是和 DOM 元素相对应的,但并非一一对应。非可视化的 DOM 元素不会插入规则树中,例如“head”元素。如果元素的 display 属性值为“none”,那么也不会显示在规则树中(但是 visibility 属性值为“hidden”的元素仍会显示)。有一些 DOM 元素对应多个可视化对象。它们往往是具有复杂结构的元素,无法用单一的矩形来描述。
eg:DOM树
eg:CSSOM树
(2). 浏览器引擎通过 DOM 树和CSS规则树(CSSOM)生成一颗渲染树(Rendering Tree)
- 渲染树是由DOM树和CSSOM树合成的;渲染树的每一个节点都有自己的style样式;渲染树上没有隐藏的节点,比如display:block和无样式head节点,就不会在渲染树上,因为这些节点不会呈现也不影响呈现;visibility:hidden会存在渲染树,因为它占有空间,会影响布局)
渲染树
(3). 渲染DOM树布局(reFlow 或 Layout)
通过 CSS 规则树 匹配 DOM 树每个节点分配一个应出现在屏幕上的确切坐标,即进行定位坐标和大小
(4). 绘制(paint)[调用操作系统Native GUI的API绘制]
呈现引擎会遍历呈现树,由用户界面后端层将每个节点绘制出来。
5.面试常问
- 浏览器渲染原理解析/浏览器渲染过程/浏览器怎么加载页面的?浏览器如果渲染过程中遇到CSS文件/JS文件怎么处理?/dom树和css树是如何合并的?/浏览器的运行机制是什么,什么会造成渲染阻塞?如何优化
参考文章
浏览器运行机制参考文章
- blog.youkuaiyun.com/yunqishequ1…
- www.cnblogs.com/caiyy/p/104…
- segmentfault.com/a/119000001…
- www.jianshu.com/p/05606b0b4…
2019-05-05 18:42:17 星期日