全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-16 10 分钟 ✍️ juanwangdev

Web Workers与Service Workers

Web Workers实现浏览器多线程,Service Workers提供离线缓存能力。

Web Workers

基本用法

JavaScript
// 主线程创建Worker
const worker = new Worker('worker.js');

// 发送消息
worker.postMessage({ data: 'hello' });

// 接收消息
worker.onmessage = function(e) {
    console.log(e.data);
};

// 错误处理
worker.onerror = function(e) {
    console.error(e.message);
};

// 终止Worker
worker.terminate();

Worker脚本

JavaScript
// worker.js
self.onmessage = function(e) {
    const result = heavyComputation(e.data);
    self.postMessage(result);
};

function heavyComputation(data) {
    // 耗时计算
    return data * 2;
}

内联Worker

JavaScript
const blob = new Blob([`
    self.onmessage = function(e) {
        self.postMessage(e.data * 2);
    };
`], { type: 'application/javascript' });

const worker = new Worker(URL.createObjectURL(blob));

双向通信

JavaScript
// 主线程
worker.postMessage({ type: 'start', data: 100 });

// Worker
self.onmessage = function(e) {
    if (e.data.type === 'start') {
        // 处理数据
        self.postMessage({ type: 'result', data: result });
    }
};

Shared Workers

创建与连接

JavaScript
// 多个页面共享同一个Worker
const sharedWorker = new SharedWorker('shared.js');

// 通过port通信
sharedWorker.port.start();
sharedWorker.port.postMessage('hello');
sharedWorker.port.onmessage = function(e) {
    console.log(e.data);
};

Shared Worker脚本

JavaScript
// shared.js
const ports = [];

self.onconnect = function(e) {
    const port = e.ports[0];
    ports.push(port);

    port.onmessage = function(e) {
        // 广播给所有连接
        ports.forEach(p => p.postMessage(e.data));
    };
};

Service Workers

注册

JavaScript
// 主线程注册
if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('/sw.js')
        .then(reg => console.log('注册成功', reg.scope))
        .catch(err => console.error('注册失败', err));
}

生命周期

状态说明
installing正在安装
installed安装完成,等待激活
activating正在激活
activated激活完成,可控制页面
redundant废弃

Service Worker脚本

JavaScript
// sw.js

// 安装事件 - 缓存静态资源
self.addEventListener('install', function(e) {
    e.waitUntil(
        caches.open('v1').then(cache => {
            return cache.addAll([
                '/',
                '/style.css',
                '/app.js'
            ]);
        })
    );
});

// 激活事件 - 清理旧缓存
self.addEventListener('activate', function(e) {
    e.waitUntil(
        caches.keys().then(keys => {
            return Promise.all(
                keys.filter(k => k !== 'v1')
                    .map(k => caches.delete(k))
            );
        })
    );
});

// 请求拦截 - 缓存策略
self.addEventListener('fetch', function(e) {
    e.respondWith(
        caches.match(e.request)
            .then(response => response || fetch(e.request))
    );
});

缓存策略

Cache First

JavaScript
// 优先缓存,无则请求
self.addEventListener('fetch', function(e) {
    e.respondWith(
        caches.match(e.request).then(response => {
            return response || fetch(e.request);
        })
    );
});

Network First

JavaScript
// 优先网络,失败则缓存
self.addEventListener('fetch', function(e) {
    e.respondWith(
        fetch(e.request).catch(() => caches.match(e.request))
    );
});

Stale While Revalidate

JavaScript
// 返回缓存同时更新
self.addEventListener('fetch', function(e) {
    e.respondWith(
        caches.match(e.request).then(response => {
            const fetchPromise = fetch(e.request).then(res => {
                caches.open('v1').then(cache => cache.put(e.request, res));
                return res;
            });
            return response || fetchPromise;
        })
    );
});

注意事项

  • Worker不能直接操作DOM,必须通过消息通信
  • Service Worker只能运行在HTTPS或localhost
  • Service Worker作用域默认是注册路径及其子路径
  • Worker中可使用importScripts()加载脚本

要点总结

  • Web Workers用于CPU密集型任务,不阻塞主线程
  • 主线程与Worker通过postMessage/onmessage通信
  • Service Workers提供离线缓存和请求拦截能力
  • 缓存策略包括Cache First、Network First、Stale While Revalidate
  • Service Worker生命周期:install -> activate -> fetch

存放路径:articles/JS/进阶/浏览器与DOM高级/Web Workers与Service Workers.md

📝 发现内容有误?点击此处直接编辑

← 上一篇 BOM与浏览器对象
下一篇 → 事件处理与委托
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库