今天是5月20号,别人的520是甜蜜、爱情、表白,而老夫的520就是写代码、努力写代码、加班写代码,一入代码深似海,从此爱情是路人。言归正传,老夫要开始装逼啦。
温馨提示:文章结构如下,可能阅读完需要花费5分钟
HTML的渲染流程分为3个阶段(自己分的)
1、URL访问请求数据阶段
2、浏览器解析渲染
3、页面布局绘制阶段
最后,总结一下渲染过程可以做的性能优化
一、URL访问请求数据阶段
1.用户输入域名地址,浏览器通过URL域名解析访问IP地址
2.发起TCP的3次握手,就是我们熟悉的建立连接,三次握手,报文等等
3.建立TCP连接后,浏览器向服务器发送http请求
这里的http请求有个注意的参数:
User-Agent:产生请求的浏览器类型
Host:请求的主机名,允许多个域名同处一个IP地址,即虚拟主机
keep-alive (保持连接)
Authorization: 客户端提供给服务器的认证信息
4.服务端接收到请求开始响应HTTP请求
4.1服务器生成html代码,返回给浏览器
注意:html页面代码可能是经过压缩的
4.2服务返回状态码
1xx: 信息性状态码
e.g:100, 101, 102
2xx: 成功状态码
e.g:200:OK
3xx: 重定向状态码
e.g
301 永久重定向, Location响应首部的值仍为当前URL,因此为隐藏重定向
302 临时重定向,显式重定向, Location响应首部的值为新的URL
304Not Modified 未修改,比如本地缓存的资源文件和服务器上比较时,发现并没有修改,服务器返回一个304状态码, 告诉浏览器,你不用请求该资源,直接使用本地的资源即可
4xx: 客户端错误状态码
e.g 404: Not Found 请求的URL资源并不存在
5xx: 服务器端错误状态码
e.g
500: Internal Server Error 服务器内部错误
502: Bad Gateway 前面代理服务器联系不到后端的服务器时出现
504:Gateway Timeout 这个是代理能联系到后端的服务器,但是后端的服务器在规定的时间内没有给代理服务器响应
5.浏览器接收到响应的HTML,开始解析
5.1 如果有压缩则首先进行解压处理,紧接着就是页面解析渲染
5.2 遇到js/css/image等静态资源,开始请求html代码中的资源(如js、css、图片等)
5.3 使用keep-alive特性了,建立一次HTTP连接,可以请求多个资源
二、浏览器解析渲染
1.浏览器解析HTML,并构建DOM树
1.1 浏览器采用自上而下的方式解析
1.2 HTML浏览器有专门的html解析器来解析HTML
1.3 遇到样式(link、style)与脚本文件(script)会阻塞解析(可以使用async 或者defer,不会阻塞线程)
注意:
display:none 的元素也会在DOM树中
注释也会在DOM树中
script标签会在DOM树中
2.解析css去构建CSSOM树
2.1 浏览器会解析CSS文件并生成CSS规则树
2.2 每个CSS文件都会被分析成StyleSheet对象,每个对象都包括CSS规则
注意:
CSS解析可以与DOM解析同进行
CSS解析与script的执行互斥
在Webkit内核中进行了script执行优化,只有在JS访问CSS时才会发生互斥
3、构建渲染树Render Tree
通过DOM树和CSS规则树,浏览器就可以通过他们两个构建渲染树
注意:
Render Tree和DOM Tree不完全对应
display: none的元素不在Render Tree中
visibility: hidden的元素在Render Tree中
JavaScript 应尽量少的去影响 DOM 的构建
三、页面布局绘制阶段
3.1.Render Tree 渲染树布局
布局阶段会从渲染树的根节点开始遍历-递归遍历
布局阶段的输出就是我们常说的盒子模型-计算大小和位置
注意
float元素,absoulte元素,fixed元素会发生位置偏移
脱离文档流,其实就是脱离Render Tree
3.2.Rendder Tree 渲染树绘制
浏览器会遍历渲染树,调用渲染器的paint()方法在屏幕上显示其内容
渲染树的绘制工作是由浏览器的UI后端组件完成的
3.3.回流(reflow)
不可避免
只要有交互就存在,就会引起部分页面重新渲染
当render树绘制完成之后,比如JavaScript改变样式或Tab,隐藏,这时候render树就需要重新计算
3.4.重绘(repaint)
当我们改变某个元素的背景色、文字颜色、边框颜色等等不影响它周围或内部布局的属性时,屏幕的一部分要重绘,但是元素的几何尺寸和位置没有发生改变
注意:
display:none 因为改变组件的大小,会触发reflow
visibility: hidden 不会改变组件占位大小,只会触发repaint
因为reflow不可避免,但是可以减少比如:用transform做形变和位移
四、总结渲染过程可以做的性能优化
1.样式文件应当在 head 标签中,而脚本文件在 body 结束前,这样可以防止阻塞的方式
2.简化并优化CSS选择器,尽量将嵌套层减少到最小
3.尽量减少在 JavaScript 中进行DOM操作
4.修改元素样式时,更改其class属性是性能最高的方法
5.不要使用document.write()这种输出内容的方法,使用现代W3C DOM方法来为现代浏览器处理页面内容
6.DNS查询和解析域名也是消耗时间的,所以要减少对外部JavaScript、CSS、图片等资源的引用,不同域名的使用越少越好
最后,以上总结都是老夫为了方便理解自己总结的内容,其中参考以下资料,创作不易,尊重原著
参考文献链接
https://blog.csdn.net/WuLex/article/details/77850206
https://www.imooc.com/article/40004
https://www.jianshu.com/p/fbe0e9fa45a6/
H5系列
Web前端基础篇-HTML-01-BOM浏览器对象模型
Web前端基础篇-HTML-02-HTML的生命周期
Web前端基础篇-HTML-03-事件处理系统
Web前端基础篇-HTML-04-HTML 渲染流程
Web前端基础篇-HTML5-05-最全本地存储总结
Web前端基础篇-HTML5-06-离线缓存AppCache
Web前端基础篇-HTML5-07-浏览器缓存机制