惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

B
Blog
T
Threatpost
N
News and Events Feed by Topic
C
Cybersecurity and Infrastructure Security Agency CISA
Cyberwarzone
Cyberwarzone
C
CXSECURITY Database RSS Feed - CXSecurity.com
A
Arctic Wolf
C
Cyber Attacks, Cyber Crime and Cyber Security
AI
AI
GbyAI
GbyAI
Recent Announcements
Recent Announcements
Security Latest
Security Latest
Scott Helme
Scott Helme
W
WeLiveSecurity
S
Schneier on Security
人人都是产品经理
人人都是产品经理
Recent Commits to openclaw:main
Recent Commits to openclaw:main
博客园_首页
Forbes - Security
Forbes - Security
Simon Willison's Weblog
Simon Willison's Weblog
S
Security @ Cisco Blogs
The Register - Security
The Register - Security
H
Hacker News: Front Page
V
Visual Studio Blog
P
Privacy & Cybersecurity Law Blog
P
Privacy International News Feed
TaoSecurity Blog
TaoSecurity Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
N
News | PayPal Newsroom
Hacker News - Newest:
Hacker News - Newest: "LLM"
Google DeepMind News
Google DeepMind News
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
C
CERT Recently Published Vulnerability Notes
Y
Y Combinator Blog
D
Docker
I
InfoQ
AWS News Blog
AWS News Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
S
Securelist
L
LINUX DO - 最新话题
阮一峰的网络日志
阮一峰的网络日志
Help Net Security
Help Net Security
G
GRAHAM CLULEY
G
Google Developers Blog
The Last Watchdog
The Last Watchdog
Hugging Face - Blog
Hugging Face - Blog
Blog — PlanetScale
Blog — PlanetScale
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Stack Overflow Blog
Stack Overflow Blog
I
Intezer

青空之蓝

