如何解决React开发中谷歌地图联动拖拽出现的延迟卡顿问题
问题根因
你当前实现的延迟核心来源于两个问题:
- 所有同步操作都走了
setState流程,React的setState本身是异步批量更新的,还要触发组件重渲染流程,额外增加了大量开销,自然会产生明显滞后 - 绑定了大量重复的地图事件,
drag/dragstart/mousemove/idle/center_changed都会重复修改同一个center状态,频繁触发更新逻辑,进一步放大了延迟问题
优化方案
1. 跳过React状态层,直接操作地图实例
不要把地图中心、缩放等级存在state里,也不要通过state同步两个地图。直接把两个地图的实例挂载在组件实例上(比如this.map1、this.map2),在事件回调里直接调用另一个地图的原生方法更新位置,完全绕开React的更新流程,性能会提升数倍。
2. 删除冗余事件监听
仅保留center_changed和zoom_changed两个必要事件即可,其他事件均为重复触发,没有必要保留。
3. 增加联动锁避免循环触发
同步地图时增加一个临时标志位,防止同步B地图的时候触发B的事件反过来同步A,造成无效的循环调用。
优化后代码示例
// 组件内先声明一个同步锁 isSyncing = false initMap = (mapProps, map, mapType) => { // mapType用来标识当前是第几个地图,初始化时分别传'map1'/'map2'即可 const { google } = mapProps; // 直接把地图实例挂载到组件实例,不用存在state里 this[mapType] = map; if (this.state.compare) { google.maps.event.addListener(map, 'center_changed', () => { // 正在同步过程中不触发反向更新,避免循环 if (this.isSyncing) return this.isSyncing = true const targetMap = mapType === 'map1' ? this.map2 : this.map1 // 直接调用目标地图的原生方法更新中心 targetMap?.setCenter(map.getCenter()) this.isSyncing = false }); google.maps.event.addListener(map, 'zoom_changed', () => { if (this.isSyncing) return this.isSyncing = true const targetMap = mapType === 'map1' ? this.map2 : this.map1 targetMap?.setZoom(map.getZoom()) this.isSyncing = false }); } }
内容的提问来源于stack exchange,提问作者Suraj Bhalerao
相关产品推荐
相关产品推荐

