做为一名前端开发人员,和本身打交道最多的就是浏览器了,那么当浏览器拿到咱们的写的代码后,是如何工做的呢?这个过程,就是浏览器的渲染机制,今天咱们来好好分析一下。css
一个浏览器都包含那些元素部分呢?html
浏览器中最重要的部分就是浏览器内核,也就是渲染引擎,这个引擎是浏览器的核心,它的开发难度极大,内核代码大概有2400万行代码,可见其复杂程度极大。前端
渲染引擎,负责对网页语法的解释(如HTML、JavaScript)并渲染网页。渲染引擎决定了浏览器如何显示网页的内容以及页面的格式信息。webpack
ps:不一样的浏览器内核对网页编写语法的解释也有不一样,所以同一网页在不一样的内核的浏览器里的渲染(显示)效果也可能不一样,这也是网页编写者须要在不一样内核的浏览器中测试网页显示效果的缘由。web
归纳:浏览器的渲染概念就是html解析成DOM,css造成样式规则。二者共同构建渲染树。浏览器根据渲染树的样式进行布局和渲染。算法
当浏览器拿到HTML文档时首先会进行HTML文档解析,构建DOM树。数据库
遇到css样式如link标签或者style标签时开始解析css,构建样式树。HTML解析构建和CSS的解析是相互独立的并不会形成冲突,所以咱们一般将css样式放在head中,让浏览器尽早解析css。后端
当html的解析遇到script标签会怎样呢?答案是中止DOM树的解析开始下载js。由于js是会阻塞html解析的,是阻塞资源。其缘由在于js可能会改变html现有结构。例若有的节点是用js动态构建的,在这种状况下就会中止dom树的构建开始下载解析js。浏览器
脚本在文档的何处插入,就在何处执行。当 HTML 解析器遇到一个 script 标记时,它会暂停构建 DOM,将控制权移交给 JavaScript 引擎;等 JavaScript 引擎运行完毕,浏览器会从中断的地方恢复 DOM 构建。而所以就会推迟页面首绘的时间。能够在首绘不须要js的状况下用async和defer实现异步加载。这样js就不会阻塞html的解析了。当HTML解析完成后,浏览器会将文档标注为交互状态,并开始解析那些处于“deferred”模式的脚本,也就是那些应在文档解析完成后才执行的脚本。而后,文档状态将设置为“完成”,一个“加载”事件将随之触发。注意,异步执行是指下载。执行js时仍然会阻塞。网络
在获得DOM树和样式树后就能够进行渲染树的构建了。应注意的是渲染树和 DOM 元素相对应的,但并不是一一对应。好比非可视化的 DOM 元素不会插入呈现树中,例如“head”元素。若是元素的 display 属性值为“none”,那么也不会显示在呈现树中(可是 visibility 属性值为“hidden”的元素仍会显示)
HTML解析分为标记化和树构建阶段
这里的交互状态是指,当浏览器已经开始执行js代码后,即便js代码尚未执行完,这时已经绑定的事件是能够被触发的。
CSS解析
css是逆向解析,也就是说咱们应该
在 Webkit 中没有规则树,所以会对匹配的声明遍历 4 次。首先应用非重要高优先级的属性(因为做为其余属性的依据而应首先应用的属性,例如 display),接着是高优先级重要规则,而后是普通优先级非重要规则,最后是普通优先级重要规则。这意味着屡次出现的属性会根据正确的层叠顺序进行解析。最后出现的最终生效。
渲染树
原理:了解浏览器如何进行解析,咱们能够在构建DOM结构,组织css选择器时,选择最优的写法,提升浏览器的解析速率。理解浏览器如何进行渲染,明白渲染的过程,咱们在设置元素属性,编写js文件时,能够减小”重绘“”从新布局“的消耗。
一、减小资源请求的次数和压缩数据内容。 由于资源的请求是一个复杂的过程。网速相同的条件下,下载一个100KB的图片比下载两个50KB的图片要快。因此,请减小HTTP请求。
①进行资源打包,将须要屡次请求的资源进行打包减小资源请求次数,如webpack等。
②使用雪碧图,能够避免因不一样图片引发的屡次资源下载
二、高效合理的css选择符能够减轻浏览器的解析负担。
由于css是逆向解析的因此应当避免多层嵌套。
避免使用通配规则。如 *{} 计算次数惊人!只对须要用到的元素进行选择
不要去用标签限定ID或者类选择符。如:ul#nav,应该简化为#nav
尽可能少的去使用后代选择器,下降选择器的权重值。后代选择器的开销是最高的,尽可能将选择器的深度降到最低,最高不要超过三层,更多的使用类来关联每个标签元素。
考虑继承。了解哪些属性是能够经过继承而来的,而后避免对这些属性重复指定规则
三、从js层面谈页面优化
①解决渲染阻塞
若是在解析HTML标记时,浏览器遇到了JavaScript,解析会中止。只有在该脚本执行完毕后,HTML渲染才会继续进行。因此这阻塞了页面的渲染。
解决方法:在标签中使用 async或defer特性
②减小对DOM的操做
对DOM操做的代价是高昂的,这在网页应用中的一般是一个性能瓶颈。
解决办法:修改和访问DOM元素会形成页面的Repaint和Reflow,循环对DOM操做更是罪恶的行为。因此请合理的使用JavaScript变量储存内容,考虑大量DOM元素中循环的性能开销,在循环结束时一次性写入。
减小对DOM元素的查询和修改,查询时可将其赋值给局部变量。
③使用JSON格式来进行数据交换
JSON是一种轻量级的数据交换格式,采用彻底独立于语言的文本格式,是理想的数据交换格式。同时,JSON是 JavaScript原生格式,这意味着在 JavaScript 中处理 JSON数据不须要任何特殊的 API 或工具包。
④让须要常常改动的节点脱离文档流 由于重绘有时确实不可避免,因此只能尽量限制重绘的影响范围。