[青空之蓝-2023] - 色彩 | 青空之蓝 [青空之蓝-2022] - 平静 | 青空之蓝 [青空之蓝-2021] - 远望 | 青空之蓝 浅谈垃圾回收 | 青空之蓝 浅谈泛型擦除 | 青空之蓝 浅谈单点登录 | 青空之蓝 使用 Kotlin 编写 Spring 测试 | 青空之蓝 设计模式系列文章 | 青空之蓝 从零实现一个 Java 微框架 - IoC | 青空之蓝 从零实现一个 Java 微框架 - 前言 | 青空之蓝 浅谈 JVM:类加载 | 青空之蓝 浅谈 IO | 青空之蓝 浅谈并发:synchronized & ReentrantLock | 青空之蓝 浅谈并发:CAS & AQS | 青空之蓝 浅谈并发:ThreadLocal | 青空之蓝 浅谈并发:三大特性 | 青空之蓝 浅谈组合注解 & 注解别名 | 青空之蓝 [青空之蓝-2020]-迷茫 | 青空之蓝 Java 系列文章 | 青空之蓝 HTTP 系列文章 | 青空之蓝 浅谈 EatWhatYouKill | 青空之蓝 浅谈可扩展线程池 | 青空之蓝 聊聊写框架 | 青空之蓝 聊聊现状-[2020-09] | 青空之蓝 浅谈并发:锁 | 青空之蓝 浅谈并发:基础 | 青空之蓝 浅谈缓存 | 青空之蓝 无须定义类,Spring 快速注入 Json 参数 | 青空之蓝 浅谈 Proxy 和 Aop | 青空之蓝 从零实现一个 PHP 微框架 - 初始化请求 | 青空之蓝 为 Vue3 添加一个简单的 Store | 青空之蓝 从零实现一个 PHP 微框架 - 服务提供者 | 青空之蓝 WSL2 踩坑记录 | 青空之蓝 浅谈浏览器Event Loop [更新] | 青空之蓝 从零实现一个 PHP 微框架 - Bootstrap 启动加载 | 青空之蓝 从零实现一个 PHP 微框架 - IoC 容器 | 青空之蓝 从零实现一个 PHP 微框架 - PSR & Composer | 青空之蓝 从零实现一个 PHP 微框架 - 前言 | 青空之蓝 MVVM 简单实现 | 青空之蓝 浅谈 DI 和 IoC | 青空之蓝 中间件实现 [PHP] | 青空之蓝 告别 Windows 终端的难看难用,打造好用的 PowerShell | 青空之蓝 VSCode Java输出中文乱码问题解决[更新] | 青空之蓝 浅谈浏览器渲染 | 青空之蓝 Vue-Cli@2 项目迁移日志 | 青空之蓝 Laragon & Scoop 集成踩坑记录 | 青空之蓝 「一行代码」优雅管理 Windows 软件 | 青空之蓝 [青空之蓝-2019]-年度总结 | 青空之蓝 为Vue添加简单的Store | 青空之蓝 为React添加简单的Store | 青空之蓝 为Vuex添加同步Action | 青空之蓝 浅谈B+树 | 青空之蓝 浅谈跳表 | 青空之蓝 浅谈数据库索引 | 青空之蓝 MySQL事务隔离 | 青空之蓝 算法复杂度分析(1) | 青空之蓝 一年来的经验总结 | 青空之蓝 Acrylic - VSCode Extension | 青空之蓝 ace编辑器设置惯性滚动 | 青空之蓝 Java二叉树实现 | 青空之蓝 Java图实现 | 青空之蓝 为apt方式安装的nginx重新编译增加WebDAV | 青空之蓝 XK-Editor - 一个支持富文本和Markdown的编辑器 | 青空之蓝 JS生成列表树 | 青空之蓝 Laravel生成目录树 | 青空之蓝 XK-Note - 集各种神奇功能的云笔记 | 青空之蓝 PHP GD生成验证码 | 青空之蓝 PHP GD图片处理[转换格式-水印-缩略图] | 青空之蓝 Origami - 简洁轻快的WordPress主题 | 青空之蓝 [青空之蓝-2018]-年度总结 | 青空之蓝 VSCode Java手动导入jar和源码包 | 青空之蓝 Windows IP变化自动发送邮件 | 青空之蓝 C链表实现重制版 | 青空之蓝 C 结构体的定义和使用 | 青空之蓝 图的搜索(遍历) - BFS & DFS | 青空之蓝 Java链表实现 | 青空之蓝 C 快速排序 | 青空之蓝 C 插入排序 | 青空之蓝 C 归并排序 | 青空之蓝 C语言链表实现 | 青空之蓝 VSCode配置Java调试环境[Windows] | 青空之蓝 C 选择排序 | 青空之蓝 C 冒泡排序 | 青空之蓝 VSCode配置PHP调试环境[Windows] | 青空之蓝 VSCode配置C/C++ GDB调试环境[Windows] | 青空之蓝 WordPress友情链接模板 | 青空之蓝 Intel Optane 傲腾内存体验 | 青空之蓝 Mysql双机热备实战 | 青空之蓝 博客一年记录 | 青空之蓝 为WordPress启用Service Worker | 青空之蓝 Bing每日一图API | 青空之蓝 iframe延迟加载 | 青空之蓝 写在2018年高考前 | 青空之蓝 The Fox主题汉化分享 | 青空之蓝 [青空之蓝-2017]-崭新 | 青空之蓝 本博客评论规则 | 青空之蓝 世界,您好! | 青空之蓝
为WordPress启用WorkBox | 青空之蓝
Otstar Lin · 2019-02-02 · via 青空之蓝

若你是一个追求极致 Web 体验的站长,那你一定或多或少都听说过 Service Worker,而现在已经是 2019 年了,Service Worker 已经不是一项令人惊叹的技术了,Service Worker 会接管全站的请求,若一不留神用户说不定就再也无法看到站点最新的资讯了,不过 Google Chrome 团队推出了 Workbox,使编写缓存规则不再困难。

本文是面向 WordPress 的教程,不适用于 Typecho

使用方法

注册 Service Worker

在主题的 functions.php 加入以下代码

