页面渲染
当输入一个URL进入页面到页面最终渲染完成展示,这一过程主要经过了以下这几个阶段:
- URL解析
- DNS解析
- TCP连接
- 发送HTTP请求
- 响应请求
- 浏览器下载资源
- 浏览器渲染页面
URL解析
首先浏览器需要判断你输入的是否是一个合法的URL,然后取出URL中的协议、域名、路径等相关信息。 一个URL结构如下图所示:
DNS 解析
目的:浏览器会从URL中获取到相关域名信息,得到对应的IP地址。
浏览器会先从本地的DNS缓存中去查找是否存在对应IP,若没有找到,会从本地服务器中向上级域名服务器中进行查询。
- 首先本地服务器向根域名服务器发起请求,
- 根域名服务器返回顶级域名服务器的地址给本地服务器
- 向顶级域名服务器发起请求,获取权限域名服务器地址
- 从权限域名服务器会返回最终的ip地址
- 本地服务器将获取的IP地址进行缓存,并返回给浏览器
TCP连接
目的:通过获取到的IP地址和端口号,就可以与目标服务器建立TCP连接了
TCP连接需要进行三次握手完成,确保双方的正常通信
- 第一次握手:发送端向接收端发送请求数据申请连接
- 第二次握手:接收端收到请求数据,向发送端响应确定连接
- 第三次握手:发送端收到响应,向接收端响应确定收到响应
当接收端再次收到响应后,就可以确定双方能够正常通信,然后就可以进行后续操作。
发送HTTP请求
在建立TCP连接后,客户端就可以向服务端发送HTTP请求进行通信了
请求的内容包括: 请求行 + 请求头 + 请求主体
响应HTTP请求
服务端在接收到客户端发送的HTTP请求后,对请求进行处理,最终将处理的结果响应给客户端
响应内容包括:状态行 + 响应头 + 响应正文
在服务器响应完之后,TCP连接会经过四次挥手完成断开连接。
浏览器下载资源
浏览器在接收到响应后,需要先对响应信息中的资源进行下载
根据响应头中的信息做出对应处理,如重定向、存储cookie、解压gzip、缓存资源等
浏览器渲染页面
浏览器根据响应头中的content-type值,对不同类型的资源采用不同的解析方式,最终渲染展示在页面上
页面的渲染过程:
-
解析HTML文件,生成DOM树
-
解析CSS文件。生成CSS树
-
合并DOM树+CSS树,生成render树
-
render树布局,负责元素尺寸、位置的计算
-
render树绘制,绘制页面样式
6. 最终交由GPU完成最终的渲染,显示在页面上
- 执行任何 JavaScript 代码。
页面渲染优
1. 在解析HTML文件时,当解析到没有async和defer的script标签时,浏览器会先阻塞HTML文件的解析,先对script中的内容进行解析,解析完成后在对HTML文件中后续内容进行解析。在解析析到有async和defer的script标签时,会将script文件与HTML文件一起并行执行
2. 在对dom进行操作时都会触发浏览器的重绘和重排,对页面进行重新布局和绘制,如果频繁操作的话,会特别消耗浏览器性能。减少重绘重排的次数方案
(1) 避免频繁的操作DOM,可以选择一次性的添加多个元素,而不是一个一个添加,可以使用documentFragment进行批量操作DOM
let list = document.querySelector("#list"),
fragment = document.createDocumentFragment(),
n = 50000;
while(n--){
//将需要添加的元素存入fragment中
fragment.appendChild(document.createElement("li"));
};
//统一挂载
list.appendChild(fragment);
(2) 避免使用table布局,因为table中一个表单元素变化会导致整个表单重新渲染
(3) 可以将小体积的图片全部合并到一张图片中,以定位的方式显示图片。从而减小http请求次数
(4) 在移动元素时最好将其先脱离文档流,使其不影响其他元素,从而减少重排次数。
(5) 用js修改样式时,通过添加一个class,将要修改的样式添加至class中,减少重绘重排次数
对dom尺寸进行多次计算时,先通过临时变量存储起来,当计算完之后再设置给dom。