返回

用缓存技术助你优化 PWA,让用户离线浏览依然流畅!

前端

上周重构后,Lighthouse 的评分中「渐进式网络应用程序」一项让我耿耿于怀。PWA 算不上新话题,概念性内容和 API 就不详细介绍了。接下来将介绍一种无需改动即可对站点进行离线缓存的方案,整体代码量少于一百行。如果你也想在不“大动干戈”的情况下对站点……

PWA 的一个重要特性就是离线访问。当网络中断时,用户仍然可以访问站点的缓存内容。这对于提升用户体验和提高站点在搜索引擎中的排名都有很大帮助。

传统的客户端缓存技术有很多,比如 HTTP 缓存、Service Worker 缓存等。这些技术都可以有效地缓存静态资源,但对于动态资源的缓存却比较困难。

为了解决这个问题,本文介绍一种基于传统前端技术实现的动态资源缓存方案。该方案使用 Service Worker 来拦截请求,并将动态资源缓存到浏览器中。这样,当用户再次访问该资源时,浏览器可以直接从缓存中读取,无需再次向服务器发送请求。

该方案的优点是简单易用,代码量少,而且对原有代码的改动很小。缺点是只能缓存 GET 请求,无法缓存 POST 请求。

具体实现方法如下:

  1. 创建一个 Service Worker 文件,并将其注册到页面中。
  2. 在 Service Worker 中,监听 fetch 事件。
  3. 当 fetch 事件触发时,检查请求的 URL 是否是动态资源。
  4. 如果是动态资源,则将请求的响应缓存在浏览器中。
  5. 如果不是动态资源,则直接将请求转发给服务器。

该方案的代码如下:

// Service Worker 文件

// 监听 fetch 事件
self.addEventListener('fetch', function(event) {
  // 检查请求的 URL 是否是动态资源
  if (event.request.url.indexOf('api') > -1) {
    // 是动态资源,则将请求的响应缓存在浏览器中
    event.respondWith(cache.match(event.request));
  } else {
    // 不是动态资源,则直接将请求转发给服务器
    event.respondWith(fetch(event.request));
  }
});
// 页面中注册 Service Worker
if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/service-worker.js');
}

该方案已经在我个人的博客中使用,效果很好。感兴趣的朋友可以自行尝试。

除了上述方案,还有一些其他的方法可以增强客户端缓存能力。比如,使用 CDN 来缓存静态资源,使用 HTTP/2 来减少请求次数,使用 Brotli 压缩来减小资源体积等等。

总之,客户端缓存是一种非常重要的优化手段。通过合理地利用客户端缓存,可以有效地提升网站的性能和用户体验。