📖 小说网站的预导航实战:link 预加载 + fetch + 前进后退全支持

一、前言

在小说网站里,点击「下一章」通常需要等待网络请求,体验不佳。为此,很多网站会采用 预导航 技术:提前获取下一章内容,点击时立即展示。

今天我们从 3 个角度展开:

  1. <link> 预加载(最简单,零 JS 方案)
  2. JS fetch 预加载(更灵活,可控)
  3. fetch + History API(支持前进/后退按钮,最佳体验)

HTML5 提供了原生预取机制,写在 <head> 里:

ini 复制代码
<link rel="prefetch" href="/chapter2.html" as="document">
  • prefetch:浏览器空闲时预加载资源(下一章 HTML / 图片等)。
  • prerender:甚至会在后台完整渲染页面,点击时几乎零延迟,但兼容性较差。

👉 优点:

  • 实现简单,一行代码搞定
  • 浏览器帮你做缓存

👉 缺点:

  • 无法控制何时加载(由浏览器决定)
  • 不会自动和前进/后退联动

适用场景:简单优化,比如普通博客或小说目录页。


三、方式二:JS fetch 主动预加载

如果我们想要更精确的控制,可以用 fetch:

ini 复制代码
let nextUrl = "/chapter2.html";
let cache = null;

// 页面加载时主动预取下一章
fetch(nextUrl)
  .then(res => res.text())
  .then(html => cache = html);

document.getElementById("next").addEventListener("click", (e) => {
  e.preventDefault();
  if (cache) {
    document.getElementById("content").innerHTML = cache;
  } else {
    location.href = nextUrl;
  }
});

👉 优点:

  • 精确可控,随时预取
  • 可以缓存多章内容

👉 缺点:

  • 前进/后退按钮失效(因为没有写入历史栈)

四、方式三:fetch + History API(推荐🔥)

要让「前进/后退」也能秒开,就必须结合 pushState + popstate。

ini 复制代码
const contentEl = document.getElementById("content");
let preloadCache = {};

// 初始化:写入当前页面内容
history.replaceState({ html: contentEl.innerHTML }, "", location.href);

// 预取下一章
function preload(url) {
  if (preloadCache[url]) return;
  fetch(url).then(res => res.text()).then(html => {
    const doc = new DOMParser().parseFromString(html, "text/html");
    const nextContent = doc.querySelector("#content").innerHTML;
    preloadCache[url] = nextContent;
    // 让历史记录也存上
    history.replaceState({ ...history.state, [url]: nextContent }, "", location.href);
  });
}

// 点击切换
document.querySelectorAll("a.nav").forEach(link => {
  link.addEventListener("click", async (e) => {
    e.preventDefault();
    const url = link.href;

    let newContent = preloadCache[url];
    if (!newContent) {
      const res = await fetch(url);
      const html = await res.text();
      const doc = new DOMParser().parseFromString(html, "text/html");
      newContent = doc.querySelector("#content").innerHTML;
    }

    contentEl.innerHTML = newContent;
    history.pushState({ html: newContent }, "", url);

    // 顺便预取下一章
    const next = link.nextElementSibling?.href;
    if (next) preload(next);
  });
});

// 前进/后退
window.addEventListener("popstate", (e) => {
  if (e.state && e.state.html) {
    contentEl.innerHTML = e.state.html;
  } else {
    location.reload();
  }
});

👉 优点:

  • 点击秒开
  • 前进/后退秒开
  • 可扩展预取策略

👉 缺点:

  • 需要额外 JS 逻辑
  • 刷新时依然需要服务端响应

五、对比总结

方案 代码复杂度 可控性 前进/后退支持 适用场景
<link rel="prefetch"> 极低 低 ❌ 简单优化
JS fetch 中 高 ❌ 定制预取策略
fetch + History API 高 高 ✅ 小说网站 / 阅读器

六、进一步优化思路

  • 条件预取 :根据 navigator.connection.saveData 判断用户是否需要省流量。
  • 多章节预取:提前缓存后两章,点击前进时也能秒开。
  • Service Worker:离线缓存,断网也能继续阅读。
  • 无限滚动:直接拼接章节,去掉翻页操作。

七、总结

  • 最简单的方式 :<link rel="prefetch">,无需 JS。
  • 更灵活的方式 :JS fetch,可缓存下一章。
  • 最佳体验的方式 :fetch + History API,前进/后退全支持。

👉 对于小说网站,推荐 第三种方案,配合预加载和缓存,可以做到媲美本地阅读器的流畅体验。

相关推荐
沙漠之主11 小时前
C++编程教学设计资料:从入门到实战的完整课程方案
java·前端·c++
hasty11 小时前
不上传新包,也能改变用户拿到的版本:npm dist-tag 的 OIDC 权限治理
前端·npm·node.js
Csvn12 小时前
diff 算法(虚拟 DOM Reconciliation)
前端
前端snow13 小时前
ai agent --- 文件存储
前端
Frag0ut13 小时前
Chrome四大版本获取及共存指南:Stable/Beta/Dev/Canary
前端·chrome·浏览器·dev·beta·canary·共存版
IT_陈寒14 小时前
SpringBoot自动配置坑了我一把,原来是这样绕过去的
前端·人工智能·后端
广州华水科技14 小时前
单北斗GNSS变形监测在大坝安全监测中的应用与优势
前端
zeng不错15 小时前
B站 173 个投稿活动看到眼瞎?我写了个扩展,主打一个精准打击
前端
Latchh15 小时前
前端导出的JPEG红字发糊,质量要拉到100才清楚
前端·图像处理·人工智能·计算机视觉
默_笙15 小时前
🚦 请三个 AI 考官给 RAG 打分:量化评估实战(下)
前端·javascript