Best way to lazy-load Snipcart in NextJS

Hi, I noticed that Snipcart takes a considerable chunk out of the initial load in my app. Is there anything I can do to improve it? For example, using next/dynamic? Would be interesting to see some example code for this.

2 Likes

Hey @FabienF,

We’re aware of this, and this is definitely something we want to improve in upcoming versions of the cart.

For now, we recommend adding the async keyword to the script tag that includes snipcart.js.

Thanks, that’s good to know. I was already using preconnect linkts and the async attribute.

I take it that there’s no other solution from Next’s perspective, then?

Yeah @FabienF, to be honest, I’m not a Next expert, maybe there are ways to lazy load scripts, but I know that we don’t have anything specific for any frameworks at the moment.

thanks for the awesome information.

Hi @alexsunny123

I am not sure if this is the “right way” but I did this for my client website

I simply added a timeout function or add a facade that only loads Snipcart if the website users make their first interaction (moving mouse, scroll, tap on screen,…)

This method also helps bringing up the Lighthouse score as well.

I also did the same thing for Facebook Chat bubble thing

I hope this will help. Please let community know if you found a better solution

1 Like

At the moment, your best bet will be to do something along the lines of what @MorningTide suggested

Here’s one simple example. It doesn’t trigger on user interaction though, only waiting for the window to have focus and be visible:

	<script>
		let snipcartIsLoaded = false
		setTimeout(() => {
			if (document.hasFocus()) {
				loadSnipcart()
			}
			document.addEventListener('visibilitychange', loadSnipcart);
		}, 0)

		const loadSnipcart = () => {
			if(document.hidden || snipcartIsLoaded){
				return
			}
			snipcartIsLoaded = true
			document.removeEventListener('visibilitychange', loadSnipcart)
			const snipcartScript = document.createElement('script');
			snipcartScript.setAttribute('src', 'https://cdn.snipcart.com/themes/v3.2.0/default/snipcart.js');
			document.head.appendChild(snipcartScript);
			const snipcartStyles = document.createElement('link');
			snipcartStyles.rel = 'stylesheet';
			snipcartStyles.type = 'text/css';
			snipcartStyles.href = 'https://cdn.snipcart.com/themes/v3.2.0/default/snipcart.css';
			document.head.appendChild(snipcartStyles)
		}
	</script>
1 Like