Memory leaks OpenLayers 6 setTileLoadFunction()文档化示例使用URL.createObjectURL(数据),需要调用revokeObjectURL()以避免内存泄漏

Memory leaks OpenLayers 6 setTileLoadFunction()文档化示例使用URL.createObjectURL(数据),需要调用revokeObjectURL()以避免内存泄漏,memory-leaks,openlayers-6,Memory Leaks,Openlayers 6,OpenLayers的最新文档如下: 显示了如何使用setTileLoadFunction()的示例。以下是提供的示例: import TileState from 'ol/TileState'; source.setTileLoadFunction(function(tile, src) { var xhr = new XMLHttpRequest(); xhr.responseType = 'blob'; xhr.addEventListener('loadend', func

OpenLayers的最新文档如下: 显示了如何使用setTileLoadFunction()的示例。以下是提供的示例:

import TileState from 'ol/TileState';

source.setTileLoadFunction(function(tile, src) {
  var xhr = new XMLHttpRequest();
  xhr.responseType = 'blob';
  xhr.addEventListener('loadend', function (evt) {
    var data = this.response;
    if (data !== undefined) {
      tile.getImage().src = URL.createObjectURL(data);
    } else {
      tile.setState(TileState.ERROR);
    }
  });
  xhr.addEventListener('error', function () {
    tile.setState(TileState.ERROR);
  });
  xhr.open('GET', src);
  xhr.send();
});
createObjectURL()创建一个必须手动撤销的永久对象。此代码示例将泄漏内存。当分幅被丢弃时,我们创建的URL对象会粘住


有关正确的示例代码,请参见我的答案。

在这个示例中,我做了两个更改。其中一个原因是为了与旧浏览器(如IE)兼容,在IE中无法立即设置responseType,您必须等待onloadstart,如下所示:

xhr.onloadstart = function (ev) {
    xhr.responseType = "blob";
}
加载磁贴后,您需要释放创建的URL对象:

    tile.getImage().onload = function() {
        URL.revokeObjectURL(this.src);
下面是应该编写的完整示例

import TileState from 'ol/TileState';

source.setTileLoadFunction(function(tile, src) {
  var xhr = new XMLHttpRequest();
  xhr.onloadstart = function() {
      xhr.responseType = 'blob';
  }
  xhr.addEventListener('loadend', function (evt) {
    var data = this.response;
    if (data !== undefined) {
      tile.getImage().src = URL.createObjectURL(data);
      tile.getImage().onload = function() {
        URL.revokeObjectURL(this.src);
      }
    } else {
      tile.setState(TileState.ERROR);
    }
  });
  xhr.addEventListener('error', function () {
    tile.setState(TileState.ERROR);
  });
  xhr.open('GET', src);
  xhr.send();
});
注意:在某些浏览器(包括iPad上的ios 11.2)中,createObjectURL失败,因为传入的数据对象类型不正确。如果您认为可以使用旧设备访问该页面,则可能需要进行额外的错误检查。如果/当我获得足够的附加信息时,我将编辑此答案,并附加错误检查要求。