浏览器访问URL的机制
经常刷到一个面试题: 当在浏览器地址栏上输入URL,然后回车,会经历哪些过程?
这里就做一个总结
首先先了解一下: URL是什么?
URL :“统一资源定位符”, 俗称 “网站”、“网址”
URL格式: 一般为: 协议 + 主机名 + 端口号 + 路径 + 查询字符串
示例:
http://www.zhihu.com:8080/file?username=zs
- 协议: http
- 域名:
www.zhihu.com, 有些主机没有域名,只有 IP 地址,比如192.168.2.15。- 端口号:8080 , 默认的 HTTP 端口为 80,HTTPS 端口为 443。
- 路径 : /file
- 查询字符串:username=zs
浏览器访问URL过程
- DNS解析:目的就是将域名解析成真实的 IP 地址
- 当浏览器输入URL,并回车,浏览器第一次访问,首先浏览器会向DNS域名服务器发生请求,进行域名解析,将域名解析成真实的IP地址
- 再次访问该URL, 则先访问去访问缓存,按照以下的缓存顺序进行访问
- 浏览器缓存
- 操作系统缓存:浏览器会从本地硬盘的host文件中查找存储的DNS信息
- 路由器缓存: 路由器一般也会有自己的DNS 缓存
- ISP:一般是网络配置中的 DNS服务器地址,一般是 国内移动、电信、联通等通用DNS服务器
- 再次访问该URL, 则先访问去访问缓存,按照以下的缓存顺序进行访问
- 当浏览器输入URL,并回车,浏览器第一次访问,首先浏览器会向DNS域名服务器发生请求,进行域名解析,将域名解析成真实的IP地址
- TCP建立连接
- 当浏览器拿到了真实的IP,会向目标服务器发送TCP连接,进行”三次握手“,建立可靠的连接
- HTTPS 会先进行 TCP “三次握手”,然后进行TLS“四次握手”
- HTTP/HTTPS请求
- 浏览器发送 HTTP/HTTPS请求,请求到系统资源,比如 html、css、js、图片等等资源
- TCP断开连接
- 服务器发送TCP请求“四次挥手”,断开连接
- 浏览器渲染
- 并行下载 html、css 文件,分别构建 DOM Tree 和 CSS Tree
- 根据 DOM Tree 和 CSS Tree 生成 Render Tree
- 根据 Render Tree 计算 每个节点的宽高、位置信息。
- 当布局发生变化会执行这一步,比如宽高、位置变化,也就是“回流”
- 将每个节点绘制到界面上,
- 不影响布局的操作会执行这一步,比如节点颜色变化等,也就是“重绘”
衍生问题1: 什么是TCP协议,三次握手与四次挥手具体指的是什么?
TCP:建立连接的全双工协议,目的是在不稳定的网络环境中建立一个稳定的通信
- 三次握手:
- 客户端向服务端发送一个 SYN 包,请求建立连接
- 服务器响应客户端的SYN包,同意建立连接,向客户端发送 SYN+ ACK 包
- 客户端响应服务器端,并发送 ACK包 到服务器
为什么不使用2次握手?
这里的2次握手是指三次握手中的前两步。如果网络比较拥堵,客户端发送了一条请求连接的包,在其中某个网络节点阻塞了,然后客户端会再次发送一个请求连接的包,然后拥堵的网络节点释放了,服务端接收了两个请求,打开了两个连接的服务,而客户端这块以为只打开了一条通信,导致服务端其中一个服务无法关闭,浪费系统资源,三次握手能够解决这个问题。
- 四次挥手(客户端和服务端都可以发起关闭)
- 客户端发送FIN包,告诉服务端需要关闭客户端连接,客户端进入等待关闭状态 FIN_WAIT_1
- 服务器发送ACK包,告诉客户端,我同意你的关闭,客户端进入 FIN_WAIT_2
- 服务端发送 FIN 包告诉 客户端,我需要关闭连接, 客户端进入 LAST_ACK 状态
- 客户端发送ACK包 告诉服务端,我同意你的关闭,服务端立即关闭,客户端进入 TIME_WAIT 状态,等待2MSL时间,如果服务器没有再发送报文,则客户端关闭
衍生问题2: 什么是回流?什么是重绘?
-
回流:改变页面的布局,影响了页面的布局,需要重新计算并产生新的布局,生产新的render tree,这个操作叫做回流,也叫重排。
-
重绘:改变页面的颜色、样式等不影响布局的时候,调用UI引擎重新绘制页面
根据上述的图片可以看出 - 重排一定会导致重绘 - 重绘不一定会导致重排
那么哪些操作为导致重排、重绘呢
重排(回流)会在以下情况下触发:
- 改变窗口大小。
- 改变元素的尺寸、位置、边距、填充等。
- 修改元素的内容,例如文本或图片。
- 添加或删除可见的DOM元素。
- 激活CSS伪类,例如
:hover。 - 查询某些属性或调用某些方法,需要布局信息,如
offsetWidth、offsetHeight、clientWidth、clientHeight、getComputedStyle、scrollWidth、scrollHeight等。
重绘会在以下情况下触发:
- 修改元素的背景色、文字颜色、边框颜色等。
- 改变元素的可见性,例如使用
visibility: hidden。 - 使用CSS3的某些属性,如
transform和opacity,但不影响布局。
衍生问题3 从上述流程上看能做哪些性能优化?
- 减少http 请求(精灵图、文件合并)
- 减少文件大小(图片压缩、代码压缩、)
- 使用CDN加载第三方库
- 预加载:SSR服务器端渲染
- 懒加载
- 分包
- 减少dom操作(避免回流,文档碎片(类似虚拟DOM))