Service Worker缓存字体是最可靠方案,通过预缓存、拦截请求和静默更新三步闭环,确保字体本地秒级加载,彻底消除FOIT/FOUT/CLS;需与font-display: swap或optional协同使用。

直接用 Service Worker 缓存字体文件,是解决全站字体闪烁(FOIT/FOUT/CLS)最可靠的方式之一。它不依赖用户设备或浏览器预加载行为,而是把关键字体资源稳稳存在本地,首次访问后即可离线加载、秒级渲染。
为什么 Service Worker 比其他方式更有效
浏览器默认缓存(如 Cache-Control: max-age=31536000)虽简单,但无法控制字体是否“已就绪”——即使文件在缓存里,CSS 中的 @font-face 仍可能触发 FOIT;而 Web Font Loader 或 font-display: swap 只能缓解闪烁,不能保证字体一定已加载完成。Service Worker 则能在 fetch 阶段主动拦截字体请求,优先返回已缓存版本,彻底消除等待空白期。
关键步骤:安装 + 预缓存 + 运行时拦截
三步闭环,缺一不可:
- 预缓存字体文件:在 install 阶段把 .woff2/.woff/.ttf 等字体路径写死进 cache,确保首次访问即生效
-
拦截字体请求:fetch 事件中匹配字体后缀(如
/\.(woff2?|ttf|eot|otf)$/i),优先从 cache.match 返回 - 静默更新缓存:若缓存未命中,fetch 后克隆响应并存入缓存,不影响当前请求,且下次访问即命中
字体路径与 @font-face 必须严格对齐
Service Worker 缓存的是请求 URL,不是字体名。如果 CSS 中写的是:
@font-face { src: url('/fonts/main.woff2') format('woff2'); }那么 Service Worker 的缓存数组就必须包含 '/fonts/main.woff2',不能写成 './fonts/main.woff2' 或相对路径。建议所有字体统一放在 /fonts/ 目录下,并在构建时校验路径一致性。
配合 font-display 提升首屏体验
仅靠缓存还不够。务必为每个 @font-face 设置 font-display: optional 或 swap:
-
optional:浏览器判断加载慢则直接用系统字体,不等;适合非品牌核心文本 -
swap:立即显示后备字体,字体加载完再切换;适合标题、按钮等关键文字
Service Worker 保证字体“有”,font-display 决定“怎么用”——两者协同,才能真正消灭布局跳动。

















