Lazy loading for maps

If the page has an interactive Yandex or Google map, then it can take a few seconds in loading speed, and it's great to ruin the Google PageSpeed report .



In this article I will describe an example of optimizing a Yandex map connection, where it will be loaded in a lazy way when you hover the mouse cursor.



1. First, let's build a Yandex map ( here ) and get a script, something like this:



<script type="text/javascript" 
        charset="utf-8" 
        async 
        src="https://api-maps.yandex.ru/services/constructor/1.0/js/?um=constructor%3A1ad4887964fc2e0a6f07c6246ffe638b138f8baacc8983f9a6a0f401a02e833a&width=1280&height=400&lang=ru_RU&scroll=true"></script>


2. On our site, we will write a container for the card block:



<div id="map_container" class="map container-fluid">
<script id="ymap_lazy"
        async
        data-src="https://api-maps.yandex.ru/services/constructor/1.0/js/?um=constructor%3A1ad4887964fc2e0a6f07c6246ffe638b138f8baacc8983f9a6a0f401a02e833a&width=1280&height=400&lang=ru_RU&scroll=true"></script>
</div>


And the styles for our static image (it is easier to make it with any screenshots):



<style>
    .map.container-fluid {
        height: 340px;
        padding: 0;
        background-image: url(/uploads/common/ymap0.png);
        background-position: center center;
    }
</style>


3. The most interesting thing is to write JavaScript code that will track events of mouse hover or clicking on the touch screen of the phone, and replace the static image with an interactive map:



<script>
    let map_container = document.getElementById('map_container');
    let options_map = {
        once: true,//  ,    
        passive: true,
        capture: true
    };
    map_container.addEventListener('click', start_lazy_map, options_map);
    map_container.addEventListener('mouseover', start_lazy_map, options_map);
    map_container.addEventListener('touchstart', start_lazy_map, options_map);
    map_container.addEventListener('touchmove', start_lazy_map, options_map);

    let map_loaded = false;
    function start_lazy_map() {
        if (!map_loaded) {
            let map_block = document.getElementById('ymap_lazy');
            map_loaded = true;
            map_block.setAttribute('src', map_block.getAttribute('data-src'));
            map_block.removeAttribute('data_src');
            console.log('YMAP LOADED');
        }
    }
</script>


4. Profit! Your site is now loading much faster!



PS: This method can also be adapted for other objects that are not required JS and CSS, due to which the page load speed can be less than a second.



All Articles