754 字
4 分钟
Swup 与持久化外壳:无刷新导航的代价
第一次体验 Swup 时,最直观的感受是「顺」。点击链接,页面内容淡入替换,导航栏和侧栏原地不动,没有整页白屏。
但真正开始维护时,我发现无刷新导航并不是免费的。它改变的不只是体验,还有代码的生命周期。
外壳与内容的分工
flowchart TB Shell[持久化外壳:导航、侧栏、页脚] Container[#swup-container:可替换页面内容] Shell --> Container Container --> PageA[页面 A] Container --> PageB[页面 B]
外壳只渲染一次,页面内容在每次导航时被替换。这样避免了重复渲染,但也带来一个关键问题:外壳里的代码不会因为路由变化而重新执行。
生命周期比事件名更重要
如果一段逻辑依赖当前页面的数据,它就不能只在首次加载时运行。常见做法是监听 Swup 的生命周期:
document.addEventListener("astro:page-load", () => { initPageScopedFeatures();});我在处理筛选器、代码块增强和图表初始化时,都同时验证了这两种路径。测试时不能只刷新页面,还要从其他页面点进来。
事件委托比重新绑定更稳
页面内容被替换后,之前绑定在旧 DOM 上的事件监听器也会一起消失。与其每次导航后重新绑定,不如把监听器放在持久化的父节点上,用事件委托处理:
document.addEventListener("click", (event) => { const target = event.target as HTMLElement; const button = target.closest("[data-copy]"); if (!button) return; copyToClipboard(button.dataset.copy ?? "");});体验与复杂度的交换
| 方面 | 普通整页导航 | Swup 无刷新导航 |
|---|---|---|
| 首屏切换 | 有白屏 | 过渡自然 |
| 状态保持 | 全部重置 | 外壳状态保留 |
| 代码复杂度 | 低 | 需要生命周期管理 |
| 调试难度 | 低 | 需要同时验证两条路径 |
无刷新导航买到的是体验,付出的是对生命周期的理解。
小结
Swup 不是「装上就变好」的插件。它要求开发者明确区分「一次性外壳」和「可替换页面」,并在正确的生命周期里做正确的事。
理解这一点之后,无刷新导航才真正成为体验优化,而不是隐藏的 bug 来源。
本站技术手记
连载中Swup 与持久化外壳:无刷新导航的代价
https://www.ycera.cn/posts/swup-navigation/分享文章
生成精美分享图或复制链接,与更多人分享本文。
继续阅读
换条路线
从其他文章中稳定抽取
最后更新于 ,距今已过 7 天
部分内容可能已过时