前言

网站是用 Astro 搭的,之前一直没太注意页面切换的细节。今天逛别人的网站,发现人家切换页面是无缝的,回来就让 ai 帮我用 astro 原生的 pjax 也整了一个。

原理

Astro 自带这个功能,叫 ClientRouter,说白了就是官方版 pjax。

原理不难:点链接的时候它不让你真的跳页,而是偷偷把新页面要过来,把页面内容整个一换,顺便播个小动画。看起来就是无缝切换了。

加到布局里就能用,一分钟搞定。但真用起来一堆毛病,都是”换页”闹的。

遇到的问题

Astro 的脚本整个网站只跑一次,第一次进站就全跑完了,之后不管换到哪个页面它都不会再动。可评论、浏览量、评论数、摘要、代码块、侧边栏的最新评论,这些都是进了页面之后由代码现场去请求、现场填进去的。换页之后代码不跑了,这些活就没人干:评论区一直挂着”评论已加载,请刷新后查看…”,顶部信息全是空的,代码块也出不来,侧边栏的最新评论切几次就丢。

表情面板样式乱掉,是同一件事的另一面:评论组件的样式是它运行时自己往 head 里塞的,换页时 head 整个被换掉,塞进去的样式也就跟着丢了。

治法不复杂:

  • 文章页专属的脚本(评论、AI 摘要这些),加个 data-astro-rerun,逼它每次进页面都重新跑;
  • 全站都有的组件挂到 page-load 事件上,每次换页重新初始化一遍;
  • 运行时注入的样式,干脆提取出来跟着页面一起打包,不指望运行时再塞。

顺带还有个小坑:脚本重跑之后,全局的滚动监听这类东西会越绑越多,页面越用越卡。绑过一次要记个号,别重复绑。

这些收拾完之后,整站点起来就顺滑多了。