使用ServiceWorker提高性能

简介: service worker 是一种在独立的处理线程上执行后台任务的 worker,允许用户拦截网络请求并有条件地将其存储在称为 CacheStorage API 的特殊缓存中,此类缓存不同于本地浏览器缓存,因为它允许在用户脱机的情况下从缓存中提供数据,还可以提高页面的性能。其工作原理建议阅读《ServiceWorker工作原理、生命周期和使用场景》

service worker 是一种在独立的处理线程上执行后台任务的 worker,允许用户拦截网络请求并有条件地将其存储在称为 CacheStorage API 的特殊缓存中,此类缓存不同于本地浏览器缓存,因为它允许在用户脱机的情况下从缓存中提供数据,还可以提高页面的性能。其工作原理建议阅读《ServiceWorker工作原理、生命周期和使用场景

这在大多数情况下都是很有用的,例如,如果用户在一个 WIFI 连接不好的地区,Service worker 可以帮助解决这个问题,它可以先为用户提供已经看到的缓存内容,让用户有东西可看,而不是什么都没有。

注册 service worker

首先创建一个 registerServiceWorker.js 文件,用来维护注册 service worker ,并将其脚本引入 html 页面或者项目。

if ("serviceWorker" in navigator) {
    window.addEventListener("load", () => {
        navigator.serviceWorker
            .register("/service-worker.js")
            .then((reg) => console.log("Service worker has been registered."))
            .catch((err) =>
                console.error(`Error during service worker registration:${err}`)
            );
    });
} else {
    console.log("Service worker is not supported by browser.");
}

navigator 是一个对象,它具有关于运行脚本的应用程序的属性和方法。回到文件  registerServiceWorker.js  并贴入一下代码:

const cacheName = "v1";
const cachedAssets = ["script.js", "index.html"];
self.addEventListener("install", (e) => {
    e.waitUntil(
        caches
            .open(cacheName)
            .then((cache) => cache.addAll(cachedAssets))
            .then(() => self.skipWaiting())
    );
});

需要将存储的资源存储在一个数组中,并向 window 对象添加 install 事件监听器。一旦触发该事件,将使用 cacheName 和数组中的资源创建一个新的缓存文件夹。之后,需要向窗口添加 activate 事件,以检查是否为最新的缓存版本。

self.addEventListener("activate", (e) => {
    e.waitUntil(
        caches.keys().then((cacheNames) => {
            return Promise.all(
                cacheNames.map((cache) => {
                    if (cache !== cacheName) {
                        return caches.delete(cache);
                    }
                })
            );
        })
    );
});

最重要的部分是从缓存存储中加载数据,继续添加以下代码:

self.addEventListener("fetch", (e) => {
    e.respondWith(fetch(e.request).catch(() => caches.match(e.request)));
});

上面的代码实现的功能是在窗口上添加 fetch 监听器,当这个事件被触发时,尝试通过使用 fetch API 发出网络请求来访问资源。在脱机的情况下,fetch API 不会返回任何数据,可以从缓存返回资源作为对原始请求的响应。为了控制用户脱机时发生的情况,需要一种介于本地和服务器之间的机制,允许缓存数据以便脱机查看。

在现代前端开发中,通常不需要自己的编写 service worker 的逻辑,对于复杂情况另说。下面是一个 VUE 项目中关于 service worker 的代码:

import { register } from "register-service-worker";
if (process.env.NODE_ENV === "production") {
    register(`${process.env.BASE_URL}service-worker.js`, {
        ready() {
            console.log(
                "App is being served from cache by a service worker.\n" +
                    "For more details, visit https://goo.gl/AFskqB"
            );
        },
        registered() {
            console.log("Service worker has been registered.");
        },
        cached() {
            console.log("Content has been cached for offline use.");
        },
        updatefound() {
            console.log("New content is downloading.");
        },
        updated() {
            console.log("New content is available; please refresh.");
        },
        offline() {
            console.log(
                "No internet connection found. App is running in offline mode."
            );
        },
        error(error) {
            console.error("Error during service worker registration:", error);
        },
    });
}

关于 service worker 的应用,还可以用于实现 MOCK 服务 《MSW:可用于浏览器和测试的Mock服务》。

Mock Service Worker 是一个 API 模拟库,它使用 Service Worker API 来拦截实际请求。 —— MSW docs

可以存储多少数据

