全站动效记录 03:页面切换不做加载,二级页面只做本地入场
博客、摄影、书法和关于页面需要进入感,但不需要全局加载遮罩。最后用本地 PageEnter 处理各页面板块。
首页动效正常后,二级页面的问题就明显了:点击博客、摄影、书法、关于,页面内容会直接闪出来。
但我不想重新做全局 route transition。之前的卡顿和“两次刷新感”,很大一部分就来自全局切换层。页面切换应该快,内容可以轻轻出现。
先关掉全局视觉切换
PageTransition.tsx 现在只保留结构:
export default function PageTransition({ children }: { children: ReactNode }) {
return <div className="min-h-[inherit]">{children}</div>;
}它不再引入 Framer Motion,也没有 AnimatePresence、initial、exit。
RouteLoading.tsx 也不显示视觉 loading。它只保留给读屏器的提示:
<div className="sr-only" role="status" aria-live="polite">
{loadingLabel}
</div>这样做的原因很简单:站点是静态内容为主,页面切换应该立刻响应。给每次切换都加一层加载动画,反而会显得卡。
本地入场组件
二级页面需要的不是 loader,而是局部入场。所以加了 PageEnter.tsx:
<PageEnterGroup>
<PageEnterItem>{children}</PageEnterItem>
</PageEnterGroup>PageEnterGroup 只负责轻微 stagger:
staggerChildren: reduceMotion ? 0 : 0.06;PageEnterItem 负责单个板块:
hidden: { opacity: 0, y: 18, filter: "blur(4px)" }
visible: { opacity: 1, y: 0, filter: "blur(0px)" }时间控制在 0.4s 左右。它能让页面有进入感,但不会让用户等。
覆盖哪些页面
这次没有把所有卡片一个个做入场。列表逐项慢慢出现会很拖。实际接入范围是页面级板块:
- 博客:页头、筛选栏、文章列表区。
- 摄影:标题说明、照片墙。
- 书法:标题、筛选和作品区。
- 关于:左侧资料、中间介绍、右侧简历和联系。
博客筛选栏有一个小细节。它原本是 sticky。如果把 sticky 放在里面的 aside 上,外层 motion wrapper 会影响布局。最后把 sticky 类放到 PageEnterItem 上,让筛选栏仍然能在桌面端跟随。
为什么不把二级页也交给首页状态
首页有 HomeEntranceProvider,但二级页面不应该依赖首页首访动画。它们只需要进入页面时做一次短动效。
所以 PageEnter 不看首页 ready 状态,也不看 pathname。它只是页面自己的本地动画。这样边界比较干净:
- 首页入口只管首页。
- 全局 route loading 不做视觉层。
- 二级页面自己负责板块进入。
用测试防止退回去
这次还改了 motion-boundaries.test.ts。测试里同时检查两件事:
PageTransition和RouteLoading仍然没有视觉动画。- 博客、摄影、书法、关于都使用
PageEnter。
这类测试不是为了测动画好不好看,而是为了守住边界。以后如果又把全局加载层接回来,测试会先提醒。
小结
页面切换要快,页面内容可以柔和出现。
把全局动画拿掉,再给页面本地板块加短入场,解决的是同一个问题:不要让动效挡路。它应该让内容更顺,不是让用户多等一遍。

