如何避免Worker每次创建时重新加载JS文件 实现页面离线正常运行
实现Worker脚本当前会话缓存的解决方案
方案1:缓存为Blob URL(完全符合当前会话缓存需求)
这种方案会在首次加载Worker脚本后将内容存在内存中,后续创建Worker时直接使用内存中的脚本,不会发起任何网络请求,断网场景也能正常使用。
修改后的完整代码如下:
let my_worker = null // 新增:用于存储缓存后的Worker脚本Blob地址 let cached_worker_url = null async function start(from_v, to_v){ // 首次运行时拉取脚本并缓存为Blob URL if (!cached_worker_url) { const response = await fetch('wwa_worker.js') const worker_content = await response.text() const blob = new Blob([worker_content], { type: 'application/javascript' }) cached_worker_url = URL.createObjectURL(blob) } // 所有场景都使用缓存地址创建Worker,无网络请求 my_worker = new Worker(cached_worker_url) my_worker.postMessage({ from_val: from_v, to_val: to_v }) my_worker.onmessage = function (e) { result_field.value = e.data } } function stop(){ if (my_worker) { my_worker.terminate() my_worker = null } } // 页面卸载时释放内存,避免内存泄漏 window.addEventListener('beforeunload', () => { if (cached_worker_url) { URL.revokeObjectURL(cached_worker_url) } })
方案2:复用Worker实例(性能最优)
如果你的业务场景允许不销毁Worker实例,可以只初始化一次Worker,后续启停都复用同一个实例,完全不存在重复加载脚本的问题:
// 全局仅初始化一次Worker const my_worker = new Worker('wwa_worker.js') my_worker.onmessage = function (e) { result_field.value = e.data } function start(from_v, to_v){ // 发送启动指令和参数 my_worker.postMessage({ type: 'start', from_val: from_v, to_val: to_v }) } function stop(){ // 发送停止指令,不销毁Worker实例 my_worker.postMessage({ type: 'stop' }) }
注意:需要同步修改
wwa_worker.js内部逻辑,新增对start、stop指令的判断处理。
方案3:持久化离线缓存(支持跨会话离线使用)
如果需要页面关闭后下次打开断网也能正常使用,可以给wwa_worker.js配置HTTP强缓存响应头:Cache-Control: public, max-age=31536000, immutable
浏览器会自动缓存该脚本,后续请求优先读本地缓存,断网时也能正常加载。
内容的提问来源于stack exchange,提问作者DeNice
相关产品推荐
相关产品推荐