function origami_setting_workbox()
{
    echo "<script>if ('serviceWorker' in navigator) {
        window.addEventListener('load', () => {
            navigator.serviceWorker.register('/sw.js');
        });
    }</script>";
}
add_action('wp_footer', 'origami_setting_workbox', '101');
function origami_setting_workbox()
{
    echo "<script>if ('serviceWorker' in navigator) {
        window.addEventListener('load', () => {
            navigator.serviceWorker.register('/sw.js');
        });
    }</script>";
}
add_action('wp_footer', 'origami_setting_workbox', '101');

引入 WorkBox 框架

importScripts("https://cdn.jsdelivr.net/npm/workbox-cdn@3.6.3/workbox/workbox-sw.js");
workbox.setConfig({
  modulePathPrefix: "https://cdn.jsdelivr.net/npm/workbox-cdn@3.6.3/workbox/",
});

if (workbox) {
  console.log(`Yay! Workbox is loaded ?`);
} else {
  console.log(`Boo! Workbox didn't load ?`);
}
importScripts("https://cdn.jsdelivr.net/npm/workbox-cdn@3.6.3/workbox/workbox-sw.js");
workbox.setConfig({
  modulePathPrefix: "https://cdn.jsdelivr.net/npm/workbox-cdn@3.6.3/workbox/",
});

if (workbox) {
  console.log(`Yay! Workbox is loaded ?`);
} else {
  console.log(`Boo! Workbox didn't load ?`);
}

若成功引入就会在浏览器的控制台中输出Yay! Workbox is loaded ?

同时可以在开发工具中的 Application 选项卡中的 Service Workers 中看到激活信息

写入规则

由于 WordPress 是动态博客,所以在写规则的就会遇到一些静态博客不会遇到的问题,比如静态博客的页面是已经渲染好的,只要缓存 html 等静态文件就可以实现离线访问,而 php 的页面是实时渲染的,并且有后台,还有评论系统,这些都不能进行缓存

建议安装 WP Super Cache

首先定义缓存的版本号和默认最大缓存数目(可以忽略,但后面的代码需要进行修改)

let cacheSuffixVersion = "-181111";
const maxEntries = 100;
let cacheSuffixVersion = "-181111";
const maxEntries = 100;

然后限制必须使用网络的资源

// 由于我的主题评论是使用Ajax获取然后由前端渲染的,所以要将其设置为网络优先
workbox.routing.registerRoute(/.*\?action.*/, workbox.strategies.networkFirst());
// Ajax评论设置为只使用网络
workbox.routing.registerRoute(/.*&action.*/, workbox.strategies.networkOnly());
// 后台也设置为只使用网络
workbox.routing.registerRoute(/.*wp-admin.*/, workbox.strategies.networkOnly());
// 将rss,sitemap等需要实时更新的页面设为只使用网络
workbox.routing.registerRoute(/.*sitemap.*/, workbox.strategies.networkOnly());
workbox.routing.registerRoute(/.*feed.*/, workbox.strategies.networkOnly());
// 匹配html页面
workbox.routing.registerRoute(
  // 使用正则表达式匹配路由
  /.*\.html'/,
  workbox.strategies.cacheFirst({
    // cache storage 名称和版本号
    cacheName: "html-cache" + cacheSuffixVersion,
    plugins: [
      // 使用 expiration 插件实现缓存条目数目和时间控制
      new workbox.expiration.Plugin({
        // 最大保存项目
        maxEntries,
        // 缓存 30 天
        maxAgeSeconds: 30 * 24 * 60 * 60,
      }),
      // 使用 cacheableResponse 插件缓存状态码为 0 的请求
      new workbox.cacheableResponse.Plugin({
        statuses: [0, 200],
      }),
    ],
  })
);
// 全站缓存的关键代码
workbox.routing.registerRoute(
  // 此处需要更改为站点对应的URL
  new RegExp("https://dev.ixk.me.*"),
  workbox.strategies.staleWhileRevalidate({
    cacheName: "blog-cache" + cacheSuffixVersion,
    plugins: [
      // 使用 expiration 插件实现缓存条目数目和时间控制
      new workbox.expiration.Plugin({
        // 最大保存项目
        maxEntries,
        // 缓存 30 天
        maxAgeSeconds: 30 * 24 * 60 * 60,
      }),
      // 使用 cacheableResponse 插件缓存状态码为 0 的请求
      new workbox.cacheableResponse.Plugin({
        statuses: [0, 200],
      }),
    ],
  })
);
// 图片,样式表,字体的缓存
workbox.routing.registerRoute(
  // Cache Image File
  /.*\.(?:png|jpg|jpeg|svg|gif)/,
  workbox.strategies.staleWhileRevalidate({
    cacheName: "img-cache" + cacheSuffixVersion,
    plugins: [
      // 使用 expiration 插件实现缓存条目数目和时间控制
      new workbox.expiration.Plugin({
        // 最大保存项目
        maxEntries,
        // 缓存 30 天
        maxAgeSeconds: 30 * 24 * 60 * 60,
      }),
      // 使用 cacheableResponse 插件缓存状态码为 0 的请求
      new workbox.cacheableResponse.Plugin({
        statuses: [0, 200],
      }),
    ],
  })
);

