Chrome缓存问题

前段时间我写了一个识别学校教务处验证码的小脚本。原理是运用浏览器的WASM运行ONNX神经网络来进行识别。不过,这个小脚本有个小瓶颈,它需要下载WASM运行库和训练好的神经网络模型。我将这两个静态资源文件托管到了Cloudflare的Page服务上,但遗憾的是璃月访问Cloudflare比较慢。于是我当时就设置了HTTP缓存,并设置缓存时间为1个月。但当我过两天重新使用脚本时,我发现浏览器没有使用缓存,而是重新下载了那两个静态资源文件,但诡异的是在Edge浏览器上就没有问题,不管过了几天Edge浏览器的缓存都还在。要知道这两个浏览器用的是同一个内核——Chromium。我重复试验了多次,确定这不是偶然事件。经过一番搜索我最后才找到了问题,那就是Chromium的缓存有大小限制。

我们来看一下这段代码,这是Chromium计算缓存最大值的源码,说实话不是很复杂。Chromium每次运行时都会使用这段代码动态计算缓存最大值。当缓存大小达到最大值时,为了缓存新的内容,Chromium会根据一套算法删除旧的缓存。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int64_t PreferredCacheSizeInternal(int64_t available) {
using disk_cache::kDefaultCacheSize;
// Return 80% of the available space if there is not enough space to use
// kDefaultCacheSize.
if (available < kDefaultCacheSize * 10 / 8)
return available * 8 / 10;
// Return kDefaultCacheSize if it uses 10% to 80% of the available space.
if (available < kDefaultCacheSize * 10)
return kDefaultCacheSize;
// Return 10% of the available space if the target size
// (2.5 * kDefaultCacheSize) is more than 10%.
if (available < static_cast<int64_t>(kDefaultCacheSize) * 25)
return available / 10;
// Return the target size (2.5 * kDefaultCacheSize) if it uses 10% to 1%
// of the available space.
if (available < static_cast<int64_t>(kDefaultCacheSize) * 250)
return kDefaultCacheSize * 5 / 2;
// Return 1% of the available space.
return available / 100;
}

在这段代码中kDefaultCacheSize = 80 * 1024 * 1024即80MB。通过这段代码我们了解到了Chromium计算缓存最大值的方法,即按顺序匹配下面的表格。

条件 缓存大小 可用空间区间 缓存大小区间
available < kDefaultCacheSize * 10 / 8 available * 8 / 10 [0MB,100MB) [0MB,80MB)
available < kDefaultCacheSize * 10 kDefaultCacheSize [100MB,800MB) 80MB
available < kDefaultCacheSize * 25 available / 10 [800MB,2000MB) (80MB,200MB)
available < kDefaultCacheSize * 250 kDefaultCacheSize * 5 / 2 [2000MB,19.5GB) 200MB
其它条件 available / 100 [19.5GB,+∞) (200MB,+∞)

由于我平时用的Chrome浏览器浏览网页,因此我的浏览器缓存很轻松地就达到了最大值,而那两个静态资源文件访问频率低很容易成为Chrome优先删除的文件。又因为我平时几乎不用Edge浏览器,所以Edge浏览器不会去删掉那个缓存。

为了解决这个破问题,我找到的方法就是使用命令行参数手动指定Chrome缓存大小,具体的参数是--disk-cache-size=1073741824这个命令行参数的单位是字节,而1073741824 = 1024 * 1024 * 1024即1GB。当然只在快捷方式中加入这个参数还有一个小问题,那就是当你在其它软件中打开链接调用Chrome时,这个参数是不会自动添加的。解决方法就是在注册表项中的HKEY_CLASSES_ROOT\ChromeHTML\shell\open\command中添加参数。顺带一提,Windows系统对HTTP协议的默认打开方式的设置在注册表项的HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice中。

参考链接