IT story

맵 인스턴스를 삭제하는 올바른 방법은 무엇입니까?

hot-time 2020. 9. 14. 21:43
반응형

맵 인스턴스를 삭제하는 올바른 방법은 무엇입니까?


최근에 html5 모바일 애플리케이션을 개발했습니다. 애플리케이션은 탐색 해시 변경 이벤트가 전체 DOM을 대체하는 단일 페이지였습니다. 애플리케이션의 한 섹션은 API v3을 사용하는 Google지도였습니다. 맵 div가 DOM에서 제거되기 전에 이벤트 핸들러 / 리스너를 제거하고 사용자가 해당 섹션으로 다시 돌아 오지 않을 수있는 한 가능한 한 많은 메모리를 확보하고 싶습니다.

맵 인스턴스를 파괴하는 가장 좋은 방법은 무엇입니까?


이 질문에 대한 두 번째 답변을 추가하고 있습니다. 이전 답변에 대한 후속 의견을 통해 앞뒤로 가졌던 내용을 제거하고 싶지 않기 때문입니다.

하지만 최근에 귀하의 질문을 직접적으로 다루는 정보를 발견하여 공유하고 싶었습니다. 이 사실을 알고 있는지는 모르겠지만 Google Maps API Office Hours 2012 년 5 월 9 일 비디오 에서 Google의 Chris Broadfoot과 Luke Mahe 는 stackoverflow 에서이 질문에 대해 논의 했습니다 . 비디오 재생을 12:50으로 설정하면이 섹션에서 질문에 대해 논의합니다.

본질적으로 그들은 그것이 버그라는 것을 인정하지만, 연속적인 맵 인스턴스 생성 / 파괴와 관련된 사용 사례를 실제로 지원하지 않는다고 덧붙입니다. 지도의 단일 인스턴스를 만들어 이러한 종류의 모든 시나리오에서 재사용하는 것이 좋습니다. 또한지도를 null로 설정하고 이벤트 리스너를 명시 적으로 제거하는 방법에 대해서도 설명합니다. 이벤트 리스너에 대한 우려를 표명하고 맵을 null로 설정하는 것으로 충분하다고 생각했지만 이벤트 리스너를 구체적으로 언급하기 때문에 우려 사항이 유효한 것 같습니다. 또한지도를 보유하는 DIV도 완전히 제거 할 것을 권장했습니다.

어쨌든, 이것을 전달하고 그것이 stackoverflow 토론에 포함되어 있는지 확인하고 당신과 다른 사람들에게 도움이되기를 바랍니다.


공식적인 답변은 그렇지 않을 것입니다. 단일 페이지 애플리케이션의 맵 인스턴스는 재사용되어야하며 파괴 된 후 다시 작성되지 않아야합니다.

일부 단일 페이지 응용 프로그램의 경우 이는지도가 생성 된 후 숨겨 지거나 DOM에서 연결 해제 될 수 있지만 절대 파괴 / 다시 생성되지 않도록 솔루션을 다시 설계하는 것을 의미 할 수 있습니다.


분명히 맵 인스턴스를 실제로 파괴 할 수 없기 때문에이 문제를 줄이는 방법은 다음과 같습니다.

  • 웹 사이트에서 한 번에 여러지도를 표시해야합니다.
  • 지도의 수는 사용자 상호 작용에 따라 변경 될 수 있습니다.
  • 지도를 숨기고 다른 구성 요소와 함께 다시 표시해야합니다 (즉, 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
    }
 }
}

You pass it the starting map options (as per the second argument of google.maps.Map's constructor), and it returns both the map instance (on which you can call functions pertaining to google.maps.Map), and the container , which you can style using the class "myDivClassHereForStyling", and you can dinamically append to the DOM. If you need to reset the system, you can use mapInstancesPool.reset(). It will reset the counter to 0, while keeping all existing instances in the pool for reuse. In my application I needed to remove all maps at once and create a new set of maps, so there's no function to recycle a specific map instance: your mileage may vary. To remove the maps from the screen, I use jQuery's detach, which doesn't destroy the map's container .

By using this system, and using

google.maps.event.clearInstanceListeners(window);
google.maps.event.clearInstanceListeners(document);

and running

google.maps.event.clearInstanceListeners(divReference[0]);
divReference.detach()

(where divReference is the div's jQuery object returned from the Instance Pool) on every div I'm removing, I managed to keep Chrome's memory usage more or less stable, as opposed to it increasing every time I delete maps and add new ones.


I would have suggested removing the content of the map div and using delete on the variable holding the reference to the map, and probably explicitly deleteing any event listeners.

There is an acknowledged bug, though, and this may not work.


As google doesnt provide gunload() for api v3 better use iframe in html and assign map.html as a source to this iframe. after use make src as null. That will definitely free the memory consumed by map.


When you remove the div, that removes the display panel and the map will disappear. To remove the map instance, just make sure that your reference to the map is set to null and that any references to other parts of the map are set to null. At that point, JavaScript garbage collection will take care of cleaning up, as described in: How does garbage collection work in JavaScript?.


I guess you're talking about addEventListener. When you remove the DOM elements, some browsers leak these events and doesn't remove them. This is why jQuery does several things when removing an element:

  • It removes the events when it can using removeEventListener. That means it's keeping an array with the event listeners it added on this element.
  • It deletes the attributes about events (onclick, onblur, etc) using delete on the DOM element when addEventListener is not available (still, it has an array where it stores the events added).
  • It sets the element to null to avoid IE 6/7/8 memory leaks.
  • It then removes the element.

참고URL : https://stackoverflow.com/questions/10485582/what-is-the-proper-way-to-destroy-a-map-instance

반응형