Оптимизация загрузки Яндекс.Карты на сайте

Оптимизируя скорость загрузки сайта на разных проектах, когда дело доходит до Яндекс.Карт, то здесь приходится искать непростые решения, чтобы загрузка карты не мешала загрузке HTML структуры. В этой статье я хочу поделиться с вами таким способом загрузки Яндекс.Карт, когда Яндекс.Карта загружается только при наведении, что значительно увеличивает скорость загрузки сайта и уменьшает количество запросов от карт Яндекса.

Видео, кстати, также очень сильно влияет на скорость загрузки. Поэтому рекомендую следующую статью, где вы узнаете о том, как сделать загрузку видео по клику:

  • Загружаем видео только при клике

Многие могут вспомнить GIF файлы, ведь они также очень большого размера. Чтобы их оптимизировать, лучше их также загружать только при клике. То есть, если человек хочет посмотреть полную GIF-анимацию, то он кликает на Play и смотрит, иначе не нужно тратить трафик пользователя на загрузку всего содержимого GIF файлов. Этот способ оптимизированной загрузки файлов описан в следующей статье:

  • Загружаем GIF только при клике

Почему лучше всего загружать при наведении?

Чтобы не писать много текста, лучше всего показать на конкретных цифрах.

Вот все запросы от Яндекса, где карта загружается сразу после загрузки страницы (когда вы создали карту с помощью конструктора карт):

Итог: 9 внешних скриптов и 44 изображения.

А вот количество запросов от Яндекса, когда мы загружаем только API карт Яндекса, а саму загрузку откладываем когда уже наведем:

Итог: 4 внешних скрипта и 5 изображений. Уже лучше, но ведь можно еще 😉 !

Ну и последний (наш оптимизированный пример) список запросов от Яндекса, когда даже API карт Яндекса загружаются после наведения:

Вот так лучше. Сейчас не загружается ни один лишний файл до тех пор, пока мы не наведем на саму карту.

Все загружаемые файлы можно отследить на вкладке Network (Сеть) в инструментах разработчика браузера Google Chrome. Но в Firefox есть аналогичный инструмент и вы можете проанализировать все запросы с помощью этого браузера.

К сожалению, реализация не такая простая, как кажется на первый взгляд… Все дело в том, что у Яндекс.Карт на данный момент нет callback-а о том, что карта загрузилась полностью. Но, как вы знаете, если тщательно искать, то проблему наверняка можно решить. И решение нашлось, но обо всем по порядку…

Как сделать оптимизированную загрузку Яндекс.Карт?

Как сделать загрузку Яндекс.Карты при наведении

Первым делом нам необходимо подключить библиотеку jQuery (можно и без нее), затем прописать стили для блока с картой, для индикатора загрузки, а после заставить это все работать в нужное время и в нужном месте. Чтобы разложить все по полочкам, будем все делать по этапам, а если останутся вопросы, то вы всегда сможете задать их ниже в комментариях.

1 этап. Подключаем необходимые скрипты

Из сторонних скриптов здесь только библиотека jQuery — скачать jQuery.

Подключаем перед закрывающим тегом </body>:HTML КОД

1 <script src=»js/jquery.min.js»></script>

2 этап. Разметка для карты

Сейчас нам необходимо создать структуру для дальнейшей вставки карты, а также индикатора загрузки, чтобы пользователь понимал что происходит:HTML КОД

1 2 3 4 <div class=»ymap-container»> <div class=»loader loader-default»></div> <div id=»map-yandex»></div> </div><!— .ymap-container —>

Ничего сложного в данной структуре нет:

  • Блок с классом ymap-container — служит как «обертка» для блока с индикатором загрузки и блока с картой.
  • Блок с классами loader и loader-default — это наш индикатор загрузки.
  • Блок с идентификатором map-yandex — здесь появится карта Яндекса, когда мы наведем на «блок-обертку».

3 этап. Стили для блока с картой, а также для индикатора загрузки

Сейчас нам необходимо прописать стили для индикатора загрузки, а также для блока, где появится карта.

Индикатор загрузки, безусловно, играет очень важную роль. Иначе может возникнуть следующая ситуация: пользователь навел на блок, но ничего не происходит. Если у посетителя интернет-соединение слабенькое, то загрузка может затянуться, а если он не будет понимать того, что процесс идет, то решит, что карта просто не работает.

Но здесь есть еще один небольшой нюанс: так как карту мы загружаем только при наведении, то нам необходимо пользователю показать что карта здесь все-таки есть. Для этого я сделал скриншот того места на карте, которое затем загрузиться. А изображение было оптимизировано и затем я его положил в папку img.