workbox.routing.registerRoute(
  // Cache CSS & JS files
  /.*\.(css|js)/,
  workbox.strategies.staleWhileRevalidate({
    cacheName: "static-assets-cache",
    plugins: [
      // 使用 expiration 插件实现缓存条目数目和时间控制
      new workbox.expiration.Plugin({
        // 最大保存项目
        maxEntries,
        // 缓存 30 天
        maxAgeSeconds: 30 * 24 * 60 * 60,
      }),
      // 使用 cacheableResponse 插件缓存状态码为 0 的请求
      new workbox.cacheableResponse.Plugin({
        statuses: [0, 200],
      }),
    ],
  })
);

workbox.routing.registerRoute(
  // Cache Fonts files
  /.*\.(woff|woff2)/,
  workbox.strategies.staleWhileRevalidate({
    cacheName: "static-assets-cache",
    plugins: [
      // 使用 expiration 插件实现缓存条目数目和时间控制
      new workbox.expiration.Plugin({
        // 最大保存项目
        maxEntries,
        // 缓存 30 天
        maxAgeSeconds: 30 * 24 * 60 * 60,
      }),
      // 使用 cacheableResponse 插件缓存状态码为 0 的请求
      new workbox.cacheableResponse.Plugin({
        statuses: [0, 200],
      }),
    ],
  })
);
// 其他的默认规则
workbox.routing.setDefaultHandler(
  workbox.strategies.networkFirst({
    options: [
      {
        // 超过 3s 请求没有响应则 fallback 到 cache
        networkTimeoutSeconds: 3,
      },
    ],
  })
);
// 由于我的主题评论是使用Ajax获取然后由前端渲染的,所以要将其设置为网络优先
workbox.routing.registerRoute(/.*\?action.*/, workbox.strategies.networkFirst());
// Ajax评论设置为只使用网络
workbox.routing.registerRoute(/.*&action.*/, workbox.strategies.networkOnly());
// 后台也设置为只使用网络
workbox.routing.registerRoute(/.*wp-admin.*/, workbox.strategies.networkOnly());
// 将rss,sitemap等需要实时更新的页面设为只使用网络
workbox.routing.registerRoute(/.*sitemap.*/, workbox.strategies.networkOnly());
workbox.routing.registerRoute(/.*feed.*/, workbox.strategies.networkOnly());
// 匹配html页面
workbox.routing.registerRoute(
  // 使用正则表达式匹配路由
  /.*\.html'/,
  workbox.strategies.cacheFirst({
    // cache storage 名称和版本号
    cacheName: "html-cache" + cacheSuffixVersion,
    plugins: [
      // 使用 expiration 插件实现缓存条目数目和时间控制
      new workbox.expiration.Plugin({
        // 最大保存项目
        maxEntries,
        // 缓存 30 天
        maxAgeSeconds: 30 * 24 * 60 * 60,
      }),
      // 使用 cacheableResponse 插件缓存状态码为 0 的请求
      new workbox.cacheableResponse.Plugin({
        statuses: [0, 200],
      }),
    ],
  })
);
// 全站缓存的关键代码
workbox.routing.registerRoute(
  // 此处需要更改为站点对应的URL
  new RegExp("https://dev.ixk.me.*"),
  workbox.strategies.staleWhileRevalidate({
    cacheName: "blog-cache" + cacheSuffixVersion,
    plugins: [
      // 使用 expiration 插件实现缓存条目数目和时间控制
      new workbox.expiration.Plugin({
        // 最大保存项目
        maxEntries,
        // 缓存 30 天
        maxAgeSeconds: 30 * 24 * 60 * 60,
      }),
      // 使用 cacheableResponse 插件缓存状态码为 0 的请求
      new workbox.cacheableResponse.Plugin({
        statuses: [0, 200],
      }),
    ],
  })
);
// 图片,样式表,字体的缓存
workbox.routing.registerRoute(
  // Cache Image File
  /.*\.(?:png|jpg|jpeg|svg|gif)/,
  workbox.strategies.staleWhileRevalidate({
    cacheName: "img-cache" + cacheSuffixVersion,
    plugins: [
      // 使用 expiration 插件实现缓存条目数目和时间控制
      new workbox.expiration.Plugin({
        // 最大保存项目
        maxEntries,
        // 缓存 30 天
        maxAgeSeconds: 30 * 24 * 60 * 60,
      }),
      // 使用 cacheableResponse 插件缓存状态码为 0 的请求
      new workbox.cacheableResponse.Plugin({
        statuses: [0, 200],
      }),
    ],
  })
);

