大家好,我是不如摸鱼去,uni-app vue3 组件库 wot-ui 的主要维护者,欢迎来到我的工具分享专栏。
前阵子解决网站国内访问慢的问题之前,总有朋友问:"网站太慢了,能离线使用吗?"
答案是:"可以!" 这需求正是 PWA 能解决的嘛!今天我们花几分钟时间,将我的个人博客改造为 PWA ,支持安装到本地并且可以离线访问,我的博客地址: blog.wot-ui.cn/。
PWA 是什么?
渐进式 Web 应用(Progressive Web App,PWA)是一个使用 web 平台技术构建的应用程序,但它提供的用户体验就像一个特定平台的应用程序。
它像网站一样,PWA 可以通过一个代码库在多个平台和设备上运行。它也像一个特定平台的应用程序一样,可以安装在设备上,可以离线和在后台运行,并且可以与设备和其他已安装的应用程序集成。
说句题外话,国内 PWA 的生态位其实是被各大 APP 的小程序占据了,不过小程序各自为战的标准实在是令人头疼,写小程序会让人变得烦恼,写多个平台的小程序会让人变得不幸。你可能会笑,而我却真的在写,wot-ui 组件库为了兼容多平台小程序不知道让我掉了多少头发。
PWA 可以安装到本地,支持离线访问,并将快捷方式放到启动台中。

VitePress 添加 PWA 支持
我博客是使用 VitePress 搭建的,生态里有个现成的插件 @vite-pwa/vitepress
,可以为 VitePress 项目添加 PWA 能力。
VitePress 是一个静态站点生成器 (SSG),专为构建快速、以内容为中心的站点而设计。简而言之,VitePress 获取用 Markdown 编写的内容,对其应用主题,并生成可以轻松部署到任何地方的静态 HTML 页面。 信息来自 vitepress 官网。
1. 安装
bash
# 我用的pnpm,快!
pnpm add @vite-pwa/vitepress -D
# npm/yarn用户自己替换一下
2. 配置(.vitepress/config.mts
)
这是核心步骤,直接上我改完的配置,关键地方我加了个**"唠叨版"注释**,解释下为啥这么设:
typescript
import { defineConfig } from 'vitepress'
import { withPwa } from '@vite-pwa/vitepress'
export default withPwa(defineConfig({
// 博客基础信息,老样子
title: '不如摸鱼去',
description: '不如摸鱼去的博客,分享前端、uni-app、AI编程相关知识',
// PWA 配置区,重点来了!
pwa: {
base: '/',
scope: '/',
includeAssets: ['favicon.ico', 'logo.png', 'images/**/*'], // 告诉插件,这些静态资源要缓存起来
registerType: 'prompt', // 有更新别偷偷刷新,得问问我(用户)同不同意
injectRegister: 'auto',
// 开发环境专用,关掉烦人的警告
devOptions: {
enabled: true,
suppressWarnings: true, // 开发时警告太多,眼花,先屏蔽
navigateFallback: '/',
type: 'module'
},
// Service Worker 配置,缓存策略的灵魂
workbox: {
globPatterns: ['**/*.{js,css,html,ico,png,jpg,jpeg,gif,svg,woff2}'], // 需要缓存哪些类型的文件
cleanupOutdatedCaches: true, // 老缓存?清理掉!别占地方
clientsClaim: true, // 新的Service Worker来了,立刻接管页面
skipWaiting: true, // 新SW别等了,赶紧干活
maximumFileSizeToCacheInBytes: 10 * 1024 * 1024, // 单个文件最大10MB,再大就不缓存了
// 针对不同资源,用不同缓存策略(这里踩过坑)
runtimeCaching: [
// Google Fonts这类外部字体:缓存优先,存久点(一年),反正不常变
{
urlPattern: /^https:\/\/fonts\.googleapis\.com\/.*/i,
handler: 'CacheFirst',
options: {
cacheName: 'google-fonts-cache',
expiration: {
maxEntries: 10,
maxAgeSeconds: 60 * 60 * 24 * 365
}
}
},
// 图片:也缓存优先,但别存太久(30天),万一我换了图呢?
{
urlPattern: /\.(?:png|jpg|jpeg|svg|gif)$/,
handler: 'CacheFirst',
options: {
cacheName: 'images-cache',
expiration: {
maxEntries: 100,
maxAgeSeconds: 60 * 60 * 24 * 30
}
}
}
// 注意:JS/CSS/HTML Workbox默认会处理,通常用 StaleWhileRevalidate 策略(缓存优先,后台更新)
]
},
// App清单,告诉系统"我是个App!"
manifest: {
name: '不如摸鱼去', // 完整名
short_name: '摸鱼去', // 桌面图标下面显示的短名,太长显示不全
description: '分享前端、uni-app、AI编程相关知识',
theme_color: '#ffffff', // 主题色,影响状态栏、启动画面背景
background_color: '#ffffff', // 启动画面背景色
display: 'standalone', // 独立显示模式(全屏,无浏览器UI)
orientation: 'portrait', // 默认竖屏
scope: '/', // PWA能管哪些页面
start_url: '/', // 点开图标从哪开始
icons: [ // 图标!重中之重!
{
src: '/logo.png',
sizes: '192x192',
type: 'image/png'
},
{
src: '/logo.png',
sizes: '512x512',
type: 'image/png'
},
{
src: '/logo.png',
sizes: '512x512',
type: 'image/png',
purpose: 'any maskable' // 这个重要!告诉系统这图标能被裁剪成各种形状(圆的、方的)
}
]
}
}
}))
看看效果
部署上线后,浏览器打开 blog.wot-ui.cn/ 会发现地址栏旁边会提示安装应用。
安装后将我们的app放到启动台中就可以快捷访问了,断网后也可以访问,很方便。


搞完之后,有啥变化?
说实话,效果比我预期的好:
- 快! 二次访问(尤其是同一设备)快多了,静态资源直接读本地缓存,秒开。在没网的地方(比如电梯里),打开博客,之前看过的文章照样能看,体验不掉线。
- 体验升级: 全屏阅读,没有浏览器边框干扰,沉浸感强不少。
- 方便访问: 可以在桌面、启动台创建快捷方式,方便读者找到我们,不需要记忆网址。
- 服务器压力小点: 缓存命中率高了,请求自然少了点。
总结
给 VitePress 博客加PWA,投入产出比真挺高的。主要就是装个插件、改改配置、准备个图标。过程不算复杂,但带来的体验提升是实打实的。如果你的网站访问速度比较慢,或者期望提高用户的粘性,提供一下 PWA 能力还是很不错的。读到这里还不把「不如摸鱼去」博客添加到桌面吗(偷笑)?
参考资料
- VitePress 官网: vitepress.dev/
- @vite-pwa/vitepress: github.com/vite-pwa/vi...
- PWA的MDN: developer.mozilla.org/zh-CN/docs/...
往期精彩
uni-app vue3 也能使用 Echarts?Wot Starter 是这样做的!
当年偷偷玩小霸王,现在偷偷用 Trae Solo 复刻坦克大战
告别 HBuilderX,拥抱现代化!这个模板让 uni-app 开发体验起飞
Vue3 uni-app 主包 2 MB 危机?1 个插件 10 分钟瘦身
欢迎评论区沟通讨论👇👇