您是否遇到过网站加载时间过长的情况,如下图所示?
?你听说过服务人员吗?
在这篇文章中,我们将深入探讨什么是 Service Worker?、它们如何工作 ⚙️,以及我如何使用它们来提高 Web 应用程序的性能。
什么是 Service Worker? ?
Service Worker 是一个独立于网页运行的后台脚本,可以:
Service Workers 的主要特征:
这是 Service Worker 脚本的一个简单示例:
if ('serviceWorker' in navigator) { window.addEventListener('load', function() { navigator.serviceWorker.register('/service-worker.js').then(function(registration) { console.log('Service Worker registered with scope:', registration.scope); }).catch(function(error) { console.error('Service Worker registration failed:', error); }); }); }
?在此代码片段中,服务工作线程 (service-worker.js) 在页面加载时注册。如果注册成功,它会记录 Service Worker 的范围;否则,它会记录错误。
我正在将 Unity WebGL 游戏集成到 .NET Razor 网站中。该游戏由大型“.wasm”和“.data”文件以及对于游戏加载至关重要的 JavaScript 文件组成。然而,第一次加载页面花了20多秒! ?这主要是由于“.wasm”和“.data”文件的大小造成的。
我创建了一个“ServiceWorker.js”文件,它缓存所有必要的游戏资源以减少加载时间。该文件包含以下内容:
const cacheName = "$Project_name"; const contentToCache = [ "Build/Game.loader.js", "Build/Game.framework.js", "Build/Game.data", "Build/Game.wasm", "TemplateData/game_style.css" ]; self.addEventListener('install', function (e) { console.log('[Service Worker] Install'); e.waitUntil((async function () { try { const cache = await caches.open(cacheName); console.log('[Service Worker] Caching all: app shell and content'); for (const resource of contentToCache) { try { await cache.add(resource); } catch (error) { console.error(`[Service Worker] Failed to cache: ${resource}`, error); } } } catch (error) { console.error('[Service Worker] Failed to open cache', error); } })()); }); self.addEventListener('fetch', function (e) { e.respondWith((async function () { try { const response = await caches.match(e.request); console.log(`[Service Worker] Fetching resource: ${e.request.url}`); if (response) return response; const fetchResponse = await fetch(e.request); const cache = await caches.open(cacheName); console.log(`[Service Worker] Caching new resource: ${e.request.url}`); await cache.put(e.request, fetchResponse.clone()); return fetchResponse; } catch (error) { console.error(`[Service Worker] Error fetching resource: ${e.request.url}`, error); throw error; } })()); });
这段代码的作用是什么?
此服务工作线程脚本执行以下操作:
通过缓存这些资源,加载时间从 20 秒减少到 3 秒以下?当用户下次访问该页面时,资产已经存储在本地,大大加快了体验速度。
虽然这种方法对于提高性能有奇效,但它引入了另一个问题:过时的缓存文件。由于我们正在积极开发Unity游戏并发布新版本,因此每次部署新版本时都需要清除缓存文件。
为了解决这个问题,我创建了一个管道脚本,每当我们发布新的游戏版本时,它都会自动取消注册旧的服务工作者并清除缓存。这可确保用户始终加载最新的资源,而不会被旧的缓存版本所困扰。
在 Web 应用程序中实现 Service Worker 可以显着提高性能,尤其是在处理大型资源(例如在我的 Unity WebGL 游戏中)时。然而,重要的是仔细处理缓存以避免提供过时的文件。
您在优化加载时间方面有类似的经历吗?您使用了服务人员或其他技术吗?在下面的评论中分享您的想法和见解! ?
希望您今天学到了新东西! ✌️
免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。
Copyright© 2022 湘ICP备2022001581号-3