workbox.routing.registerRoute(
  // Cache CSS & JS files
  /.*\.(css|js)/,
  workbox.strategies.staleWhileRevalidate({
    cacheName: "static-assets-cache",
    plugins: [
      // 使用 expiration 插件实现缓存条目数目和时间控制
      new workbox.expiration.Plugin({
        // 最大保存项目
        maxEntries,
        // 缓存 30 天
        maxAgeSeconds: 30 * 24 * 60 * 60,
      }),
      // 使用 cacheableResponse 插件缓存状态码为 0 的请求
      new workbox.cacheableResponse.Plugin({
        statuses: [0, 200],
      }),
    ],
  })
);

workbox.routing.registerRoute(
  // Cache Fonts files
  /.*\.(woff|woff2)/,
  workbox.strategies.staleWhileRevalidate({
    cacheName: "static-assets-cache",
    plugins: [
      // 使用 expiration 插件实现缓存条目数目和时间控制
      new workbox.expiration.Plugin({
        // 最大保存项目
        maxEntries,
        // 缓存 30 天
        maxAgeSeconds: 30 * 24 * 60 * 60,
      }),
      // 使用 cacheableResponse 插件缓存状态码为 0 的请求
      new workbox.cacheableResponse.Plugin({
        statuses: [0, 200],
      }),
    ],
  })
);
// 其他的默认规则
workbox.routing.setDefaultHandler(
  workbox.strategies.networkFirst({
    options: [
      {
        // 超过 3s 请求没有响应则 fallback 到 cache
        networkTimeoutSeconds: 3,
      },
    ],
  })
);

结尾

至此站点除了后台,其他的页面应该就可以进行全站离线访问,但是由于使用了缓存,若站点未将评论分离的话,就会导致评论不能实时更新,这时候就可以使用第三方评论系统来代替默认评论,如 Disqus(国内处于被墙状态)

我的新主题已经使用了 WorkBox,可以去尝试一下 Link 从缓存中的加载页面的速度可以达到惊人的 219ms。

为WordPress启用WorkBox

https://blog.ixk.me/post/wordpress-enabled-workbox
  • 许可协议

    BY-NC-SA

  • 本文作者

    Otstar Lin

  • 发布于

    2019/02/02

转载或引用本文时请遵守许可协议,注明出处、不得用于商业用途!

Origami - 简洁轻快的WordPress主题[青空之蓝-2018]-年度总结