Flutter Web如何缓存canvaskit.wasm以避免重复下载?
解决Flutter Web中CanvasKit.wasm的缓存问题
1. 可通过服务工作者或HTTP缓存机制有效缓存CanvasKit.wasm
Flutter Web本身支持两种缓存方案解决重复下载问题:
自定义服务工作者缓存规则
Flutter默认的flutter_service_worker.js有基础缓存逻辑,但你可以扩展它专门处理CanvasKit.wasm:
- 构建时指定自定义服务工作者文件:
flutter build web --service-worker=custom_sw.js
- 在
custom_sw.js中添加针对性缓存逻辑:
importScripts('flutter_service_worker.js'); self.addEventListener('fetch', (event) => { const req = event.request; // 匹配CanvasKit的请求 if (req.url.includes('canvaskit.wasm')) { event.respondWith( caches.open('canvaskit-cache-v1').then(cache => { return cache.match(req).then(cachedRes => { // 优先用缓存,后台同步最新资源 return cachedRes || fetch(req).then(networkRes => { cache.put(req, networkRes.clone()); return networkRes; }); }); }) ); } });
首次加载后文件会存在本地,后续请求直接读取缓存。
利用Flutter默认缓存机制
如果不想自定义SW,默认情况下Flutter构建生成的flutter_service_worker.js会把所有产物加入预缓存列表,只要没修改默认SW配置,CanvasKit.wasm会被自动缓存。
2. 浏览器处理WASM文件的缓存逻辑及必备响应头
浏览器对WASM文件的缓存逻辑和普通静态资源一致,但需配置正确响应头最大化缓存效率:
核心响应头配置
- Cache-Control:结合Flutter生成的带哈希文件名(如
canvaskit.abc123.wasm),建议设置:Cache-Control: public, max-age=31536000, immutablepublic:允许CDN、代理服务器和浏览器缓存max-age=31536000:缓存有效期设为1年immutable:告诉浏览器资源不会变更,无需每次发送验证请求,减少无效网络交互
- ETag/Last-Modified:若未使用哈希文件名,需设置这两个头让浏览器验证资源更新,但优先推荐哈希文件名+
immutable的组合,效率更高。
服务器端配置示例
以Nginx为例,针对.wasm文件添加响应头:
location ~* \.wasm$ { add_header Cache-Control "public, max-age=31536000, immutable"; # 可选:开启Brotli压缩减小文件体积 brotli on; brotli_types application/wasm; }
Apache可在.htaccess中添加:
<FilesMatch "\.wasm$"> Header set Cache-Control "public, max-age=31536000, immutable" # 开启Gzip压缩 SetOutputFilter DEFLATE </FilesMatch>
额外优化点
- 启用压缩:对WASM文件开启Gzip或Brotli压缩,能把1.5MB的文件压缩到500KB左右,加快首次加载速度
- 使用精简版CanvasKit:Flutter 3.7+支持构建时指定
--canvaskit-only参数,只打包必要组件,进一步减小文件体积
内容的提问来源于stack exchange,提问作者Daniel Brunner
相关产品推荐
相关产品推荐

