SvelteKit SSR环境下Svelte-Motion初始动画异常问题排查
解决SvelteKit SSR项目中Motion动画部署后闪烁问题
问题原因
SSR环境下,服务端会直接渲染出元素的最终样式(服务端不执行动画逻辑),客户端hydrate阶段,Motion组件会先将元素切换到initial定义的初始状态,再执行动画过渡到animate目标状态,从而出现「初始可见→消失→动画执行」的闪烁现象。
解决方案
方法1:强制服务端渲染初始状态
直接给Motion包裹的元素添加与initial参数匹配的内联样式,让服务端渲染出的元素一开始就是动画的初始状态,客户端hydrate后Motion会直接执行过渡动画,避免状态突变。
修改后的代码示例:
<div class="grid lg:grid-cols-2 justify-between items-center py-[6rem] max-w-[1200px] m-auto"> <Motion initial={{ opacity: 0, x: 100 }} animate={{ opacity: 1, x: 0 }} transition={{delay: .25}} let:motion> <img use:motion style="opacity: 0; transform: translateX(100px);" class="p-5 m-auto hover:scale-[105%]" src="/images/home-responsive-devices.jpeg" alt="Homepage on different devices"/> </Motion> <Motion initial={{opacity: 0, y: 20}} animate={{opacity: 1, y: 0}} transition={{delay: .5}} let:motion> <div use:motion style="opacity: 0; transform: translateY(20px);" class="flex flex-col w-full"> <p class="leading-8 px-10 py-6 text-justify"><span class="font-semibold">TEST</span> test</p> <a class="m-auto" href="/contact"><button class="self-center mt-10 btn btn-primary btn-outline">Learn More</button></a> </div> </Motion> </div>
方法2:结合SvelteKit环境变量控制初始样式
利用SvelteKit提供的browser环境变量,仅在服务端渲染时添加初始状态样式,客户端则由Motion接管动画逻辑:
<script> import { browser } from '$app/environment'; </script> <div class="grid lg:grid-cols-2 justify-between items-center py-[6rem] max-w-[1200px] m-auto"> <Motion initial={{ opacity: 0, x: 100 }} animate={{ opacity: 1, x: 0 }} transition={{delay: .25}} let:motion> <img use:motion style={!browser ? 'opacity: 0; transform: translateX(100px);' : ''} class="p-5 m-auto hover:scale-[105%]" src="/images/home-responsive-devices.jpeg" alt="Homepage on different devices"/> </Motion> <Motion initial={{opacity: 0, y: 20}} animate={{opacity: 1, y: 0}} transition={{delay: .5}} let:motion> <div use:motion style={!browser ? 'opacity: 0; transform: translateY(20px);' : ''} class="flex flex-col w-full"> <p class="leading-8 px-10 py-6 text-justify"><span class="font-semibold">TEST</span> test</p> <a class="m-auto" href="/contact"><button class="self-center mt-10 btn btn-primary btn-outline">Learn More</button></a> </div> </Motion> </div>
额外建议
- 确保使用最新版本的
svelte-motion,旧版本可能存在SSR兼容缺陷。 - 若使用Tailwind CSS,也可以通过
class:hidden结合browser变量实现初始隐藏,但需注意动画过渡的兼容性。
内容的提问来源于stack exchange,提问作者Joel Hager
相关产品推荐
相关产品推荐

