面试题: 从输入url到渲染页面都发生了什么?

1. 缓存

输入url, 有可能触发缓存,如出现主动补全网址就证明之前访问过,有缓存,访问时我们可以打开调试查看静态资源都是本地缓存获取的,缓存有强制缓存和协商缓存

协商缓存:
  1. Last-Modified和If-Modified-Since
  2. ETag和If-None-Match
Last-Modified和ETag对比

Last-Modified是最后的修改时间,Etag是基于内容做的一个唯一标识,优先使用Etag

  1. 如果一秒内多次更改,Last-Modified无法体现
  2. 打开文件,但没有修改,Last-Modified无法解决
  3. 有负载均衡的服务器生成的时间可能也不一样,Last-Modified无法解决
  4. Etag需要服务器计算生成,有消耗,
强制缓存:
  1. Expires
  2. Cache-Control
Expires和Cache-Control的区别

Expires 用来指定资源到期的时间,受限于本地时间,功能单一
Cache-Control功能更强大,常用选项:

  1. public: 所有服务器都可缓存
  2. private: 仅有客户端可以缓存
  3. max-age: 最大缓存时间
  4. no-cache: 强制使用协商缓存验证
  5. no-store: 不使用强制缓存,也不使用协商缓存
  6. only-if-cached: 表示不进行网络请求,完全只使用缓存,若缓存不命中,则返回503错误

2. HSTS

简单来说就是必须使用https访问, 而且当证书出现问题时,用户无法绕过警告。当第一次通过HTTPS请求网站,如果存在Strict-Transport-Security头,浏览器记录下这些信息,然后后面尝试访问这个网站的请求都会自动把HTTP替换为HTTPS。

出现原因:

大部分用户会偷懒,直接访问没有前缀的网址如:baidu.com, 之前版本的浏览器会默认访问http,然后重定向到https, 这一步容易导致ssl剥离攻击

不足:

如果我们第一次访问的不是https,浏览器会忽略Strict-Transport-Security,所以各大浏览器都维护一个预加载HSTS列表,在列表的网站强制访问https, 这个列表是随浏览器版本进行更新的,无法随意修改。

访问www.baidu.com

image.png

image.png

3. DNS

DNS服务器:
  1. 根服务器:只有13台根服务器,通过根服务器可以查询域名所属的顶级服务器
  2. 顶级服务器:顶级服务器对应一个顶级域名,如com/net/org/cn/edu/…,通过顶级域服务器可以查询二级域。
  3. 权威服务器:权威服务器对应二级域,如baidu.com/qq.com,
DNS解析过程
  1. 浏览器的 DNS 缓存
  2. 操作系统中的 DNS 缓存
  3. 操作系统的hosts文件(可手动写入的缓存/etc/hosts)
  4. 路由DNS缓存
  5. 运营商DNS缓存
  6. 递归查询: 本地DNS服务器(运营商维护)向根服务器查询,根服务器返回域名所属的顶级服务器,本地DNS服务器查询顶级服务器,顶级服务器返回域名所在的权威服务器,本地DNS服务器向权威服务器查询得到ip地址
  7. 本地服务器把结果返回给用户电脑
DNS预解析
 // dns解析提前
 <link rel="dns-prefetch" href="xxx.com"> 
 // dns解析、建立连接时间(Socket) + SSL认证时间都提前
 <link rel="preconnect" href="https://ajax.googleapis.com">
复制代码

http页面下所有的a标签的href都会自动启用DNS Prefetch,https页面需要使用meta标签强制开启

<meta http-equiv="x-dns-prefetch-control" content="on">
复制代码

https

三次握手

