从输入URL到看到页面“CRP关键节点的性能优化【HTTP网络层面】
浏览器一共进行七个步骤:
- URL解析
- 缓存检查
- DNS解析
- TCP的三次握手
- HTTP传输
- TCP的四次挥手
- 渲染页面
URL解析
- 传输协议:HTTP / HTTPS(SSL) / FTP(文件上传)…
- 域名:顶级、一级、二级…
- 端口号:0~65535 区分同一台服务器上的不同服务 [默认端口号:HTTP: 80 HTTPS: 443 FTP: 21] 默认端口号是浏览器处理的
- 问号参数:可以把一些信息传递给服务器“get系列”;也可以实现两个页面之间的信息通信;SPA单页面中,实现组件和组件之间的通信;…
- HASH哈希值:锚点定位;HASH路由;…
编码问题:URL中特殊内容的编码
- encodeURI decodeURI 编译能力弱,只是把URL地址中的中文或者空格等编译 “用于整个URL的编译”
- encodeURIComponent decodeURIComponent 编译能力强,还可以多编译一些特殊符号“用于传递参数的某个值编译”
- escape unescape 只适合客户端之间的通信和编码
axios.get(`http://www.xxx.com/api/list?name=${encodeURIComponent('雪之下雪乃')}&from=${encodeURIComponent('http://www.weixin.com/')}&lx=1`);
缓存检查
缓存检查针对静态资源文件,例如:html/css/js/图片…
缓存位置:内存、硬盘
F5普通刷新:TAB页卡没关闭,先检测内存,再检测硬盘是否有缓存
重新打开页面:直接检测硬盘中是否有缓存
CTRL + F5强制刷新:不检测任何缓存,直接向服务器发送请求
-
强缓存
- 先检测本地是否有强缓存,如果有且没过期,直接从本地获取,然后渲染【HTTP状态码:200】
- 如果没有或过期了,则重新向服务器发送请求,拉取回最新的结果,渲染的同时,把本次结果缓存起来
优势:性能优化的重要手段,可以保证第二次及以后再访问产品,速度会很快
弊端:可能无法保证本地获取的资源是最新的
如何解决弊端?
- HTML是不能做强缓存的
- 只要HTML不处理强缓存,我们就可以保证其余资源的及时更新:请求资源后面设置时间戳,或者文件名字根据内容生成HASH名
- 服务器设置的强缓存:在每一次重新从服务器拉取最新资源文件的时候,都在响应头中携带 Cache-Control/Expires “缓存有效期”,以后再访问这些资源,就可以看看本地是否有,以及是否过期了
-
协商缓存304 【只有强缓存失效后,才会校验协商缓存】
-
如果啥缓存都没有,直接从服务器获取最新的资源信息“把信息缓存起来;强缓存:把 Cache-Control/Expires 存储起来;协商缓存:把 Last-Modified/ETag 存储起来”
Last-Modified:当前资源文件再服务器端最后修改的时间
ETag:每一次修改文件都会生成一个标志 -
再次请求这个页面,如果强缓存不生效,则开始协商缓存
- 向服务器发送请求,同时带上 if-Modified-Since:Last-Modified 或者if-None-Match:ETag 传递给服务器;服务器根据传递的时间/标志,和服务器本身资源文件最后修改的时间/标志,进行对比,如果一样,说明文件没有更新过,直接返回304即可,无需返回内容;如果不一样,说明更新过,那么则返回最新的内容和最新的 Last-Modified/ETag
- 接收的是304,直接从本地缓存中获取信息渲染即可
HTML文件资源是可以使用协商缓存的
一、 什么是”Last-Modified”?
在浏览器第一次请求某一个URL时,服务器端的返回状态会是200,内容是你请求的资源,同时有一个Last-Modified的属性标记此文件在服务期端最后被修改的时间,格式类似这样:
Last-Modified: Fri, 12 May 2006 18:53:33 GMT客户端第二次请求此URL时,根据 HTTP 协议的规定,浏览器会向服务器传送 If-Modified-Since 报头,询问该时间之后文件是否有被修改过:
If-Modified-Since: Fri, 12 May 2006 18:53:33 GMT如果服务器端的资源没有变化,则自动返回 HTTP 304 (Not Changed.)状态码,内容为空,这样就节省了传输数据量。当服务器端代码发生改变或者重启服务器时,则重新发出资源,返回和第一次请求时类似。从而 保证不向客户端重复发出资源,也保证当服务器有变化时,客户端能够得到最新的资源。
二、 什么是”Etag”?
HTTP 协议规格说明定义ETag为“被请求变量的实体值” (参见 —— 章节 14.19)。 另一种说法是,ETag是一个可以与Web资源关联的记号(token)。典型的Web资源可以一个Web页,但也可能是JSON或XML文档。服务器单 独负责判断记号是什么及其含义,并在HTTP响应头中将其传送到客户端,以下是服务器端返回的格式:
ETag: "50b1c1d4f775c61:df3"客端的查询更新格式是这样的:
If-None-Match: W/"50b1c1d4f775c61:df3"
如果ETag没改变,则返回状态304然后不返回,这也和Last-Modified一样。Etag主要在断点下载时比较有用。Last-Modified和Etags如何帮助提高性能?
聪明的开发者会把Last-Modified 和ETags请求的http报头一起使用,这样可利用客户端(例如浏览器)的缓存。
因为服务器首先产生 Last-Modified/Etag标记,服务器可在稍后使用它来判断页面是否已经被修改。本质上,客户端通过将该记号传回服务器要求服务器验证其(客 户端)缓存。过程如下:
1. 客户端请求一个页面(A)。
2. 服务器返回页面A,并在给A加上一个Last-Modified/ETag。
3. 客户端展现该页面,并将页面连同Last-Modified/ETag一起缓存。
4. 客户再次请求页面A,并将上次请求时服务器返回的Last-Modified/ETag一起传递给服务器。
5. 服务器检查该Last-Modified或ETag,并判断出该页面自上次客户端请求之后还未被修改,直接返回响应304和一个空的响应体。注:以上内容转载自 tianmo2010的博客《Last-Modified 与 If-Modified-Since详解》https://blog.youkuaiyun.com/tianmohust/article/details/8840256
-
-
数据缓存【AJAX/FETCH…】
DNS解析【域名解析】
在DNS服务器上,基于域名找到服务器的外网IP,后面我们就可以基于服务器的外网IP找到服务器了
DNS解析也有缓存
- 从本地缓存中找时用的是递归查询
- 从DNS服务器上查找时用的时迭代查找
一次DNS解析大概20ms~120ms之间
服务器拆分优势: - 资源的合理利用
- 抗压能力加强
- 提高HTTP并发
TCP三次握手
在拿到外网IP后,我们开始建立客户端和服务器端连接的通道“TCP通道”
- TCP:稳定的网络通信协议【图稳定】
- UDP:不稳定的网络通信协议【图个快,例如音视频的传输】
TCP作为一种可靠传输控制协议,其核心思想:既要保证数据可靠传输,又要提高效率
数据传输
HTTP报文 - 请求报文
- 响应报文
TCP四次挥手
断开TCP连接通道
- connection:keep-alive 长连接,在一定时间内,如果建立连接之后,可以保证连接通道不关闭,这样可以提高传输效率
性能优化汇总
- 利用缓存
- 对于静态资源文件实现强缓存和协商缓存(扩展:文件有更新,如何保证及时刷新?)
- 对于不经常更新的接口数据采用本地存储做数据缓存(扩展:cookie/localStorage/vuex|redux 区别?)
- DNS优化
- 分服务器部署,增加HTTP并发性(导致DNS解析变慢)
- DNS Prefetch(预先载入)
- TCP的三次握手和四次挥手
- Connection: keep-alive
- 数据传输
- 减少数据传输的大小
- 内容或者数据压缩(webpack等)
- 服务器端一定要开启GZIP压缩(一般能压缩60%左右)
- 大批量数据分批次请求(例如:下拉刷新或者分页,保证首次加载请求数据少)
- 减少HTTP请求的次数
- 资源文件合并处理
- 字体图标
- 雪碧图 CSS-Sprit
- 图片的BASE64
+…
- CDN服务器“地域分布式”
- 采用HTTP2.0
网络优化是前端性能优化中的重点内容,因为大部分的消耗都发生在网络层,尤其是第一次页面加载,如何减少等待时间很重要“减少白屏的效果和时间“
- LOADING 人性化体验
- 骨架屏:客户端骨屏 + 服务器骨架屏
- 图片延迟加载
- …