返回

揭秘TouchMove事件SetData优化的秘密,体验丝滑流畅的小球跟随效果

前端

现象

  • 流畅运行环境: 开发工具、IOS平台

  • 卡顿现象: 安卓机下手机预览时交互极其卡顿

  • 原因分析: SetData每秒调用高达50左右

优化方案

  • 优化1:延迟触发SetData

    将SetData调用延迟到特定时间间隔或用户抬起手指时,以减少调用频率。

    const touchMove = (e) => {
        const { touches } = e
        if (touches.length !== 1) return //确保只存在一个手指触摸
        let timer = setTimeout(() => {
            setData({ ballX: touches[0].clientX, ballY: touches[0].clientY })
        }, 100) //延迟100ms触发SetData
    
        return () => clearTimeout(timer) //清除定时器
    }
    
  • 优化2:减少不必要的SetData调用

    在TouchMove事件中,手指的移动位置可能存在微小变化,因此不必要的SetData调用会影响性能。可以使用判断来避免不必要的情况。

    let prevX, prevY //记录上一次触摸位置
    const touchMove = (e) => {
        const { touches } = e
        if (touches.length !== 1) return //确保只存在一个手指触摸
        const touch = touches[0]
        if (prevX === touch.clientX && prevY === touch.clientY) return //判断位置是否变化
        setData({ ballX: touch.clientX, ballY: touch.clientY })
        prevX = touch.clientX
        prevY = touch.clientY
    }
    
  • 优化3:使用CSS实现动画

    在某些情况下,我们可以使用CSS动画来实现小球跟随手指移动的效果,这可以避免SetData调用的性能问题。

    .ball {
        position: absolute;
        left: 0;
        top: 0;
        transform: translate(0, 0);
    }
    
    const touchMove = (e) => {
        const { touches } = e
        if (touches.length !== 1) return //确保只存在一个手指触摸
        const touch = touches[0]
        const ball = document.querySelector('.ball')
        ball.style.transform = `translate(${touch.clientX}px, ${touch.clientY}px)`
    }
    

效果对比

通过优化后,小球跟随手指移动的效果在安卓机上也实现了丝滑流畅的体验,SetData的调用次数也大大减少。以下对比展示了优化前后SetData调用次数的差异:

优化前: 每秒高达50次

优化后: 每秒不到10次

总结

通过优化SetData的使用,我们成功消除了安卓机下的交互卡顿问题,使得小球跟随手指移动的效果变得流畅自然。优化方法包括延迟触发SetData、减少不必要的SetData调用以及使用CSS实现动画。这些优化不仅改善了交互体验,也提高了小程序的性能。

希望本文能帮助您解决在小程序中实现跟随手指移动的效果时遇到的性能问题。