![9454ca81485fdb8ddfd9b89332a575c5.png](https://i-blog.csdnimg.cn/blog_migrate/a88f64b77e73002d35570354ad8916b7.jpeg)
之前我写过一篇文章,主要是面向 React 框架的性能优化,实际上,面向浏览器、资源请求也可以作出很多的优化,很多很杂,本文对部分方案作了总结。
合理利用缓存
第一部分我们聊聊缓存,这是前后端一个很重要的知识点。缓存可以减少冗余传输、减少带宽、降低源服务器的压力。
缓存的工作机制如下:
- 浏览器先根据这个资源的 http 头信息来判断是否命中强缓存。如果命中则直接加在缓存中的资源,并不会将请求发送到服务器。
- 如果未命中强缓存,则浏览器会将资源加载请求发送到服务器。服务器来判断浏览器本地缓存是否失效。若可以使用,则服务器并不会返回资源信息,浏览器继续从缓存加载资源。
- 如果未命中协商缓存,则服务器会将完整的资源返回给浏览器,浏览器加载新资源,并更新缓存。
一图以蔽之:
![39277ecbbdceee0f31ef25dd2124bb90.png](https://i-blog.csdnimg.cn/blog_migrate/25ad07153bd67838f218f4c7d655e7db.png)
强制缓存
强制缓存的状态码为 200,要实现强制缓存,需要依靠这些请求头:
Cache-Control,这个头的可能值如下:
private
客户端可以缓存public
客户端和代理服务器都可以缓存max-age=x
缓存内容将在 x 秒后失效no-cache
需要使用对比缓存验证数据, 强制向源服务器再次验证 (没有强制缓存)no-store
所有内容都不会缓存,强制缓存和对比缓存都不会触发 (不缓存)
Expires,一个时间戳,表示在此时候之后,响应过期。
如果在 Cache-Control 响应头设置了 max-age
或者 s-max-age
指令,那么 Expires
头会被忽略。
Cache-Control 中的 max-age=x
和 Expires
的值有所区别 --- 一个是相对时间、一个是绝对时间。
协商缓存
协商缓存的状态码为 304(3xx 属于重定向,这没毛病 -- 重定向到本地的缓存),要想实现协商缓存,需要依赖下面这些请求/响应头:
ETag
ETag
用来标示资源是否改变。
例如:服务器产生 ETag,并在 HTTP 响应头中将其传送到客户端,服务器用它来判断页面是否被修改过,如果未修改返回 304,无需传输整个对象。
If-None-Match
和 Etag
匹配的请求头,客户端接收到 ETag
之后,下次可以通过这个请求头来发送它,服务端可以通过比较来决定是否需要缓存。
Last-Modified
包含源头服务器认定的资源做出修改的日期及时间。它通常被用作一个验证器来判断接收到的或者存储的资源是否彼此一致。
If-Modified-Since
和 Last-Modified
匹配的请求头,客户端会发送上一次的 Last-Modified
,服务端通过判断时间来决定是否返回 304。
实践 -- 强制缓存和协商缓存
Last-Modified + If-Modified-Since
下面的代码利用 Last-Modified 和 If-Modified-Since 来实现协商缓存,Last-Modified 是服务端返回的,可以是当前时间,下次浏览器请求这个资源时就会把这个 Last-Modified 交给服务端,让服务端来进行验证。
![88857d62f081c82d118ec18ee925d6b2.png](https://i-blog.csdnimg.cn/blog_migrate/9f5ad13f4bb7c249b6bbcff27cc395c0.jpeg)
ETag + If-None-Match
下面的代码利用 ETag + If-None-Match 实现缓存,服务端将文件计算 hash 值放入 Etag 返回,下次用户再次访问时 If-None-Match 会携带这个ETag,服务端将新的文件计算 hash,然后对比来判断是否 304。
![89baef6745ba2ad6116e0dac718876bf.png](https://i-blog.csdnimg.cn/blog_migrate/eff6c4843d06c362163d2c60067bada3.jpeg)
优化资源的编码/大小
如果缓存是“获取速度快”,那么优化编码就是“拿得尽可能少”。
就拿图片来说,将一个较大尺寸的图片后添加到页面的较小一块区域,显示部分还是那么大,但是我们下载的图片还是那个 “大尺寸的大小”。浪费了流量并损害了页面性能。
图片自适应
我们按照不同宽度准备好几张照片,达到为不同设备加载不同图片的目的,这便是响应式图片(图片自适应)。针对这种需求,我们使用 h5 的 <img>
标签新特性 srcset 和 sizes。
例如:
<img srcset="img1.jpg 320w,
img2.jpg 800w"
sizes="(max-width: 480px) 4