Загрузка тайлов в Leaflet основана на стандартном HTML-механизме
<img>-элементов, где каждый тайл представляет собой
отдельный запрос к серверу. Библиотека не выполняет низкоуровневую
обработку HTTP-запросов, а делегирует это браузеру, получая уведомления
о результате загрузки через события изображения.
Каждый слой L.TileLayer формирует URL тайла на основе
шаблона:
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19
}).addTo(map);
При каждом перемещении карты вычисляются координаты тайлов
(x, y, z), после чего создаются изображения:
<img src=".../z/x/y.png">
Браузер самостоятельно инициирует запросы и кэширование, а Leaflet отслеживает события загрузки через DOM API.
Ошибки тайлов не формализованы как единая сущность — они проявляются
через поведение <img>:
HTTP-ошибки (404, 403, 500) Сервер возвращает
некорректный ответ или отсутствующий ресурс. Браузер триггерит событие
error.
Сетевые ошибки Отсутствие соединения, DNS-сбои,
обрыв соединения. Также приводят к error у изображения.
CORS-ограничения При попытке доступа к тайлам с ограниченной политикой кросс-доменных запросов изображение может не отобразиться, особенно при использовании canvas-операций поверх тайлов.
Некорректные тайлы Сервер возвращает изображение с повреждёнными данными или пустой графикой, при этом технически ошибка не фиксируется браузером.
Leaflet предоставляет событие tileerror, которое
срабатывает при неудачной загрузке тайла:
const layer = L.tileLayer(urlTemplate);
layer.on('tileerror', function (error, tile) {
console.log('Ошибка тайла:', error, tile);
});
Объект tile содержит DOM-элемент
<img>, а также координаты:
tile.coords; // {x, y, z}
Событие позволяет реализовать централизованную обработку ошибок загрузки.
Leaflet поддерживает встроенный механизм замены изображения при ошибке:
L.tileLayer(urlTemplate, {
errorTileUrl: '/images/empty-tile.png'
}).addTo(map);
Этот параметр подставляет резервное изображение вместо отсутствующего тайла, предотвращая визуальные «дыры» на карте.
Особенности поведения:
errorLeaflet не реализует встроенный retry-механизм, поэтому повторные попытки организуются вручную:
L.TileLayer.Retry = L.TileLayer.extend({
initialize: function (url, options) {
L.TileLayer.prototype.initialize.call(this, url, options);
this._retryLimit = options.retryLimit || 3;
},
createTile: function (coords, done) {
const tile = L.TileLayer.prototype.createTile.call(this, coords, done);
tile._retryCount = 0;
tile.addEventListener('error', () => {
if (tile._retryCount < this._retryLimit) {
tile._retryCount++;
tile.src = tile.src.split('?')[0] + '?retry=' + tile._retryCount;
} else {
done(null, tile);
}
});
return tile;
}
});
Такой подход позволяет реализовать контроль нестабильных источников тайлов.
Браузер активно кэширует тайлы, что может маскировать ошибки:
Для диагностики часто используется отключение кэша через параметры URL:
L.tileLayer(urlTemplate + '?v=' + Date.now());
При отсутствии сети <img> генерирует ошибку
загрузки. В Leaflet это проявляется массовым tileerror.
Практика обработки включает:
errorTileUrl на офлайн-заглушкуПример переключения источника:
map.on('tileerror', function () {
map.removeLayer(onlineLayer);
map.addLayer(offlineLayer);
});
Более низкоуровневый контроль достигается через переопределение
createTile:
L.TileLayer.Custom = L.TileLayer.extend({
createTile: function (coords, done) {
const img = document.createElement('img');
img.onl oad = function () {
done(null, img);
};
img.oner ror = function () {
img.src = '/fallback.png';
done(null, img);
};
img.src = this.getTileUrl(coords);
return img;
}
});
Этот метод позволяет полностью контролировать жизненный цикл тайла.
Для анализа ошибок загрузки применяется сбор событий:
layer.on('tileloadstart', function (e) {
console.log('Загрузка тайла:', e.coords);
});
layer.on('tileload', function (e) {
console.log('Загружен тайл:', e.coords);
});
layer.on('tileerror', function (e) {
console.log('Ошибка тайла:', e.tile.src, e.coords);
});
Такой подход позволяет выявлять:
Использование {s} в URL шаблоне распределяет
нагрузку:
L.tileLayer('https://{s}.tile.server.com/{z}/{x}/{y}.png', {
subdomains: ['a', 'b', 'c']
});
Ошибки могут быть связаны с:
При деградации одного поддомена Leaflet продолжает использовать остальные, но ошибки становятся неравномерными.
При detectRetina: true запрашиваются тайлы
@2x. Ошибки часто возникают из-за отсутствия
высокоразрешённых ресурсов:
L.tileLayer(urlTemplate, {
detectRetina: true
});
Если сервер не поддерживает retina-версии, происходят:
@2x тайлыПри использовании Service Worker ошибки тайлов могут не соответствовать реальному состоянию сети:
Content-TypeВ результате tileload может не соответствовать
фактическому содержимому.
При деградации источника тайлов возникает каскад запросов:
error событийОптимизация включает ограничение параллельных загрузок:
L.tileLayer(urlTemplate, {
updateWhenIdle: true,
keepBuffer: 2
});
Это снижает нагрузку при нестабильных источниках.
Дополнительная проверка может выполняться через анализ изображения после загрузки:
img.onl oad = function () {
if (img.width === 0 || img.height === 0) {
handleInvalidTile(img);
}
};
Такая проверка позволяет выявлять «пустые» тайлы, которые не вызывают
error, но фактически некорректны.