Readest 网页版离线阅读功能完整指南:断网也能畅读电子书
【免费下载链接】readestReadest is a modern, feature-rich ebook reader designed for avid readers offering seamless cross-platform access, powerful tools, and an intuitive interface to elevate your reading experience.项目地址: https://gitcode.com/gh_mirrors/re/readest
Readest 是一款支持 Web、桌面、移动端的现代电子书阅读器,它的网页版内置离线能力:基于 Service Worker 和浏览器本地存储,把读过的页面、书籍文件留在设备上,断网时继续流畅翻页,恢复联网后再自动刷新内容。通勤、飞行、偏远地区出差,任何网络不稳定的读者都会用得上。
断网之后,Readest 网页版还能做什么
离线能力解决的不是"打开网站"这一件事,而是三件具体的事:
- 继续读已经打开的书。网页版把导入的书籍内容存进浏览器的 IndexedDB,翻页渲染时优先读本地副本,而不是每次都从服务器拉文件。地铁里信号断了几分钟,阅读不会白屏等待。
- 书架和阅读进度照常可用。已加载的页面走本地缓存,断网时切换书籍、翻回上一章这类操作基本无感。
- 联网后自动追上进度。Readest 的同步服务(src/services/sync/)会在网络恢复后同步阅读状态,你在离线期间读到的位置,换台设备登录也能接上。
对普通用户来说,体感就是:网络断了,阅读器没"断"。
为什么用 Service Worker + Serwist 实现
离线阅读的关键矛盾是:网页应用默认"不联网就没有内容",但读者要的是"本地有数据就能读"。Readest 的解法分两层:
- Service Worker 拦截请求。它运行在浏览器后台,能截获页面向服务器发起的每次请求,决定"走网络"还是"走缓存"。这是所有 PWA 离线能力的地基。
- 浏览器本地存储持久化数据。书籍文件、元数据存在 IndexedDB 里(见 webAppService.ts 中封装的
indexedDBFileSystem),容量远大于普通 Cookie 缓存,重启浏览器后依然保留。
具体到框架选型,Readest 用Serwist(Workbox 的下一代缓存库)接入 Next.js,而不是手写 Service Worker。原因是 Next.js 项目里构建产物路径由框架生成,手写缓存清单很容易漏资源;Serwist 能在构建时自动生成 precache 清单,页面代码更新后旧缓存也会跟着失效。
这个方案还有一个刻意的取舍:离线能力只在 Web 生产构建中启用。桌面端(Tauri)和移动端本身就是本地应用,书籍文件就在设备上,走 Service Worker 缓存反而多此一举,所以在 next.config.mjs 里用开关直接关掉:
const pwaDisabled = isDev || appPlatform !== 'web'; const withPWA = pwaDisabled ? (config) => config : withSerwistInit({ swSrc: 'src/sw.ts', swDest: 'public/sw.js', cacheOnNavigation: true, reloadOnOnline: true, });拆解要点:
pwaDisabled:开发模式或桌面/移动构建时跳过 Service Worker,避免干扰调试cacheOnNavigation: true:页面导航本身就进缓存,SPA 路由切换离线也能命中reloadOnOnline: true:检测到网络恢复后自动重新加载页面,拿到最新内容
关键落地细节:缓存策略是核心
Service Worker 建好只是骨架,怎么决定哪些请求走网络、哪些走缓存才是离线的成败关键。全部策略集中在 src/sw.ts,核心是三段差异化配置:
runtimeCaching: [ // 核心路由 /library、/reader:网络优先,3 秒超时回退缓存 { matcher: ({ url, request }) => ['/library', '/reader'].some((r) => url.pathname.startsWith(r)) && request.mode === 'navigate', handler: new NetworkFirst({ cacheName: 'client-pages', networkTimeoutSeconds: 3 }), }, // 字体等静态资源:缓存优先,一年有效 { matcher: isFontRequest, handler: new CacheFirst({ cacheName: 'fonts-cache' }) }, ]三种请求,三种待遇,每类都对应一个明确的理由:
| 资源类型 | 策略 | 为什么 |
|---|---|---|
/library、/reader页面 | NetworkFirst,3 秒超时 | 页面要尽量新鲜,但网络慢时不能卡死,超时立刻读缓存 |
| 字体等静态资源 | CacheFirst,有效期 2 年 | 内容极少变化,优先本地读取,首屏速度最快 |
| 其他外部资源 | NetworkFirst | 通用兜底,与页面保持一致的取舍 |
另外两个值得注意的细节:
- 兜底离线页。所有
document类型请求(即用户直接访问的页面)失败时,Serwist 会回退到/offline路由,由 离线页面 展示"你已断网"的提示,而不是浏览器默认的无法访问页面。 - 缓存不会无限膨胀。每类缓存都挂了
ExpirationPlugin,限定条目数和有效期(页面缓存 128 条、字体 200 条、外部资源 512 条),超出自动淘汰,避免把用户浏览器磁盘塞满。
普通用户怎么用好离线阅读
- 先联网"喂"一遍缓存。离线能力是"读过的才留得住"。想离线读某本书,先在网络好的时候打开它、把前后章节翻一遍,缓存命中之后断网才丝滑。
- 核心场景优先选 Web 版。离线 Service Worker 只在网页构建中启用,如果你主要在网络不稳定的环境阅读,用浏览器版 Readest 比装个会联网同步的桌面版更稳。
- 断网后别急着刷新页面。
reloadOnOnline会在网络恢复时自动处理,期间手动刷新反而可能触发一次失败请求;等页面自己恢复正常即可。 - 注意浏览器存储清理。书籍内容存在 IndexedDB 里,手动"清除网站数据"会连带删掉离线缓存,下次需要重新联网加载。
小结
Readest 用 Service Worker + Serwist + IndexedDB 的组合,把网页阅读器从"依赖网络"变成"本地优先、联网刷新":书籍文件落本地存储,请求层面按资源类型分配缓存策略,离线兜底页保证断网时体验不崩。想深入实现细节,可以看 架构文档 中 "Service worker and offline" 一节和 sw.ts 源码。
【免费下载链接】readestReadest is a modern, feature-rich ebook reader designed for avid readers offering seamless cross-platform access, powerful tools, and an intuitive interface to elevate your reading experience.项目地址: https://gitcode.com/gh_mirrors/re/readest
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考