Документированный пример OpenLayers 6 setTileLoadFunction () использует URL.createObjectURL (данные), необходимо вызвать revokeObjectURL (), чтобы избежать утечки памяти - PullRequest
0 голосов
/ 19 июня 2020

Последняя документация OpenLayers здесь: https://openlayers.org/en/latest/apidoc/module-ol_Tile.html показывает пример использования 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();
});

URL.createObjectURL () создает постоянный объект, который необходимо отозвать вручную. В этом примере кода будет утечка памяти. Когда плитки удаляются, созданные нами объекты URL остаются.

Правильный пример кода см. В моем ответе.

1 Ответ

0 голосов
/ 19 июня 2020

В этом примере я делаю два изменения. Один из вариантов совместимости со старыми браузерами, например 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();
});
...