我最近开发了一个 html5 移动应用程序。该应用程序是一个页面,其中导航哈希更改事件替换了整个 DOM。该应用程序的一个部分是使用 API v3 的 Google 地图。在从 DOM 中删除地图 div 之前,我想删除所有事件处理程序/侦听器并释放尽可能多的内存,因为用户可能不会再次返回该部分。
销毁地图实例的最佳方法是什么?
我最近开发了一个 html5 移动应用程序。该应用程序是一个页面,其中导航哈希更改事件替换了整个 DOM。该应用程序的一个部分是使用 API v3 的 Google 地图。在从 DOM 中删除地图 div 之前,我想删除所有事件处理程序/侦听器并释放尽可能多的内存,因为用户可能不会再次返回该部分。
销毁地图实例的最佳方法是什么?
我在这个问题上添加了第二个答案,因为我不想删除我们通过对我之前的答案的后续评论的来回。
但我最近遇到了一些直接解决您的问题的信息,所以我想分享一下。我不知道您是否意识到这一点,但在2012 年 5 月 9 日的Google Maps API 办公时间视频中,来自 Google 的 Chris Broadfoot 和 Luke Mahe 讨论了来自 stackoverflow 的这个问题。如果您将视频播放时间设置为 12:50,他们将在该部分讨论您的问题。
本质上,他们承认这是一个错误,但还补充说他们并不真正支持涉及创建/销毁连续地图实例的用例。他们强烈建议创建地图的单个实例并在任何此类场景中重复使用它。他们还谈到将地图设置为 null,并明确删除事件侦听器。您表达了对事件侦听器的担忧,我认为只需将地图设置为 null 就足够了,但看起来您的担忧是有效的,因为它们特别提到了事件侦听器。他们还建议完全删除保存地图的 DIV。
无论如何,只是想传递这个并确保它包含在stackoverflow讨论中,并希望它可以帮助您和其他人 -
在官方的回答是你不知道。单页应用程序中的地图实例应该被重用,而不是销毁然后重新创建。
对于某些单页应用程序,这可能意味着重新构建解决方案,这样一旦创建了地图,它就可以隐藏或与 DOM 断开连接,但它永远不会被破坏/重新创建。
由于显然您无法真正销毁地图实例,因此可以通过以下方式减少此问题
正在保留一个地图实例池。该池会跟踪正在使用的实例,当它请求一个新实例时,它会检查任何可用的地图实例是否空闲:如果是,它将返回一个现有的实例,如果不是,它将创建一个新地图实例并返回它,将其添加到池中。这样,您的最大实例数将等于您在屏幕上同时显示的最大地图数。我正在使用此代码(它需要 jQuery):
var mapInstancesPool = {
pool: [],
used: 0,
getInstance: function(options){
if(mapInstancesPool.used >= mapInstancesPool.pool.length){
mapInstancesPool.used++;
mapInstancesPool.pool.push (mapInstancesPool.createNewInstance(options));
} else {
mapInstancesPool.used++;
}
return mapInstancesPool.pool[mapInstancesPool.used-1];
},
reset: function(){
mapInstancesPool.used = 0;
},
createNewInstance: function(options){
var div = $("<div></div>").addClass("myDivClassHereForStyling");
var map = new google.maps.Map(div[0], options);
return {
map: map,
div: div
}
}
}
您将起始地图选项传递给它(根据 google.maps.Map 构造函数的第二个参数),它返回地图实例(您可以在其上调用与 google.maps.Map 相关的函数)和容器,其中您可以使用“myDivClassHereForStyling”类来设置样式,并且可以动态地附加到 DOM。如果需要重置系统,可以使用mapInstancesPool.reset()。它将计数器重置为 0,同时保留池中的所有现有实例以供重用。在我的应用程序中,我需要一次删除所有地图并创建一组新地图,因此没有回收特定地图实例的功能:您的里程可能会有所不同。为了从屏幕上移除地图,我使用了 jQuery 的 detach,它不会破坏地图的容器。
通过使用该系统,并使用
google.maps.event.clearInstanceListeners(window);
google.maps.event.clearInstanceListeners(document);
和跑步
google.maps.event.clearInstanceListeners(divReference[0]);
divReference.detach()
(其中 divReference 是从实例池返回的 div 的 jQuery 对象)在我删除的每个 div 上,我设法使 Chrome 的内存使用或多或少保持稳定,而不是每次删除地图和添加新地图时都会增加。
我会建议删除地图 div 的内容并delete
在保存对地图的引用的变量上使用,并且可能明确地delete
调用任何事件侦听器。
但是,有一个公认的错误,这可能不起作用。
由于谷歌没有为 api v3 提供 gunload() 更好地在 html 中使用 iframe 并将 map.html 作为此 iframe 的源。使用后使 src 为空。那肯定会释放地图消耗的内存。