可以存储的数据量因浏览器和设备而异,要验证可用空间,可以使用配额管理 API storageQuota

navigator.storageQuota.queryInfo("temporary").then(function (info) {
    console.log(info.quota);
});

当达到特定阈值时,一些浏览器会提示用户是否同意继续存储更多数据,一下是主流浏览器的触发阀值:

  • Firefox 存储 50MB 数据后
  • Safari 手机最多只能使用 50MB
  • Safari 桌面没有存储限制,但在存储 5MB 后开始请求确认。

测量性能

当从 service worker 缓存中检索资源时,可以获得比浏览器缓存更好的性能。这意味着可以通过降低浏览器开始绘制页面所需的时间来进一步加快用户的呈现性能。数据显示,当使用 service worker 来增强性能时,可以看到浏览器的缓存行为可用提高 50%。大大减少了渲染时间,这并不意味着浏览器缓存已经死了。对于WEB应用仍然需要它,可以在不支持 service worker 的浏览器中使用它。即使在支持 service worker 的浏览器中,也可以配置 fetch 事件代码来忽略不想拦截的请求,这时请求就会落在浏览器缓存中。

总结

当涉及到渲染时,service worker 可以显著提高应用程序的性能,只能在使用 https 的情况下使用,可以在不需要SSL证书的本地主机上开发它们,但在生产环境中就需要SSL证书。service worker  可以在缓存中存储内容,离线存储页面,在互联网连接不佳的情况下显示离线页面,还可以开发像移动应用程序一样快速且用户友好的渐进式 Web 应用程序 (PWA) ,如有兴趣可以参阅《如何 PWA 构建现代离线应用程序》。


相关文章
|
8月前
|
存储 缓存 算法
【C/C++ 性能优化】提高C++程序的缓存命中率以优化性能
【C/C++ 性能优化】提高C++程序的缓存命中率以优化性能
1171 0
|
3月前
|
缓存 监控 固态存储
如何优化磁盘性能?
【10月更文挑战第4天】如何优化磁盘性能?
136 4
ly~
|
3月前
|
缓存 中间件 数据库
FileRun 的性能如何?
FileRun 的性能受网络环境、硬件配置等因素影响。在网络和硬件条件优越的情况下,文件传输速度快,系统响应迅速,资源占用低。面对大量文件或高并发访问,需注意资源分配与系统优化,以维持稳定性和可扩展性。支持插件扩展,可与第三方应用集成,提升文件管理效率。
ly~
64 3
ly~
|
3月前
|
存储 监控 Linux
如何确定 FileRun 性能的瓶颈所在?
监控服务器资源使用情况,包括CPU使用率、内存使用量、磁盘I/O性能和网络带宽占用,确保FileRun运行顺畅。同时,分析数据库性能,如查询执行时间和连接数,以及检查FileRun内部操作日志,评估用户行为和并发访问对系统的影响。
ly~
54 4
|
5月前
|
Web App开发 API 图形学
QtWebEngine性能问题
QtWebEngine性能问题
182 1
|
JSON 数据库 数据格式
性能和可测试性的选择
性能和可测试性的选择
|
缓存 Ubuntu 网络协议
virtiofs性能
virtiofs性能测试
544 0
|
算法
HIMA F8621A 用于需要高带宽和低噪声性能
HIMA F8621A 用于需要高带宽和低噪声性能
HIMA F8621A 用于需要高带宽和低噪声性能
|
存储 缓存 JavaScript
优化SPA性能的方法
Web开发中,随着JavaScript的发展,越来越多的网站开始采用单页面应用程序(SPA)的方式来呈现内容。SPA相对于传统的多页面应用程序来说,具有更好的用户体验和更快的加载速度。但是,随着SPA的流行,页面越来越复杂,也面临着越来越多的性能问题。在这篇文章中,我们将讨论一些优化SPA性能的方法。
256 0
|
Dubbo 算法 NoSQL
记一次提升18倍的性能优化
最近负责的一个自研的 Dubbo 注册中心经常收到 CPU 使用率的告警,于是进行了一波优化,效果还不错,于是打算分享下思考、优化过程,希望对大家有一些帮助。 自研 Dubbo 注册中心是个什么东西,我画个简图大家稍微感受一下就好,看不懂也没关系,不影响后续的理解。
265 0
记一次提升18倍的性能优化

热门文章

最新文章