拖拽组件频繁计算坐标,如何用缓存优化性能?

开发者甜雅 阅读 62

我在做一个可拖拽的卡片组件,每次鼠标移动都会触发坐标计算,发现控制台提示性能警告。尝试用 useMemo 缓存计算结果,但好像没起作用,还是在频繁重新计算:


const calculatePosition = (e) => ({
  x: e.clientX - offsetLeft,
  y: e.clientY - offsetTop
});

const cachedPos = useMemo(() => calculatePosition(event), [event]);

依赖项写了 event 对象,但每次拖动 event 都是新引用导致缓存失效。如果不用依赖项又怕数据不一致,有什么更好的缓存策略吗?

我来解答 赞 1 收藏
二维码
手机扫码查看
1 条解答
Mr-德丽
Mr-德丽 Lv1
这个问题的核心在于 event 对象每次触发都是新的引用,导致 useMemo 依赖项变化频繁,缓存形同虚设。性能上我们需要换个思路,不要直接依赖 event 对象。

可以考虑用一个局部变量来存储上一次计算的结果,再通过 requestAnimationFrame 来限制高频触发。代码大致像这样:

let lastPosition = null;

const onMouseMove = (e) => {
if (!lastPosition) {
lastPosition = calculatePosition(e);
} else {
lastPosition.x += e.movementX;
lastPosition.y += e.movementY;
}

// 使用缓存的坐标
updatePosition(lastPosition);
};

const throttledMouseMove = (e) => {
requestAnimationFrame(() => onMouseMove(e));
};

element.addEventListener('mousemove', throttledMouseMove);


这里用了 movementX 和 movementY,它们表示鼠标移动的偏移量,比直接计算绝对坐标性能更好。requestAnimationFrame 能有效降低计算频率,避免每帧都做计算。

另外记得在 mouseup 的时候重置 lastPosition,不然下次拖拽会从上次结束的位置继续。这种方案既能保证数据准确,又能大幅提升性能,特别是在低性能设备上效果更明显。
点赞 3
2026-02-16 01:00