前提知识
1.TCP报文段首部格式
几个常见控制位:
确认位ACK: ACK=1时确认号有效,在连接建立后所有传送的报文段都必须把ACK置为1。
同步位SYN: SYN=1时, 表明是一个连接请求/连接接受报文。
终止位FIN: FIN=1时, 表明此报文段发送方数据已发完,要求释放连接。
2.TCP建立连接的过程
TCP 连接传输的三个阶段:连接建立——>数据传送——>连接释放
3.浏览器内核
分为两个部:一是渲染引擎,另一个是JS引擎。
常见的浏览器内核:Trident(IE)、Gecko(火狐)、Blink(Opera)、Webkit(Safari、Chrome)。
从输入URL到页面加载全过程
简单来说就是1.浏览器下载资源;2.浏览器渲染页面。
1.浏览器分析URL
URL(统一资源定位符)一般形式:URL不区分大小写
://:/
http 域名
https IP地址
ftp
file
URL 和URI 的区别:
URL:统一资源定位符。通过路径确定资源。
URI:统一资源标识符。唯一标识一个资源。
URI = URL + URK
2.浏览器向DNS请求解析IP地址
DNS 域名解析系统。
域名解析过程有两种:1. 递归查询。2. 迭代查询
高速缓存:定期更新。当浏览器访问过一域名后会在本地域名服务器中缓存这个地址,下次直接访问即可。
比如:要查找efg.com 域名时直接到dns.com顶级域名服务器查找,不必在先去根域名服务器查找。
3.浏览器与服务器建立TCP连接
连接建立:采用客户服务器方式(三次握手)
ROUND 1:
客户端发送连接请求报文段,无应用层数据。SYN = 1,seq =x(随机)
同步位SYN:SYN = 1时,表明是一个连接请求/连接接受报文。
ROUND 2:
服务器端该TCP连接分配缓存和变量,并向客户端返回确认报文段,允许连接,无应用层数据。
SYN=1,ACK=1,seq=y(随机),ack=x+1
ACK=1时确认号有效,在连接建立后所有传送的报文段都必须把ACK置为1。
ROUND 3:
客户端为该TCP连接分配缓存和变t,并向服务器端返回确认的确认,可以携带数据。
SYN=0,ACK-1,seq=x+1, ack=y+1
4.浏览器发出取文件命令
发起HTTP请求,发送请求报文:
//某浏览器发出的请求报文
GET /index .html HTTP/1.1
Host: www.test. edu.cn
Connection: Close
Cookie: 123456
5.服务器响应
状态码
6.释放TCP连接(4次挥手)
ROUND 1:
客户端发送连接释放报文段,停止发送数据,主动关闭TCP连接。FIN=1,seq=u
ROUND 2:
服务器端回送一个确认报文段,客户到服务器这个方向的连接就释放了一一半关闭状态。ACK=1,seq=v, ack=u+1
ROUND 3:
服务器端发完数据,就发出连接释放报文段,主动关闭TCP连接。FIN=1,ACK=1, seq=w, ack=u+1
ROUND 4:
客户端回送一个确认报文段,再等到时间等待计时器设置的2MSL (最长报文段寿命)后,连接彻底关闭。ACK=1,seq=u+1,ack=w+1
7.浏览器渲染
关键渲染路径是指浏览器请求下载资源,然后解析、构建树、渲染布局、绘制,最后呈现给客户界面的整个过程。
用户看到页面实际上可以分为两个阶段:页面内容加载完成和页面资源加载完成,分别对应于 DOMContentLoaded和Load。
window.onload 和DOMContentLoaded的区别。
window.addEventListener("load",function(){
// 页面的全部资源加载完才会执行,包括图片、视频等。
})
document.addEventListener("DOMContentLoaded",function(){
//DOM 渲染完即可执行,此时样式表、图片、视频还可能没有加载完(比较好)
})
浏览器渲染的过程主要包括以下五步:
浏览器将获取的HTML文档解析成DOM树。
处理CSS标记,构成层叠样式表模型CSSOM。
将DOM和CSSOM合并为渲染树(Render tree)。
计算渲染树中每个DOM元素的坐标和大小,它被称之为布局layout。浏览器使用一种流式处理的方法,只需要一次绘制操作就可以布局所有的元素。
将渲染树的各个节点绘制到屏幕上,这一步被称为绘制painting。
浏览器渲染网页的具体流程
构建DOM树
当浏览器接收到服务器响应来的HTML文档后,会遍历文档节点,生成DOM树。
需要注意以下几点:
DOM树在构建的过程中可能会被CSS和JS的加载而执行阻塞
display:none的元素也会在DOM树中
注释也会在DOM树中
script标签会在DOM树中
无论是DOM还是CSSOM,都是要经过Bytes→characters→tokens→nodes→objectmodel这个过程。
当前节点的所有子节点都构建好后才会去构建当前节点的下一个兄弟节点。
构建CSSOM规则树
浏览器解析CSS文件并生成CSSOM,每个CSS文件都被分析成一个StyleSheet对象,每个对象都包含CSS规则。CSS规则对象包含对应于CSS语法的选择器和声明对象以及其他对象。
在这个过程需要注意的是:
CSS解析可以与DOM解析同时进行。
CSS解析与script的执行互斥 。
在Webkit内核中进行了script执行优化,只有在JS访问CSS时才会发生互斥。
构建渲染树(Render Tree)
通过DOM树和CSS规则树,浏览器就可以通过它两构建渲染树了。浏览器会先从DOM树的根节点开始遍历每个可见节点,然后对每个可见节点找到适配的CSS样式规则并应用。
有以下几点需要注意:
Render Tree和DOM Tree不完全对应
display: none的元素不在Render Tree中
visibility: hidden的元素在Render Tree中
渲染树生成后,还是没有办法渲染到屏幕上,渲染到屏幕需要得到各个节点的位置信息,这就需要布局(Layout)的处理了。
渲染树布局(layout of the render tree)
定位DOM元素坐标和大小
布局阶段会从渲染树的根节点开始遍历,由于渲染树的每个节点都是一个Render Object对象,包含宽高,位置,背景色等样式信息。所以浏览器就可以通过这些样式信息来确定每个节点对象在页面上的确切大小和位置,布局阶段的输出就是我们常说的盒子模型,它会精确地捕获每个元素在屏幕内的确切位置与大小。需要注意的是:
float元素,absoulte元素,fixed元素会发生位置偏移。
我们常说的脱离文档流,其实就是脱离Render Tree。
渲染树绘制(Painting the render tree)
在绘制阶段,浏览器会遍历渲染树,调用渲染器的paint()方法在屏幕上显示其内容。渲染树的绘制工作是由浏览器的UI后端组件完成的。
常见知识点
浏览器如果渲染过程中遇到JS文件怎么处理?
渲染过程中,如果遇到
没有 defer 或 async,浏览器会立即加载并执行指定的脚本,
2)情况2
(异步下载)
async是异步下载脚本文件,下载完毕立即解释执行代码。如果是多个,执行顺序和加载顺序无关
3)情况3
(延迟执行)
defer是在HTML解析完之后才会执行,如果是多个,按照加载的顺序依次执行
为什么操作 DOM 慢?
用 JS 去操作 DOM 时,本质上是 JS 引擎和渲染引擎之间进行了“跨界交流”。它依赖了桥接接口作为“桥梁”,我们每操作一次 DOM,都要过一次“桥”。过“桥”的次数一多,就会产生比较明显的性能问题。因此“减少 DOM 操作”。
基于浏览器渲染原理的性能优化策略?
CSS放在head中,JS放在body最下面
懒加载(图片懒加载,上滑加载更多)
用DOMContentLoaded触发执行JS
减少reflow、repaint触发次数
非核心代码异步加载