移动端复杂动画Hook优化

Arthur228 +0/-0 0 0 正常 2025-12-24T07:01:19 React Hooks · 动画优化 · 移动端性能

移动端复杂动画Hook优化踩坑记录

最近在重构一个移动端电商应用的购物车动画组件时,踩了一个大坑。最初我们直接在组件中使用了多个useEffect来处理动画状态,结果导致性能严重下滑。

问题重现

const CartAnimation = ({ items }) => {
  const [isVisible, setIsVisible] = useState(false);
  const [animatePosition, setAnimatePosition] = useState({ x: 0, y: 0 });
  const [scale, setScale] = useState(1);
  
  useEffect(() => {
    if (items.length > 0) {
      setIsVisible(true);
      // 复杂的动画逻辑
      animatePosition.x = calculateX(items);
      animatePosition.y = calculateY(items);
      setScale(1.2);
      
      setTimeout(() => {
        setScale(1);
      }, 300);
    }
  }, [items]);
  
  useEffect(() => {
    // 另一个动画监听器
    if (isVisible) {
      // 复杂的DOM操作
    }
  }, [isVisible]);
};

优化方案

最终我们重构为一个自定义Hook,将所有动画逻辑集中管理:

const useCartAnimation = (items) => {
  const [animationState, setAnimationState] = useState({
    isVisible: false,
    position: { x: 0, y: 0 },
    scale: 1
  });
  
  const animate = useCallback(() => {
    if (items.length > 0) {
      setAnimationState(prev => ({
        ...prev,
        isVisible: true,
        position: calculatePosition(items),
        scale: 1.2
      }));
      
      setTimeout(() => {
        setAnimationState(prev => ({
          ...prev,
          scale: 1
        }));
      }, 300);
    }
  }, [items]);
  
  return { animationState, animate };
};

// 使用时
const CartComponent = ({ items }) => {
  const { animationState, animate } = useCartAnimation(items);
  
  useEffect(() => {
    animate();
  }, [items, animate]);
  
  return (
    <div style={{
      transform: `translate(${animationState.position.x}px, ${animationState.position.y}px) scale(${animationState.scale})`
    }}>
      {/* 动画内容 */}
    </div>
  );
};

关键优化点

  1. 使用useCallback避免重复创建函数
  2. 合并多个useEffect为单个状态管理
  3. 将动画逻辑提取到独立Hook中复用
  4. 避免在渲染过程中执行复杂计算

这次重构后,移动端动画流畅度提升约40%,内存占用减少30%。

推广
广告位招租

讨论

0/2000