浏览器从输入网址到页面显示的过程 
- 浏览器主进程解析地址栏中的内容,如果是地址正确拼接协议;如果是搜索内容,拼接搜索地址。 
- 将请求地址交给浏览器网络进程,构建请求行 
- 查找是否存在缓存,有则直接返回缓存 
- 通过 - DNS域名解析得到- IP地址- 查找顺序为: - 查找浏览器缓存,有缓存则返回 IP
- 查找本机缓存,有缓存则返回 IP
- 查找本机配置 DNS服务器,有缓存则返回IP,无则由本机配置DNS服务器向根域名服务器中查找
- 根域名服务器会返回顶级域名服务器(.com 等)地址
- 本机配置 DNS服务器再向顶级域名服务器查找,会返回权威域名服务器地址
- 本机配置 DNS服务器再向权威域名服务器地址查找,找到后返回IP(由域名服务商提供,能正确找到IP)
 
- 查找浏览器缓存,有缓存则返回 
- 如果请求地址中没有端口号,使用默认端口号 - 80(- HTTP)或- 443(- HTTPS)
- 通过三次握手建立 - TCP连接(同一域名最多同时存在 6 个连接,如果已满需要等待)- 第一次握手:客户端发送 SYN报文并设置序列号为A,表示能够发送
- 第二次握手:服务端回复 ACK报文并设置序列号为A+1,以及SYN报文并设置序列号 B,表示能够接收和发送
- 第三次握手:客户端回复 ACK报文并设置序列号为B+1,表示能够接收
 
- 第一次握手:客户端发送 
- 发送 - HTTP请求
- 服务端处理并返回 - HTTP响应,如果响应为重定向,从步骤 2 开始请求新地址;如果响应- Content-Type为二进制流类型,浏览器尝试下载,否则尝试解析展示- TCP 单次传输的数据包通常在 14KB,HTTP 响应会被拆分为多个数据包,在传输完成后进行排序、组合 
- 如果请求头未包含 - Connection: Keep-Alive,则通过四次挥手断开- TCP连接- 第一次挥手:发起断开方发送 FIN报文并设置序列号为A,表示自己没有要发送的内容了
- 第二次挥手:接收断开方发送 ACK报文并设置序列号为A+1,表示收到断开请求,等我检查是否还需要发送
- 第三次挥手:接收断开方发送 FIN报文并设置序列号为B,表示自己没有要发送的内容了
- 第四次挥手:发起断开方发送 ACK报文并设置序列号为B+1,表示确认断开。此时接收断开方收到后便断开连接,而发起断开方需要等到一段时间确认报文发送成功后再断开。
 
- 第一次挥手:发起断开方发送 
- 浏览器主进程新开一个渲染进程(如果是从协议和根域名相同的页面中打开的,会复用同一个渲染进程) 
- 浏览器主进程向渲染进程发送“提交文档”消息,渲染进程与网络进程通信并获取响应;待渲染进程接收响应完毕后向主进程发送“确认提交”消息,主进程更新浏览器界面状态 
- (如果响应是 - HTML代码)- HTML 解析器模块开始解析代码(边加载边解析)并构建- DOM树- 渲染引擎收到 HTML代码字节流后,会开启一个预解析线程,用来分析代码中存在的JS和CSS链接,并提前加载这些文件。所以浏览器网络请求中,HTML、JS、CSS的优先级高于图片等静态资源
- HTML 解析器会首先对- HTML代码进行分词,然后从根节点开始使用栈结构的方式构建- DOM树。栈底为全局- Document对象,然后每一个开始标签进行入栈,当结束标签入栈时会匹配对应的开始标签,匹配成功后表示这段代码解析完成,便会取出加入- DOM树对象中;文本块不需要入栈,直接加入- DOM树对象
- 当解析到没有 async或defer属性的script块时,HTML 解析器会暂停解析并开始加载执行脚本代码。因为JS中也有可能操作CSS,所以在这之前还会等待CSS的加载和解析。脚本加载之后会将代码作为宏任务放入消息队列等待执行
- 解析到带有 async属性的script块时,不会暂停HTML解析,而是异步加载脚本。等脚本加载完成后再暂停HTML解析,并以普通script块同样的方式进行处理
- 解析到带有 defer属性的script块时,不会暂停HTML解析,而是异步加载脚本。等DOM树构建完成后(DOMContentLoaded事件触发后)再以普通script块同样的方式进行处理
- 当解析到其他资源时,会异步请求资源,不会阻塞 HTML解析和页面渲染(图片等元素异步请求完成后会产生新的合并Render树、布局计算、分层、渲染事件,并加入事件循环中)
 
- 渲染引擎收到 
- 将从不同来源解析得到的 - CSS代码(样式表与内联样式)构建为- CSSOM树
- 从 - DOM树中复制元素到- Render树,这个过程会过滤掉不需要显示的元素。之后将- CSSOM树中的样式应用到- Render树的每一个元素(- CSS中使用的图片,会在这时才开始加载)
- 渲染引擎计算 - Render树中每一个元素的显示几何位置,之后在合适的时机开始渲染流程(例如一个宏任务执行结束后)- 渲染流程是在合成线程中进行的,所以不会阻塞主线程 - 对渲染树中的元素进行分层,形成图层树 - 支持 - GPU硬件加速的元素包括:- 具有 3D 变换属性的元素,如使用 transform
- 使用硬件加速的元素,如使用 will-change
- 使用透明度属性 opacity的元素
- 使用滤镜属性的元素,如混合模式(mix-blend-mode)、CSS 过滤器(filter)和遮罩(mask)
- 具有动画(animation)和过渡(transition)效果的元素
- 具有固定定位(fixed)或黏性定位(sticky)的元素
- 被裁剪的元素,如具有滚动条或使用了 clip-path。
- video、- canvas、- webGL等特定媒体元素
 - 这些元素会使用单独的图层,自身修改不会触发其他图层的重排与重绘操作,所以性能更高。 - 通常所说的 - CSS动画性能高于- JS动画是因为:- JS动画需要手动控制绘制频率,绘制操作存在于主线程中,可能被其他任务阻塞;而- CSS动画由浏览器自己管理,能保持更好的流畅性
- JS动画元素如果未单独分层,绘制会与其他元素一同计算,导致部分性能上的损失
 
- 具有 3D 变换属性的元素,如使用 
- 遍历图层树,生成每个图层的绘制指令 
- 对页面进行栅格化(分块),并优先绘制视口附近的块,之后合并每一块的图像 
- 将图像显示到屏幕上