vue使用百度地图,每分钟渲染一次标注点(800个),两个小时左右会导致浏览器崩溃,如何解决。
附:这个是个大屏可视化地图,页面请求标注点数据由间隔定时器每分钟请求一次
分层加载,按需释放。
您可以尝试以下方法来解决该问题:
使用Chrome DevTools检查内存泄漏:请使用Chrome DevTools观察内存使用情况,以确定是否存在内存泄漏。
减少标注点数量:每次渲染的标注点数量越少,内存的使用就越少。可以考虑通过分批加载标注点,以避免一次性渲染所有标注点。
使用Web Workers:Web Workers是一种在后台运行的JavaScript线程,它可以提高应用程序的性能。您可以将百度地图的渲染工作放到Web Worker中,以避免阻塞主线程。
使用其他地图库:如果仍然无法解决问题,您可以考虑使用其他地图库,例如Leaflet或Google Maps。
请注意,以上建议仅供参考,具体方案取决于您的需求和限制。
百度地图可能会导致内存泄漏,从而导致浏览器崩溃。如果您遇到了这种情况,可以尝试以下几种方法来解决:
降低每分钟渲染标注点的数量,并定期删除不再使用的标注点。
使用Chrome DevTools检查内存使用情况,并尝试找到导致内存泄漏的代码。
使用更高效的图形库,例如Three.js,以减少内存使用。
在百度地图 API 中设置回收机制,以释放不再使用的内存。
希望这些方法能够帮助您解决问题。
渲染的同时 把用不到的再销毁掉从而来节省内存占用
1、使用回收机制,将不需使用的对象销毁。
2、试试用对象聚类,将点对象聚合到一起, 避免一次性加载太多数据而卡死。
那确实有可能 卡顿崩溃 。近10万个呢,建议 想想其它方案,不需要的 就 移出 。或者分层级 加载
解决问题换个思路
一、首先明确:技术绝对不是万能的,必要的时候请你的产品经理来背锅!
二、技术上:
1)使用缓存,浏览器缓存度娘下有n多!
2)1分钟请求一次后台,查看请求后台的时间!是不是占有了1分钟的大部分?
3)请后台去重:难道每分钟请求后台的数据是完全不一样的?如果是一样的,你就不要再渲染了,具体要求后台标识返回的数据与前一次请求是否一致,然后你依据此标识决定是否再渲染!
希望可以打开你的脑洞,谢谢
“该回答引用ChatGPT”
可以参考下面的解决方案,如果觉得还可以,还请点击 采纳,感谢支持!
如果该应用每分钟重新渲染 800 个标注点,会造成浏览器内存消耗过大,导致浏览器崩溃。有以下一些解决方法:
1、减少渲染次数:增加渲染标注点的时间间隔,比如每 5 分钟或更长时间渲染一次,减少频繁渲染的次数。
2、增加懒加载:只在用户可视范围内的标注点渲染,当用户移动地图时再加载范围内的标注点。
3、优化代码:使用 Vue 的虚拟 DOM 功能优化标注点的渲染性能。
以下是 Vue 中使用百度地图的代码示例,实现了根据解决方案的思路进行的相应修改:
<template>
<div id="map" ref="mapContainer"></div>
</template>
<script>
import BMap from 'BMap'
export default {
data () {
return {
markers: [],
timer: null
}
},
mounted () {
this.initMap()
this.loadMarkers()
},
methods: {
initMap () {
let map = new BMap.Map(this.$refs.mapContainer)
map.centerAndZoom(new BMap.Point(116.404, 39.915), 11)
map.enableScrollWheelZoom(true)
},
loadMarkers () {
this.timer = setInterval(() => {
this.getMarkersData().then(markersData => {
this.clearMarkers()
markersData.forEach(markerData => {
let marker = new BMap.Marker(new BMap.Point(markerData.lng, markerData.lat))
this.markers.push(marker)
marker.addEventListener('click', () => {
this.showInfoWindow(markerData)
})
})
this.markers.forEach(marker => {
marker.setMap(this.map)
})
})
}, 60000)
},
getMarkersData () {
// 模拟从后端获取标注点数据的过程
return new Promise((resolve, reject) => {
setTimeout(() => {
let markersData = []
for (let i = 0; i < 800; i++) {
markersData.push({
lng: 116.404 + Math.random() * 0.1,
lat: 39.915 + Math.random() * 0.1
})
}
resolve(markersData)
}, 1000)
})
},
clearMarkers () {
this.markers.forEach(marker => {
marker.setMap(null)
})
this.markers = []
},
showInfoWindow (markerData) {
let infoWindow = new BMap.InfoWindow(`标注点信息:${markerData.lng}, ${markerData.lat}`)
this.map.openInfoWindow(infoWindow, new BMap.Point(markerData.lng, markerData.lat))
}
},
beforeDestroy () {
clearInterval(this.timer)
}
}
</script>
<style>
#map {
width: 100%;
height: 100%;
}
</style>
最简单的方法,加电脑配置,内存一直增长的原因,如果确认不是内存泄露的话,那就是浏览器处理不过来,换更好的cpu就能解决
还有一个解决方法,要求的是地图上保持800个点,你应该是做的简单粗暴的写了一个一分钟的定时器,到时间删除所有,一次性画800个点出来,为什么不试一试将一次性的任务分解呢,比如每隔100ms删除一个旧的点,创建一个新的点出来,这样cpu工作的时候永远处理的只有删除一个点,创建一个点的工作,不比一次性删除800,再马上画800出来科学多了?
地图上的点本身应该是随时变化的,你应该和后端说,每隔一段时间给你一个新点的位置,不要一次性操作大量数据,应该尝试将一分钟拆解,每次只处理一两条数据
你应该对地图上的所有点进行id分配,后台不断的给你发送点的数据,形成一个数据传输流,不要一次性直接请求800条数据,
刷新页面,打开任务管理器,看看浏览器的内存占用是否一直在增加,是的话就证明实例还是没被销毁的,重新再看看有没有销毁成功
还有不要在data里面new
map.destroy()
map = null
题主,这个问题我来替你解决,若有帮助,还望采纳,点击回答右侧采纳即可。
很有可能是使用百度地图导致BMapGL内存泄漏 Out of Memory。
建议你尝试下:
1.对象不定义在data中:
initMap(){
map = new BMapGL.Map("allMap") // 创建Map实例
}
2.在vue中组件使用 v-if 指令会从dom中移除
beforeDestroy() {
map.destroy()
map = null
},