HTML5的Service Worker作为运行在浏览器后台的脚本,能够拦截网络请求、管理缓存资源,是实现PWA离线能力的核心基础。通过合理配置Service Worker,我们可以让网页在无网络或弱网环境下依然正常展示核心内容,提升用户的使用体验。

Service Worker基础认知
Service Worker是一个独立于网页主线程的 worker 脚本,它无法直接操作DOM,主要通过事件监听的方式处理网络请求和缓存逻辑。它的运行不依赖页面,即使页面关闭,只要没有被注销,依然可以在后台运行。
使用Service Worker需要注意几个前提条件:
- 必须在HTTPS环境下运行,本地开发时localhost和127.0.0.1可以例外
- 浏览器需要支持Service Worker特性,目前主流现代浏览器都已经支持
- Service Worker的作用域由注册时的路径决定,默认会控制其路径下所有页面的请求
用Service Worker实现离线缓存的核心步骤
1. 注册Service Worker
首先需要在网页的主脚本中注册Service Worker,指定对应的脚本文件路径。注册操作需要在页面加载完成后执行,避免影响页面的正常渲染。
// 检查浏览器是否支持Service Worker
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
// 注册service-worker.js脚本,作用域为当前页面所在目录
navigator.serviceWorker.register('/service-worker.js')
.then(function(registration) {
console.log('Service Worker注册成功,作用域为: ', registration.scope);
})
.catch(function(error) {
console.log('Service Worker注册失败: ', error);
});
});
}
2. 编写Service Worker缓存逻辑
Service Worker脚本中主要处理三个核心事件:install(安装阶段)、activate(激活阶段)、fetch(请求拦截阶段)。
安装阶段缓存静态资源
在install事件中,我们可以预缓存网页需要的静态资源,比如HTML、CSS、JS、图片等,这些资源会被存到浏览器的Cache Storage中。
// 定义缓存名称和需要预缓存的资源列表
const CACHE_NAME = 'my-site-cache-v1';
const urlsToCache = [
'/',
'/index.html',
'/style.css',
'/main.js',
'/logo.png'
];
// 监听install事件,预缓存资源
self.addEventListener('install', function(event) {
// 等待所有缓存操作完成后再结束install阶段
event.waitUntil(
caches.open(CACHE_NAME)
.then(function(cache) {
console.log('缓存已打开');
return cache.addAll(urlsToCache);
})
);
});
激活阶段清理旧缓存
当Service Worker更新后,新的脚本安装完成会进入activate阶段,此时可以清理之前版本的旧缓存,避免占用存储空间。
// 监听activate事件,清理旧缓存
self.addEventListener('activate', function(event) {
event.waitUntil(
caches.keys().then(function(cacheNames) {
return Promise.all(
cacheNames.map(function(cacheName) {
// 如果缓存名称不是当前版本,就删除
if (cacheName !== CACHE_NAME) {
console.log('删除旧缓存: ', cacheName);
return caches.delete(cacheName);
}
})
);
})
);
});
请求拦截阶段返回缓存内容
在fetch事件中,我们可以拦截页面的所有网络请求,优先返回缓存中的内容,如果缓存没有再请求网络,同时可以把新的请求结果更新到缓存中。
// 监听fetch事件,拦截请求返回缓存内容
self.addEventListener('fetch', function(event) {
event.respondWith(
caches.match(event.request)
.then(function(response) {
// 如果缓存中有对应请求的内容,直接返回
if (response) {
return response;
}
// 缓存中没有,就发起网络请求
return fetch(event.request).then(function(networkResponse) {
// 检查请求是否有效,状态码200且类型是basic(同源请求)
if (!networkResponse || networkResponse.status !== 200 || networkResponse.type !== 'basic') {
return networkResponse;
}
// 克隆响应,因为响应流只能被读取一次
const responseToCache = networkResponse.clone();
// 把新的请求结果存入缓存
caches.open(CACHE_NAME)
.then(function(cache) {
cache.put(event.request, responseToCache);
});
return networkResponse;
});
})
);
});
PWA技术的核心步骤
PWA(Progressive Web App)是一套结合了多种Web技术的方案,Service Worker只是其中一部分,完整的PWA落地还需要以下步骤:
1. 配置Web App Manifest
Manifest是一个JSON文件,用于定义PWA的名称、图标、启动页、显示模式等信息,让网页可以被添加到手机桌面,以类原生应用的方式启动。
首先创建manifest.json文件:
{
"name": "我的PWA应用",
"short_name": "PWA应用",
"description": "一个支持离线访问的PWA示例应用",
"start_url": "/index.html",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#2196f3",
"icons": [
{
"src": "/icon-192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/icon-512.png",
"sizes": "512x512",
"type": "image/png"
}
]
}
然后在HTML页面的<head>中引入该文件:
<link rel="manifest" href="/manifest.json">
2. 确保HTTPS部署
PWA的很多特性包括Service Worker都要求页面运行在HTTPS环境下,因此需要给网站配置SSL证书,确保通过HTTPS协议访问。如果是本地开发环境,localhost和127.0.0.1可以不需要HTTPS。
3. 实现响应式布局
PWA需要适配不同的设备屏幕,因此需要采用响应式布局方案,确保网页在手机、平板、PC等不同设备上都能正常展示,提升用户体验。
4. 优化加载性能
除了离线缓存,还可以通过代码分割、图片懒加载、压缩资源等方式优化网页的加载性能,让PWA的启动速度和运行速度更接近原生应用。
常见问题与注意事项
- Service Worker更新后,需要用户关闭所有相关页面再重新打开,新的Service Worker才会激活,也可以通过
self.skipWaiting()跳过等待阶段 - Cache Storage的存储空间是有限的,需要合理规划缓存的资源,避免缓存过多内容导致存储失败
- 调试Service Worker可以在Chrome浏览器的开发者工具Application面板中查看,能够看到注册的Service Worker、缓存的内容等信息
Service Worker的缓存策略可以根据实际需求调整,比如可以设置只缓存核心静态资源,动态内容还是走网络请求,平衡离线体验和内容的实时性。
Service_WorkerHTML5PWA离线缓存修改时间:2026-07-04 05:21:30