百度首页缓存分析 | 青训营

81 阅读2分钟

缓存是网页非常重要的一部分,它可以节约流量、减少耗电,还能加快网页载入速度,几乎是百利而无一害。

HTTP的缓存策略

HTTP的缓存策略大致可分为以下两步:

  1. 如果缓存没有过期,那么直接使用缓存
  2. 如果缓存过期了,那么问一下服务器这玩意还能不能用,能用就接着用,不能用才重新下载。

第一步判断缓存有没有过期,使用的是max-age(新),Expires(老)的方式来判断的。

第二步要判断缓存还能不能用,因为虽然过期了但可能这个缓存其实还是最新的文件。有两种方式:If-Modified-SinceETag/If-None-Match

If-Modified-Since

这个非常好理解,就是浏览器问一下服务器,这个文件从这个时间以来变没变过。如果没变,服务器就返回304 Not Modified而不发送内容,要是变了才把内容发过去。与此同时,还可以重新指定max-age或者指定新的Expires

ETag/If-None-Match

ETag其实就是个哈希值,服务器发这个文件的时候就在ETag中顺便带上它的哈希值(算法由服务器随意决定),浏览器下次访问这个文件的时候就在If-None-Match中带上这个哈希值。然后还是同理,变了就发文件,没变就304

有趣的是,MDN说了,即使使用了ETag也建议依然指定Last-Modified。因为:

然而,Last-Modified 不仅仅对缓存有用;相反,它是一个标准的 HTTP 标头,内容管理 (CMS) 系统也使用它来显示上次修改时间,由爬虫调整爬取频率,以及用于其他各种目的。所以考虑到整个 HTTP 生态系统,最好同时提供 ETagLast-Modified

百度首页的缓存方式

百度首页可以大致划分为两个部分:

  • 万年不变的部分,比如百度知道、百度新闻的图标,还有大大的百度图标
  • 花里胡哨的新闻

很显然,新闻是不可能缓存的。实际上,每次刷新都会给你新的新闻列表。缓存的只有那些万年不变的图标、js脚本啥的。

js代码

aabbcc

可以看到,脚本的文件名后面被加上了一串哈希,然后缓存时间为一年。这应该说是达到了和Etag/If-None-Match同样的效果,但是Etag方案应该是会对每个文件发送一次验证请求,而这种方法等于是把哈希嵌入到大的html里去了,减少了请求次数,性能上应该会有所提高。

图标

图片.png 图标和js代码采用了一样的缓存方式

新闻图片

图片.png

图片.png 可以看到,新闻图片采用了Expires+ETag的缓存方式。