IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    通过Service Worker‌ 缓存优化 Typecho 的首页访问加速

    bosir发表于 2025-02-19 00:05:00
    love 0

    Service Worker‌ 是一种运行在浏览器背景的脚本,它可以在页面关闭后继续运行,主要用于处理网络请求、缓存资源、推送消息等功能。

    认识

    Service Worker 也是一个后台运行的脚本,充当一个代理服务器,拦截用户发出的网络请求,比如加载脚本和图片。Service Worker 可以修改用户的请求,或者直接向用户发出回应,不用联系服务器,这使得用户可以在离线情况下使用网络应用。它还可以在本地缓存资源文件,直接从缓存加载文件,因此可以加快访问速度。

    条件

    要使用 Service Worker‌ 确保网站支持 HTTPS 协议,这是必要条件。

    注册

    Typecho 使用的话,需要在主题的 header.php 或者 footer.php 里面添加如下代码,以完成 Service Worker 注册。

    <script>
        if ('serviceWorker' in navigator) {
            navigator.serviceWorker.register('/serviceworker.js')
                .then(registration => {
                    console.log('Service Worker 注册成功:', registration);
                })
                .catch(error => {
                    console.log('Service Worker 注册失败:', error);
                });
        }
    </script>
    

    新建

    在网站的根目录新建 serviceworker.js 和 offline.html 两个独立文件,其中js为引入的必需文件,offline为非必需离线文件。

    const CACHE_NAME = 'typecho-cache-v2';
    const OFFLINE_URL = '/offline.html';
    
    const urlsToCache = [
        '/',
        '/index.php',
        '/usr/themes/你的主题名字/css/style.min.css', /**css文件
        '/usr/themes/你的主题名字/js/script.min.js', /**js文件
        '/usr/uploads/ /**存储在服务器的图片或文件
        '/favicon.ico',
        OFFLINE_URL,
        'https://artalk.bosir.cn/dist/Artalk.js' /**第三方缓存文件
    ];
    
    self.addEventListener('install', event => {
        event.waitUntil(
            caches.open(CACHE_NAME)
                .then(cache => cache.addAll(urlsToCache))
                .then(() => self.skipWaiting())
        );
    });
    
    self.addEventListener('activate', event => {
        event.waitUntil(
            caches.keys().then(cacheNames => {
                return Promise.all(
                    cacheNames.map(name => {
                        if (name !== CACHE_NAME) {
                            return caches.delete(name);
                        }
                    })
                );
            }).then(() => self.clients.claim())
        );
    });
    
    self.addEventListener('fetch', event => {
        if (event.request.method !== 'GET') return;
    
        event.respondWith(
            caches.match(event.request).then(response => {
                if (response) return response;
    
                return fetch(event.request).then(response => {
                    if (!response || response.status !== 200 || response.type !== 'basic') {
                        return response;
                    }
                    const responseToCache = response.clone();
                    caches.open(CACHE_NAME).then(cache => cache.put(event.request, responseToCache));
                    return response;
                }).catch(() => {
                    return caches.match(OFFLINE_URL);
                });
            })
        );
    });
    

    offline模式,即离线模式,f12 打开开发者工具后找到 online选项,点击后会出现offine 字样,点击打开离线模式,刷新页面会发现首页依然可以访问,而没有缓存的页面就显示下面的离线页面。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>水清无鱼</title>
    </head>
    <body>
        <h1>离线模式</h1>
    </body>
    </html>
    

    缓存

    为了防止在浏览器需要请求新版本的 serviceworker.js 文件时,而文件自身被缓存,所以需要给 serviceworker.js 文件单独指定缓存头 Cache-control: no-store 或 no-cache 。然后在 Nainx 的 server { 区域内添加:

    # serviceworker.js 不设置缓存
    location ~* /(.*)/serviceworker\.js {
        add_header Cache-Control no-cache;
        add_header Pragma no-cache;
        add_header Expires 0;
    }
    

    添加完毕后,重启Nginx服务器。

    更新

    在更新 Service Worker 时,需要修改 CACHE_NAME 的版本号以触发缓存更新

    const CACHE_NAME = 'typecho-cache-v1';
    或
    const CACHE_NAME = 'typecho-cache-v2';
    

    总结

    整体来说,只要不涉及复杂的主题和js,Typecho 已经足够快,且拥有良好的打开速度。可如果你像我一样比较追求极致性能,喜欢折腾,也可以尝试一下。我的目标是把博客优化到和静态博客一样丝滑,目前缓存过后进入首页只需要100ms以内,en...

    题外话

    目前 typecho 已经出现了 1.3.0测试版本,没错,就是目前我现在使用的这个版本。不过我并不建议大家进行升级,毕竟BUG有点多。我目前是全站 0 插件,测试版本的兼容性有待考量。且如果php像我一样为最新版,出现的问题可能更多...

    参考资料

    1.// cloud.tencent.com/developer/article/2005909

    2.// www.luolt.cn/archives/1848.html

    3.// www.bookstack.cn/read/webapi-tutorial/docs-service-worker.md



沪ICP备19023445号-2号
友情链接