背景
前端性能优化是在当下前端实际工作中非常重要的一件事。整体看前端可以做性能优化的可以分为几个方向,一个是资源请求类,前端代码优化,前端构建产物大小和构建速度优化。本篇就先对于资源请求部分做一个优化方向具体行动的介绍。
可优化方向
- 请求协议
- 浏览器缓存
- 资源压缩
- 资源加载时机
请求协议
这里主要是去检查页面中的请求是否都采用了HTTP2.0协议,顺带从安全考虑,检查是否都采用了https的协议。先复习一下http2.0的优点。
- 多路复用:多个http请求可以复用一个tcp连接,并且解决了队头阻塞的问题,即http请求无需根据请求先后返回,这里的原理与4的二进制分帧有关。
- 服务器push能力:增加了服务器主动push资源的能力,不过这个实践中不多,但比如一些订阅服务,消息通知还是可以用的。nestjs的sse
- 头部压缩:HTTP/1.1并不支持 HTTP 首部压缩,为此 SPDY 和 HTTP/2 应运而生, SPDY 使用的是通用的DEFLATE 算法,而 HTTP/2 则使用了专门为首部压缩而设计的 HPACK 算法。
- 二进制分帧:用自己的理解说就是,http2把请求头和请求体,进行了一帧一帧的切割,并且每帧都进行了二进制处理,这样一来就解决了队头阻塞的问题,最后只要根据每一帧的标识进行组装就可以还原为最后的完整请求了
http2.0升级,这里需要后端进行配合了。CDN资源目前应该绝大多数都是支持http2.0。另外就是业务中对于cookie头大小的治理。
浏览器缓存
先简单复习一下强缓存与协商缓存。首先是缓存的优点,主要就是两个方面:减少服务器被请求的次数减小压力,客户请求的加速和省流。 然后回顾一下强缓存与协商缓存
强缓存
涉及http里面的两个字段:Expires 和 Cache-Control。一旦触发了强缓存浏览器不会真的发出http请求的,会直接响应200。Expires是标记了资源有效的时间,这个了解即可,这个字段使用很少了,且优先级低于Cache-Control字段。 Cache-Control首先一定是在响应头里的,代表了这个返回的资源的缓存策略。
no-cache
不使用强缓存,会进入协商缓存阶段,如何协商缓存可用,则直接使用缓存资源
no-store
直接禁止浏览器缓存,每次都是从服务器拿到新的资源
public
可以被所有用户缓存,包括浏览器和cdn等中间代理服务器
private
只允许浏览器缓存,不允许cdn等中间代理服务器缓存
max-age
从当前请求开始,允许缓存可用的最长时间
must-revalidate
当缓存过期时,需要去服务器校验缓存的有效性
最常见的返回是no-cache和max-age。
协商缓存
涉及http里面的两个字段:Last-Modified / If-Modified-Since和Etag / If-None-Match,后者的优先级高于前者。Last-Modified是返回资源的最后修改时间而Etag可以认为是资源在服务器上的标识id。第二次请求的时候会向服务器询问缓存是否可用,请求中携带 If-Modified-Since或If-None-Match,携带值就是第一次该资源返回的Last-Modified或者Etag,如果可用服务器会返回304,浏览器可以使用缓存。
优化行动
这里一般前端资源都是放在了CDN上,可以关注一下对应的缓存时间和策略是否合理,假设有资源在后端的服务器上存放,可以关注一下对应的缓存字段是否返回了。
资源压缩
js与css
业务中的这两个的压缩处理一般是在构建中进行的,包括code split,这里先不特别说了,可以关注一下引入的第三方的js和css是否使用了min文件。
图片
图片的压缩,可以在构建的时候进行,也可以是使用工具进行压缩。有些后端下发的图片很可能在上传时前端没有处理直接放在了CDN上的,这种可以用添加cdn压缩参数的方式进行压缩。另外还有雪碧图制作,减少图片的请求数。能用css处理的尽量不要使用切图的方式。iconfont方案来代替大量的icon图。在兼容性允许的情况下使用webp格式的图片。
字体
如果项目中引入了一些较大的字体文件的话,使用类似fontmin这种字体压缩工具。字体的懒加载,这种场景可能不常见,但如果你的网站是设计类的网站会有动态化加载字体的需求。加载方式
gzip
检查构建资源是否用了compression-webpack-plugin进行gzip压缩,其他后端的请求资源是否开启了gzip压缩。
资源加载时机
懒加载图片视频
比如react项目中,尤其是首屏有大量图片视频的场景,可以采用react-lazyload的方案,对资源进行懒加载。
css和js文件的加载
头部加载css文件,js文件采用defer方式加载,注意由于async属性的不稳定性,一般还是采用defer的方式加载js。
preload和prefetch
有写的比较好的文章
结语
资源请求相关的优化是前端性能优化的第一部分,后续将从代码部分和构建部分再做优化。