截图.png

  1. 客户端发送带有SYN标识(SYN=1,seq=x)的请求报文段,然后进入SYN_SEND状态,等待服务端确认;
  2. 服务端接收到客户端SYN报文段后,需要发送ACK信息对这个SYN进行确认,同时还要发送自己的SYN信息(SYN=1,ACK=1,seq=y,ack=x+1)服务端把这些信息放在一个报文段中((SYN+ACK报文段),一并发给客户端,此时客户端进入SYN_RECV状态;
  3. 客户端接收到服务端的SYN+ACK报文段后会向服务端发送ACK(ACK=1,seq=x+,ack=y+1)确认报文段,这个报文段发送后,客户端和服务端都进入ESTABLISHED状态,完成三次握手。
四次挥手

image.png

  1. 第一次挥手 由浏览器发给服务器 我的东西接受完了,你关闭把
  2. 第二次挥手 由服务器发给浏览器 我还有一些东西要发送,你等一会(我要验证发送数据的完整性)当收到对方的 FIN 报文时,仅仅表示对方不再发送数据了但是还能接收数据,己方是否现在关闭发送数据通道,需要上层应用来决定
  3. 第三次挥手 由服务器发给浏览器 我发送完了,你断开吧
  4. 第四次挥手 由浏览器发给服务器 好的,我断开了
为什么是三次握手,不是两次

保证双方都有接收数据的能力

为什么建立连接是三次握手,而关闭连接却是四次挥手呢?

多了确认断开的步骤,第二次挥手是回复收到断开的请求,但是如果有正在传输的数据,可以选择继续发送,第三次挥手才是服务器通知浏览器我这边完事了,

为什么客户端最后还要等待2MSL?

2MSL是一段TCP报文在传输过程中的最大生命周期,确保服务器收到最后一次发送的ACK报文。如果客户端在2MSL内,再次收到了来自服务器端的FIN报文,说明服务器端由于各种原因没有接收到客户端发出的ACK确认报文。客户端会再次向服务器端发出ACK确认报文,

TCP是通过什么机制保障可靠性的?

滑动窗口: 可靠,有序,稳定, 拥塞控制: 慢启动, 加法增大、乘法减小,超时重传,选择性应答

浏览器解析html

aHR0cHM6Ly91cGxvYWQtaW1hZ2VzLmppYW5zaHUuaW8vdXBsb2FkX2ltYWdlcy80MzQ1Mzc4LWI3Y2NhZDNiYzgwODc4M2YucG5nP2ltYWdlTW9ncjIvYXV0by1vcmllbnQvc3RyaXB8aW1hZ2VWaWV3Mi8yL3cvNjI0L2Zvcm1hdC93ZWJw.png

  1. 构建dom树,
  2. 构建cssom树
  3. 合成render树
  4. 布局
  5. 绘制
常用指标名称
  1. FP: 第一次绘制,通常这时候只能显示背景图片等,没有实际上的DOM
  2. FCP: 第一次带有DOM内容的渲染
  3. FMP: 有意义的绘制, 可以触发交互了
阻塞

css会阻塞render树的构建,js会阻塞dom树的构建,由于js常常会修改css, css会阻塞js,

<head>
    <link rel="stylesheet" href="./static/style.css">
    <script src="./static/index.js"></script> // 上方的css文件解析会阻塞下面的js,需要等待cssom树构建完成
</head>
复制代码
js阻塞dom树的构建,这时可以在页面上看到dom吗?

可以看到阻塞之前的dom(如果有的话),浏览器将会在所有CSS就绪之后,开始进行一次提前渲染,有什么显示什么

async defer
  1. async: js下载是异步的,下载完立刻执行
  2. defer: js下载异步,页面解析完后执行
preload prefetch
  <link rel="preload" href="style.css" as="style">
  <link rel="preload" href="main.js" as="script">
  
  <link rel="prefetch" href="/script.js" as="script">
复制代码
  1. preload: 可以强制浏览器请求资源,同时不阻塞文档onload事件

  2. prefetch: 告诉浏览器这个资源将来可能需要,但是什么时间加载这个资源是由浏览器来决定的。 若能预测到用户的行为,比如懒加载,点击到其它页面等则相当于提前预加载了需要的资源。

  3. preload 加载字体解决闪动问题, 加载非首屏资源,优化体验

  4. prefetch加载用户可能点击的页面

重排(reflow)和重绘(repaint)
  1. 重绘:某些元素的外观被改变,例如:颜色
  2. 重排:重新生成布局,重新排列元素, 查询某些属性如offsetTop也会触发

触发重绘的属性: width height margin padding position overflow offsetTop ... 触发重排的属性: color background border-radius ......

如何减少重排和重绘
  1. 动态改变类而不是直接改变样式
  2. 避免频繁操作,可以创建一个documentFragment或div,更改完成后再添加到,也可以在display:none的元素上进行操作,最终把它显示出来。这样不会引发过多的重排和重绘。
  3. 动画元素可以使用absolute 或 fixed脱离文档流,动画可以开启cpu加速,常用属性有:transform, opacity, filter

猜你喜欢

转载自juejin.im/post/7096836258118238221