mapbox / storytelling

Storytelling with maps template
BSD 3-Clause "New" or "Revised" License
527 stars 258 forks source link

[Performance] Improve Storytelling first page load time #23

Open ryanbaumann opened 4 years ago

ryanbaumann commented 4 years ago

Problem

As a Storytelling map user, I want my web page to load as fast as possible for the best user experience and SEO / Page Load Time. The Mapbox GL JS library is relatively large vs. other assets on the page, so loading it in my webpage header as a synchronous, blocking operation can impact my time-to-first page load.

Solution

Change the vanilla js template to load and initialize the Mapbox GL JS library asynchronously, alongside the rest of the page assets like HTML and CSS. This allows all smaller assets to load while the larger GL JS library loads and fetches the first map assets like the style sheet, fonts, glyphs, and tiles.

Implementation

Fist load the JS library async in the page head element:

<head>
<script async defer src='https://api.tiles.mapbox.com/mapbox-gl-js/v1.7.0/mapbox-gl.js' onload="initMap()"></script>`
</head>

Then define the function to run after the Mapbox GL JS library loads:

<script>
function initMap() {
            mapboxgl.accessToken = 'my-token';
            map = new mapboxgl.Map({
                container: 'map',
                style: style_url,
                zoom: 1,
                hash: true
            });
        // Add functions that happen after the map initializes here
}
</script>

Finally, load the Mapbox GL CSS at the bottom of the page, after all HTML and headers have completed:

<script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v1.7.0/mapbox-gl.css' rel='stylesheet' />
</script>

cc/ @jbranigan @lobenichou

eversionsystems commented 9 months ago

You can only use async or defer, I believe you can't use both in a script tag...