当你看到网页里那炫丽多彩的图片和动画时,不知道你脑海里是否有一种想探究这些东西是怎么生成的想法。对,今天我们所探究的就是浏览器为了生成一个漂亮的网页,经历了哪些处理。
一、工作流程概览
浏览器的内核不同,相对应的渲染方式有所不同。下面分别是Webkit和Gecko相应的渲染流程图。
Webkit内核渲染流程图:
Gecko内核渲染流程图:
二、HTML解析
解析是html渲染中一个重要的过程。解析通常是将html文档转化成浏览器引擎能够识别的节点树,我们通常称之为解析树或者语法树。
示例:解析 2 + 3 - 1这个语法树,会返回以下的树:
HTML解析过程中,包含了一些对错误输入的处理,如以下一段HTML:
<html><head> <title>Web page parsingtitle> <div> <h1>Web page parsingh1> <p>This is an example Web page.p>div>head><body>body>html>
经过解析,会生成以下结构:
对于文档树的容错,Webkit在HTML解析器的开头注释中做了很好的概括。
下面是一些Webkit做的容错示例:
1、使用而非
2、表格嵌套
<table> <table> <tr><td>inner tabletd>tr> table> <tr><td>outer tabletd>tr>table>
如上表格webkit会处理成以下结构:
<table> <tr><td>outer tabletd>tr>table><table> <tr><td>inner tabletd>tr>table>
3、嵌套的表单元素。如果一个表单中被放入另一个表单,那么被放入的表单将被忽略。
4、过多的嵌套节点。webkit默认通类型的节点最大嵌套层数为20层,多的层数将被忽略。
5、放错位置的html或body节点。
<html lang="en"><head>head><body> <script>script>html>
处理后的结构:
<html lang="en"><head>head><body> <script>script> body>html>
三、css解析
WebKit 使用 Flex 和 Bison 解析器生成器,通过 CSS 语法文件自动创建解析器。正如我们之前在解析器简介中所说,Bison 会创建自下而上的移位归约解析器。Firefox 使用的是人工编写的自上而下的解析器。这两种解析器都会将 CSS 文件解析成 StyleSheet 对象,且每个对象都包含 CSS 规则。CSS 规则对象则包含选择器和声明对象,以及其他与 CSS 语法对应的对象。
四、脚本处理
在解析器解析输入的文档时,遇到
我们也可以将脚本标注为“defer”,这样它就不会停止文档解析,而是等到解析结束才执行。HTML5 增加了一个选项,可将脚本标记为异步,以便由其他线程解析和执行。
“defer”和“async”:
五、重绘和回流
在我们构造renderTree时,更新的属性只是影响到元素的外观和风格时,我们称值为重绘。当属性影响到元素的大小,形状,位置等,我们称之为回流。
引起回流的一些操作:
1、增加或减少DOM元素
2、元素的位置发生变化
3、元素的尺寸发生变化(包括外边距、内边框、边框大小、高度和宽度等)
4、内容发生变化,比如文本变化或图片被另一个不同尺寸的图片所替代。
5、页面一开始渲染的时候(这肯定避免不了)
6、浏览器的窗口尺寸变化(因为回流是根据视口的大小来计算元素的位置和大小的)
减少重排的一些优化:
1、用class替代style直接修改元素样式
错误示范:
const el = document.querySelector('#app');el.style.border = '1px solid red';el.style.width = '20px';el.style.height = '10px';
正确示范:
const el = document.querySelector('#app');el.className += ' active';
2、对于复杂的的动画效果,使用绝对定位脱离文档流
3、利用css3的硬件加速效果。
使用css3硬件加速,可以让transform、opacity、filters这些动画不会引起回流重绘,但是过度的使用会造成内存占用过大而产生性能问题。
参考链接
浏览器的工作原理:新式网络浏览器幕后揭秘
浏览器渲染页面过程与页面优化
你真的了解重绘和回流吗