防止重复的$ .ajax({dataType:'script'})导致内存泄漏

时间:2014-01-14 18:09:38

标签: javascript jquery performance memory-leaks dynamic-script-loading

我正在编写一个本地运行的小型网络应用,预计会有间歇性的网络访问。考虑到这一点,我正在检查我们的外部依赖(Google Maps)是否无法加载,并在10秒后再次尝试。简要概述:

// Assume the worst
var mapsSuccess = false;

// Only gets invoked by maps success
function initialize(){
  // Set the flag to prevent continuous recursion of the previous function
  mapsSucess = true;

  /* application init */
}

// Invoke immediately
( function mapsCall(){
  // Maybe we don't need this...
  if( mapsSuccess === true ){
    return;
  }

  $.ajax( {
    cache    : true,
    dataType : 'script',
    // `callback` param specifies function to call on successful execution
    url      : googleMapsUri + '&callback=initialize'
  } );

  // Run this function again in 10 seconds to see if we succeeded
  setTimeout( mapsCall, 10000 )
}() );

问题出在最糟糕的情况,即我们无法成功加载地图数小时。有后备离线内容,但目前内存泄漏最终导致浏览器崩溃。检查Chrome开发工具中的时间表,来源显而易见:

Chrome dev tools memory timeline: event listener count increases with each request

每次重新调用mapsCall时,都会调用新的DOM节点和新的事件侦听器。我想删除这些并删除任何事件监听器被绑定(具有讽刺意味的是,我的代码没有设置任何事件监听器),所以我在mapsCall正文中设置了这个:

$( 'script[async][src*="callback=initialize"]' ).off().remove();

这有效地删除了冗余的脚本元素,但由于事件侦听器计数,并没有真正消除内存泄漏。我曾尝试使用$._data( element, 'events' )嗅探这些神秘事件监听器的绑定位置,但它们不在脚本本身,documentwindow或根元素({{ 1}},html)所以我不知所措。

0 个答案:

没有答案