使用AnimatePresence切换路由时出现延迟问题求助
解决AnimatePresence路由切换卡顿问题
针对重型组件导致AnimatePresence路由切换延迟的问题,可通过以下几种方案优化:
1. 对重型组件实现懒加载 + 过渡占位
将重型组件(比如ProjectsSection)改为懒加载,避免初始时一次性加载所有组件,同时配合Suspense在组件加载期间显示过渡占位,降低路由切换时的性能开销。
修改路由组件的导入方式:
// 替换原有的直接导入 const ProjectsSection = React.lazy(() => import("../Projects/Projects")); const Home = React.lazy(() => import("../Home/Home")); const About = React.lazy(() => import("../About/About"));
在路由元素外层包裹Suspense并添加加载占位:
<Route path="projects" element={ <PaddingHandle> <React.Suspense fallback={<div>加载中...</div>}> <motion.div key="projects" initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} > <ProjectsSection /> </motion.div> </React.Suspense> </PaddingHandle> } />
2. 调整AnimatePresence的渲染模式
将AnimatePresence的mode从"sync"改为"wait",让旧组件的退出动画完全结束后再卸载并渲染新组件,避免新旧重型组件同时渲染导致的性能瓶颈:
<AnimatePresence mode="wait"> {/* 路由内容 */} </AnimatePresence>
3. 优化重型组件的渲染性能
- 用
React.memo包裹重型组件,减少不必要的重渲染:
// 在ProjectsSection组件文件中 export default React.memo(ProjectsSection);
- 拆分重型组件为更小的子组件,仅渲染当前可见部分(比如用虚拟列表处理长列表)
- 使用
useMemo/useCallback缓存组件内的计算结果和回调函数,避免重复计算
4. 移除无效动画减少性能消耗
你的Transition组件中,多个motion.div设置了duration: 0的动画,这类动画无视觉效果但会触发Framer Motion的计算,浪费性能,建议直接移除:
// 修改后的Transition组件 const Transition = ({ children }) => { return ( <> {children} <motion.div className="slide-out" initial={{ scaleY: 1 }} animate={{ scaleY: 0 }} exit={{ scaleY: 0 }} transition={{ duration: 0.3, ease: [0.22, 1, 0.36, 1] }} ></motion.div> </> ); };
5. 修正路由key的绑定方式
确保AnimatePresence能正确识别路由变化,将key直接绑定到location对象,避免路径参数变化时无法触发过渡:
<AnimatePresence mode="wait"> <Routes key={location.key}> {/* 路由配置 */} </Routes> </AnimatePresence>
内容的提问来源于stack exchange,提问作者Mina Melad
相关产品推荐
相关产品推荐