Итак, вот стили для блока с картой:CSS КОД

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 /* &#34;Блок-обертка&#34;, где мы задаем фоновое изображение скриншотом как на карте */ .ymap-container { position: relative; margin: 3em 0 2em 0; overflow: hidden; cursor: pointer; background: url(‘../img/yandex-before-load.png’) #ffffff no-repeat; background-position: center center; background-size: cover; box-shadow: 0 0 2em 0 rgba(0,0,0,.2); }   /* Блок, в котором появится Яндекс.Карта */ #map-yandex { position: relative; z-index: 7; width: 100%; height: 20em; cursor: pointer; background-color: transparent; }

Остались стили только для индикатора загрузки:CSS КОД

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 /* Индикатор загрузки, который показывается до загрузки карты */ .loader { position: absolute; z-index: 15; top: -100%; left: 0; box-sizing: border-box; width: 100%; height: 100%; overflow: hidden; color: #000000; transition: opacity .7s ease; opacity: 0; background-color: rgba(0,0,0,.55); }   .loader:after, .loader:before { box-sizing: border-box; }   .loader.is-active { top: 0; opacity: 1; }   .loader-default:after { position: absolute; top: calc(50% — 24px); left: calc(50% — 24px); width: 48px; height: 48px; content: »; animation: rotation 1s linear infinite; border: solid 8px #ffffff; border-left-color: transparent; border-radius: 50%; }   @keyframes rotation { from { transform: rotate(0); } to { transform: rotate(359deg); } }   @keyframes blink { from { opacity: .5; } to { opacity: 1; } }

Здесь я выложил пример, где нет префиксов, чтобы код не был громоздким.

4 этап. Заставляем все вместе работать (JS)

Чтобы много не расписывать, опишу лишь процесс: когда пользователь наводит на карту, появляется индикатор загрузки (в это время загружается API Яндекса, а после сама карта), как только карта была загружена, то индикатор загрузки пропадает:JAVASCRIPT КОД

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 //Переменная для включения/отключения индикатора загрузки var spinner = $(‘.ymap-container’).children(‘.loader’); //Переменная для определения была ли хоть раз загружена Яндекс.Карта (чтобы избежать повторной загрузки при наведении) var check_if_load = false; //Необходимые переменные для того, чтобы задать координаты на Яндекс.Карте var myMapTemp, myPlacemarkTemp;   //Функция создания карты сайта и затем вставки ее в блок с идентификатором &#34;map-yandex&#34; function init () { var myMapTemp = new ymaps.Map(«map-yandex», { center: [55.730138, 37.594238], // координаты центра на карте zoom: 7, // коэффициент приближения карты controls: [‘zoomControl’, ‘fullscreenControl’] // выбираем только те функции, которые необходимы при использовании }); var myPlacemarkTemp = new ymaps.GeoObject({ geometry: { type: «Point», coordinates: [55.730138, 37.594238] // координаты, где будет размещаться флажок на карте } }); myMapTemp.geoObjects.add(myPlacemarkTemp); // помещаем флажок на карту   // Получаем первый экземпляр коллекции слоев, потом первый слой коллекции var layer = myMapTemp.layers.get(0).get(0);   // Решение по callback-у для определения полной загрузки карты waitForTilesLoad(layer).then(function() { // Скрываем индикатор загрузки после полной загрузки карты spinner.removeClass(‘is-active’); }); }   // Функция для определения полной загрузки карты (на самом деле проверяется загрузка тайлов) function waitForTilesLoad(layer) { return new ymaps.vow.Promise(function (resolve, reject) { var tc = getTileContainer(layer), readyAll = true; tc.tiles.each(function (tile, number) { if (!tile.isReady()) { readyAll = false; } }); if (readyAll) { resolve(); } else { tc.events.once(«ready», function() { resolve(); }); } }); }   function getTileContainer(layer) { for (var k in layer) { if (layer.hasOwnProperty(k)) { if ( layer[k] instanceof ymaps.layer.tileContainer.CanvasContainer || layer[k] instanceof ymaps.layer.tileContainer.DomContainer ) { return layer[k]; } } } return null; }   // Функция загрузки API Яндекс.Карт по требованию (в нашем случае при наведении) function loadScript(url, callback){ var script = document.createElement(«script»);   if (script.readyState){ // IE script.onreadystatechange = function(){ if (script.readyState == «loaded» || script.readyState == «complete»){ script.onreadystatechange = null; callback(); } }; } else { // Другие браузеры script.onload = function(){ callback(); }; }   script.src = url; document.getElementsByTagName(«head»)[0].appendChild(script); }   // Основная функция, которая проверяет когда мы навели на блок с классом &#34;ymap-container&#34; var ymap = function() { $(‘.ymap-container’).mouseenter(function(){ if (!check_if_load) { // проверяем первый ли раз загружается Яндекс.Карта, если да, то загружаем   // Чтобы не было повторной загрузки карты, мы изменяем значение переменной check_if_load = true;   // Показываем индикатор загрузки до тех пор, пока карта не загрузится spinner.addClass(‘is-active’);   // Загружаем API Яндекс.Карт loadScript(«https://api-maps.yandex.ru/2.1/?lang=ru_RU&amp;loadByRequire=1», function(){ // Как только API Яндекс.Карт загрузились, сразу формируем карту и помещаем в блок с идентификатором &#34;map-yandex&#34; ymaps.load(init); }); } } ); }   $(function() {   //Запускаем основную функцию ymap();   });

Весь код я постарался подробно прокомментировать, чтобы все было понятно, но если остались вопросы, то вы можете задать их мне в комментариях.

Скачать готовый пример вы можете по ссылке ниже:

Вывод

Данный способ особенно хорошо, если применять его вместе с другими способами оптимизации: запускаем Youtube видео только по клику и запускаем GIF по клику. Тогда вы точно ощутите прирост в скорости загрузки.

Если у вас появились идеи и мысли на счет того, как можно оптимизировать данный способ — не стесняйтесь, пишите в комментариях! 🙂

Успехов!

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *