深度剖析前端性能CRP
CRP(Critical Rendener Path,关键渲染路径)
常见面试题:输入地址栏到浏览器渲染页面,中间都经历了什么?
- URL解析(浏览器解析)
- DNS解析(域名解析)
- 建立TCP链接(3次握手)
- 发送HTPP请求
- 服务器处理,服务器基于HTTP响应客户端需要的内容
- 关闭TCP的链接通道(4次挥手)
- 客户端把获取的结果进行渲染
URL
URL组成部分(URL/URI/URN),格式如下:
协议://域名:端口号/请求的路径名称?问号传参#哈希值
http://www.baidu.com:80/test/index.html?user=visitoer#video(不可访问)
传输协议:用来在服务器和客户端之间进行信息传输
http:超文本传输协议
https: 比HTTP更安全(SSL加密,CA证书)
ftp: 文件上传下载协议(把文件上传到服务器)
对到query(传参),常用的js处理方法有以下三组:
- encodeURI / decodeURI
对整个URL处理,里面的汉字和特殊字符进行编码 - encodeURIComponent / decodeURIComponent
能处理很多字符和汉字,针对某个参数信息编码 - escape/ unescape
只应用于客户端信息传输中,对汉字的编码解码(例如存到cookie中的时候使用)
DNS解析
本地DNS解析(缓存),如果没有才会到网络DNS解析
DNS解析流程,虚线代表有缓存则不需要经过的步骤DNS解析也是需要花费时间的,需要耗费20~120ms之间
DNS解析有两种方法:
- 分布域名解析(递归查询)
- 集中式域名解析(迭代查询)
tcp3次握手
客户端和服务器端建立连接,建立连接后才能进行HTTP等信息传输
发送HTPP请求和服务器处理响应
HTTP报文分为请求报文和响应报文
报文又分为:请求行 请求头 请求体
tcp4次挥手
客户端和服务器端断开连接,需要等待服务器处理完成后才完全断开
浏览器渲染
这个真的可以写一篇大文章了…包括css解析渲染方式,js解析执行等等,写不动了,给别人的链接跳转看吧~
浏览器渲染原理与过程
网络优化:
- DNS缓存(预解析)
EX:<link rel="dns-prefeth" href="//cimg.imgtest.com">
浏览器会派发一个任务去解析DNS,但浏览器会继续解析页面,允许最大请求并发数为6~7个 - 减少HTTP请求次数和请求资源大小
- 资源合并压缩
- 字体图标
- base64
- GZIP
- 图片懒加载
- 数据延迟分批加载(前端骨架屏,服务器骨架屏ssr等手段)
- CDN资源(地域分布式,烧钱,管用)
- 应用缓存
缓存位置:
- Service Worker:浏览器独立线程进行缓存
- Memory Cache:内存缓存
- Disk Cache:硬盘缓存
- Push Cache:推送缓存(HTTP/2中的)
缓存机制:
- 资源缓存:强缓存和协商缓存(大部分都是服务器处理的,剩下的是浏览器处理的)
每一次向服务器请求获取资源文件,都会先看一下本地是否有缓存(先看是否有强缓存,没有再去看是否有协商缓存,都没有才去重新获取资源)
- 强缓存 Expires / Cache-Control
浏览器对于强缓存的处理:根据第一次请求资源时返回的响应头来确定的,但一般我们会两个都设置,以Cache-Control为准
Cache-Control: max-age= (HTTP/1.1)
Expires: 指定时间(HTTP/1.0)
- 协商缓存 Last-Modified / ETag
协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程
-
Last-Modified 和 If-Modified-Since (HTTP/1.0)
第一次访问资源,服务器返回资源的同时,响应头中设置 Last-Modified(服务器上的最后修改时间),浏览器接收后,缓存文件和响应头;下一次请求这个资源,浏览器检测到有 Last-Modified,于是添加If-Modified-Since
请求头,值为Last-Modified中的值;
服务器再次受到这个资源请求,会根据If-Modified-Since
中的值与服务器中这个资源的最后修改时间对比,如果没有变化,返回304和空的响应体,直接从缓存读取即可。如果If-Modified-Since
的时间小于服务器中这个资源的最后修改时间,说明文件有更新,于是返回新的资源文件和状态200;
但是 Last-Modified 只能以秒计时,如果再不可感知的时间内修改完成文件,那么服务器会认为资源还是命中了,不会返回正确的资源 -
ETag 和 If-None-Match (HTTP/1.1)
Etag是服务器响应请求时,返回当前资源文件的一个唯一表示(有服务器生成),只要资源有变化,Etag会重新生成;下一次加载资源向服务器发送请求时,会将上一次返回的Etag值放到请求头If-None-Match
里,服务器只需要比较客户端传来的If-None-Match
跟自己服务器上改资源的Etag是否一致,就能很好的判断资源相对于客户端而言是否被修改过了。如果服务器发现Etag匹配不上,那么直接以常规GET 200回包形式,将新的资源(包括新的Etag)发送给客户端;如果Etag是一致的,则直接返回304知会客户端直接使用本地缓存即可
- 数据缓存
GET请求缓存(一般不要,因为是不可控的)
第一次从服务器获取数据,如果这些数据不是需要经常更新的,我们会基于本地存储把数据存储到本地,在一定时效内,再加载页面,直接从本地缓存中获取数据
参考文章:
初识网络原理: 从浏览器地址栏输入 URL 到页面渲染之间都经历了什么(这篇文章很长,但特别的详细)