浏览器工作原理
一、浏览器的模块组成?
1、用户界面,除了显示请求页面的窗口外,其它显示的各个部分都属于用户界面(包括地址栏、书签菜单等)
2、渲染引擎,负责显示请求内容,如果请求的内容是HTML。它就负责解析HTML和CSS内容,并将解析后的内容显示在屏幕上。
3、浏览器引擎,在用户界面和渲染引擎之间传送指令。
4、网络,用于网络调用,比如http请求。其接口和平台无关,并为所有平台提供底层实现。
5、用户界面后端,用于绘制基本的窗口小部件,比如组合框和窗口。其公开了与平台无关的通用接口,而在底层使用操作系统的用户界面方法。
6、JavaScript 解释器。用于解析和执行 JavaScript 代码,比如chrome的javascript解释器是V8。
7、数据存储。这是持久层。浏览器需要在硬盘上保存各种数据,例如 Cookie。新的 HTML 规范 (HTML5)定义了“网络数据库”,这是一个完整(但是轻便)的浏览器内数据库。
二、渲染引擎
哪些模块组成:1、负责HTML、CSS代码的解析(渲染引擎,如blink引擎)。2、负责JavaScript代码的解析(javascript引擎,如V8,由于js引擎越来越独立,内核倾向于只指渲染引擎)
在浏览器占什么地位?渲染引擎的主要职责就是渲染,即在浏览器窗口中显示所请求的内容,这是每一个浏览器核心的部分,所以渲染引擎也称为浏览器内核。
渲染什么?默认情况下,渲染引擎可显示HTML和XML文档及图片。通过插件(或浏览器扩展程序)浏览器还可显示其他类型内容(例如,使用PDF查看器插件就能显示PDF文档),我们介绍其主要用途:显示CSS、HTML内容、图片。
浏览器从用户输入网址之后到呈现的流程?
1、进行DNS解析,
重绘和重排?元素的宽高变化会影响其它元素的坐标位置都影响,浏览器需要重新构建渲染树进行布局为重排,重排完进行重新绘制为重绘。
html文档解析过程:
浏览器解析HTML构建DOM树过程注释: 构建DOM树过程:将字节转换成字符,字符转化为标记,标记构建DOM树,这个过程分为标记化和树构建。
1、纯html文档,无css和脚本。浏览器解析HTML,构建DOM树,构建完成触发DOMContentLoaded事件,构建render树,接着布局和绘制像素。
2、含内联样式和脚本的html。浏览器解析HTML,构建DOM树。当遇到<style>标签,样式信息开始解析,CSSOM开始被构建,但它不影响到HTML的解析和DOM树的构建。当遇到<script>标签,因为脚本可能会改变DOM内容,所以HTML的解析得等到脚本执行完毕后继续,因为脚本可能会改变CSSOM,脚本得等到CSS解析构建CSSOM完毕后才能执行,CSSOM构建完毕,脚本交到JS引擎手里,由JS引擎执行,当脚本执行完毕,HTML继续解析直到完毕,DOM树构建完成触发DOMContentLoaded事件然后就开始构建render树。
注意:DOMContentLoaded事件只和HTML的加载和解析有关,一旦HTML解析完毕,将其触发开始构建render树,不管此时css解析、图片加载、异步脚本的加载和执行。同步脚本的执行会阻塞HTML的解析,直接影响DOMContentLoaded 事件的触发,CSS解析构建CSSOM会阻塞JS脚本执行,间接影响DOMContentLoaded 事件的触发。
所以,内联CSS越放前面越好,不影响JS执行,也就不间接影响HTML解析。内联JS放越后面越好,不直接影响HTML解析。
3、包含外部CSS和脚本的HTML文档。HTML文档加载完成后,浏览器首先扫描HTML文档查看哪些外部资源需要请求,在解析HTML同时发送所有资源请求。遇到<link>标签,CSS资源请求加载完毕后,立即解析构建CSSOM,期间同时在解析HTML(不受CSS加载解析影响)。遇到<script>标签,停止HTML解析构建DOM树,等到其请求加载完毕并且CSS已经加载解析好了,把脚本交给JS引擎执行完毕,再进行HTML解析。
注意:如果脚本有async属性,那么脚本会等到相关CSS解析完毕交给JS引擎去执行。不会等到HTML解析到<script>标签再交给JS引擎去执行。
综上,HTML文档的解析构建DOM过程遇到<script>会等待其加载完毕交给JS引擎执行完毕再继续解析HTML,而JS执行前会先等到相关CSS加载解析成CSSOM完毕才交给JS引擎执行。
JS解析器工作原理:
1、扫描全局变量,确定所有已声明的变量或函数名。
JS对脚本进行全局扫描,结束后得到全局环境中的变量对象,此过程发生了变量申明提升和函数申明提升,所有变量都没有被赋值,其值为undefined。
2、顺序执行所有语句。
当JS解析器得到声明好的全局变量或函数后,开始顺序执行文件中的语句,进行赋值、函数调用等操作。
渲染引擎一开始会从网络层获取请求文档的内容,通常以8k分块的方式完成。获取文档后渲染引擎开始正式工作,渲染引擎解析HTML文档,并将文档中的标签转化为dom节点树(即内容树),同时,它也会解析外部css文件及style标签中的样式数据。这些样式信息连同HTML中的“可见内容”一道,被用于构建渲染树。
渲染树,由一些带有视觉属性(如颜色、大小)的矩阵组成,这些矩阵将按照正确的顺序显示在屏幕上。
渲染树构建完毕,进入“布局”处理阶段,即为每个节点分配一个屏幕坐标。
接下来就是绘制,遍历render树,使用UI后端层绘制每个节点。
这个过程是逐步完成的,为了更好的用户体验,渲染引擎将会尽可能早的将内容呈现到屏幕上,并不会等到所有html都解析完了再去构建和布局render树,它是解析完一部分就显示一部分内容,同时可能还在通过网络下载其余内容。
webkit工作流程另外:css的解析是从右到左逆向解析的。因为,如果正向解析[div div p em],我们首先就要检查当前元素到html整条路径,找到上层的div,再往下找,如果遇到不匹配就必须回到最上层那个div,往下再去匹配选择器中第一个div,回溯若干次才能确定匹配与否,效率低。所以,嵌套越多会增加浏览器工作量,而不会越快。