Maintaining Green Google PageSpeed Scores When Using Third-Party Scripts

This article will cover keeping your Google PageSpeed Insights scores in the 90-100 range when using third-party scripts.

What is Google PageSpeed?

Google PageSpeed Insights is a free tool that allows you to check the speed of your site. Since speed is now a ranking factor for Google search, it is important to keep your site fast.

By default, VOLT Stores score in the 90-100 range on PageSpeed testing. This is the green or “good” range, where you want to stay for search engine optimization (SEO). To help you rank highest on Google and other search engines, VOLT has lightning-fast page loading speed — a key advantage for your ecommerce platform. Google AMP pages (also built-in to VOLT) are an even faster version of your VOLT Store that will appear on Google search on mobile devices.

All together, VOLT’s mobile-first experience provides best-in-class SEO for ecommerce stores.

One thing can easily damage your SEO, though, and that is loading third-party scripts. Read on for the potential risks of using third-party scripts in the VOLT Store when building custom Blocks using the Element platform.

About Third-Party Scripts

Third-party scripts are any external JavaScript or CSS stylesheets that are not being hosted directly by your Volusion store. These scripts and stylesheets can be large and cause significant slowdown on your site. Ads are a common example of third-party scripts added to websites that can potentially slow things down. If your site slows too far, Google and other search engines might lower your ranking placement in search results.

Thankfully, the VOLT Store does not reference any third-party scripts by default. When building custom Blocks, you will want to avoid using third-party scripts when possible, as this article will discuss in detail later.

Why it Matters

You will want to avoid third-party scripts in your custom Blocks for two main reasons.

First, loading external scripts requires additional server requests to fetch the files. This can slow down your web site significantly, resulting in poorer scores when assessing performance with Google PageSpeed Insights. Even using too many dependencies (importing too many npm packages like lodash) can increase the bundle size of your custom Block, meaning more data will need to be transferred to the user of your site.

Second, you cannot execute scripts on AMP pages. Google AMP (Accelerated Mobile Pages) pages, when available, show up in Google search results on mobile devices. VOLT is AMP-ready by default when using built-in Blocks. If you need the third-party script to function on AMP pages, you may need to look for another solution, such as reproducing the functionality in React or building a custom integration with the target API (if one is available).

AMP pages also cannot load external CSS files, except for font files in the <head> element. Custom Blocks are unable to load any external CSS files without losing AMP compatibility.

The previous article on custom fonts in VOLT Stores offers an example of loading an external CSS file (in the section using <link>), with the caveat that it does not work for AMP pages. Read on for alternatives to third-party scripts, a discussion of bundle size, and the technical details for including third-party scripts in your custom Blocks built with Element.

Why Might You Want to use Third-Party Scripts?

A common reason to load third-party scripts would be to add some content provided by a third-party provider. You may want to add some type of social proof functionality through a service like Proof, showing customers recent purchases in order to increase conversion rates. A small third-party request that would have less impact on your site would be loading a CSS variable font, as was discussed in the previous article on customizing fonts using Element.

Your site may need a custom search function, such as using Algolia search to be able to search and reference some content on your website directly from your VOLT store. Or, you might need a newsletter signup. Often, email newsletter subscription services like MailerLite provide a <script> tag to be added to your website. Sometimes, you might want to load a JavaScript framework, such as jQuery. It is not recommended to load jQuery, as you will see later, because this can break Google AMP compatibility.

What are Alternatives to Third-Party Scripts?

This article offers instructions for and alternatives to loading third-party scripts. Decreasing your bundle size through minimizing dependencies will also be discussed. The developmental flexibility built-in to Element offers you many options for providing your VOLT Store with custom functionality. In fact, you may not need to load a third-party script at all if you can duplicate the desired functionality in React.

A good reference for creating Google AMP-ready components that do not require third-party scripts is the Google AMP documentation. For example, the amp-carousel component provides a slideshow functionality that is compatible with Google AMP. Other useful features might be the amp-form and amp-autocomplete components.

Next, you will learn what to always avoid loading in custom Blocks, examine how to keep bundle size down, and discover how to load third-party scripts from custom Blocks.

What Not to Load in Custom Blocks

There are a few items you should refrain from loading altogether:

Avoid loading JavaScript framework libraries like jQuery.

You can likely achieve what you want with less than the amount that you would need to load with the framework. Additionally, AMP does not allow JavaScript at all, so you would not be able to utilize any third-party JavaScript framework and remain AMP compliant. Later, you will learn how to install just the functions you need from a npm package like lodash, a helper library for working with JavaScript objects and arrays.

Avoid loading CSS libraries

Google AMP pages have a limit of only 50KB CSS total for all the styles in your entire page. It doesn't take much to go over the 50KB CSS limit for AMP compliance, and you don't want to invalidate your entire page (or site) on AMP because you loaded too much CSS. For more information, please read the article “Styling Your Block with CSS” for how best to add CSS to your block.

Basically, you will want to use Element’s Atomic CSS when possible for styling and then write custom styles using Aphrodite, which is built-in to Element. In the rare case that you cannot accomplish what you need using the CSS options provided, you may load an external CSS file by using the addLink util, which will be discussed later in your file.

Be sure to keep the external CSS file small, and be aware that using external stylesheets will keep your site from being AMP compliant, so only use them on the desktop (or non-AMP) version of your VOLT Store.

What to do instead

As a general rule, you should try to avoid loading third-party scripts when you can; however, it is not always possible to do so. Consider whether your needs can be met using React — there's a good chance that someone has already accomplished what you're trying to do and posted about it on developer forums. Google in particular has discussed that loading too much JavaScript can be detrimental for your site’s real-world performance by hurting page speeds.

Element is built-in on React, which already offers you a lot of dynamic functionality in your ecommerce store. If you absolutely need a third-party script, this article will show you how to build one in a custom Block using Element.

What is Built-in to Element

Element uses rollup (the npm package) to bundle all of its JavaScript into one file. The size of that file is called bundle size, and VOLT typically has a small bundle size. That is part of the reason VOLT is so fast. When you build your site using vanilla JavaScript, React, and Aphrodite for CSS, these tools are all very fast because Element. However, adding additional libraries (also called dependencies or npm packages) is possible, albeit at the cost of potentially increasing the bundle size.

The next section will show you how to minimize bundle size, and then the article will discuss loading third-party scripts, which will not be included in your bundle.

How to Minimize Bundle Size 

One example of an npm package you might install while working on a custom Block would be lodash, which provides helpers to work with JavaScript objects and arrays.If a large bundle size decreasing page speed were not a concern, you might install the entire lodash library in order to use a single function.

Instead, here are some recommendations to reduce bundle size.

Install just one function

In order to reduce bundle size, try installing only the method you need, for example isEqual:

npm install --save lodash.isequal

Then, use the following syntax in your custom Block’s JavaScript file:

import isEqual from 'lodash.isequal'

Compare this to installing the entire lodash library:

npm install --save lodash

In this case, you could import the entire thing, but this will greatly increase bundle size:

import _ from 'lodash'

Avoid importing the entire library

Using the following syntax in your JavaScript file is not an improvement:

import { isEqual } from 'lodash'

With this syntax, you still import the full lodash library, even though you only want the isEqual function. This will load the entire library and then extract the one function to the current scope. To get only the isEqual function and thereby reduce the size of your bundle, you need to use the other syntax.

An alternative for lodash

With lodash specifically, there is also the lodash-es package:

npm install --save lodash-es

This package splits lodash into separate ES6 modules and allows the following syntax:

import { isEqual } from 'lodash-es'

This may be the most convenient option for this particular library.

Avoiding dependencies is the best

Of course, not using lodash at all would result in an even further decrease in bundle size. The less dependencies you have, the smaller your custom Block.

For further information on minimizing bundle size, please see the article Keeping Your Site Fast in the Element Platform Documentation. That article discusses how if you import lodash in each of 5 custom Blocks, you can end up with a page in the VOLT Store loading 5 different copies of lodash, in each custom Block’s bundle. The article suggests adding the script to the <head> element of your VOLT Store using the addScript function, which will be discussed in the next section of this article. Doing so would be instead of including the lodash dependency in your bundle — i.e. using addScript in your /src/Block.js instead of running npm install lodash:

props.utils.addScript("https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js")

Unfortunately, doing so will break Google AMP compatibility, because you are now referring to a third-party script.

The better solution is to individually install the specific modules you need. Think about bundle size before adding too many dependencies to your custom Block. Please also consider the article How To Fetch Data Fast in the Element Platform Documentation. It has relevant tips about how to use asynchronous requests in Element when building custom Blocks, such as when accessing category or product data.

If you still need to load third-party content, here are some best practices for doing so effectively. Remember that third-party scripts cannot be used on the AMP version of your VOLT Store.

Where to Load Your Third-Party Scripts

When building a custom Block using Element, you can load a third-party script in the /src/getDataProps.js file or the /src/Block.js file. This article assumes you know the basics of building a custom Block using Element. For a refresher, you can refer to 15-minute article “Building An Element Page Tutorial” in the Element Platform Documentation or view the YouTube playlist “Element Tutorial | VOLT Learning Center” (27 minutes total).

Before getting started adding the third-party script, determine how your third-party script will interact with page content:

  • If a script doesn’t need to immediately interact with something on your page — for example, if it is below the fold — load it in /src/getDataProps.js using the Element addScript util function, part of the Element utils (utilities).
  • If a script needs to interact with page content as soon as it loads — for example, if it is above the fold — add it in your /src/Block.js file using the addScript util in a React function that executes on mount like componentDidMount() or useEffect(). This will ensure that the third-party script loads as quickly as possible.

The next section explains these two methods to detail.

If a script can wait to load

When a script can wait to load, you will want to edit your /src/getDataProps.js file to include a call to the addScript util function, available as utils.addScript("URL.js"):

export const getDataProps = (utils, props) =>
Promise.resolve(
utils.addScript(
"https://cdn.jsdelivr.net/algoliasearch/3/algoliasearchLite.min.js",
false, // optional boolean: include the defer attribute
false // optional boolean: include the async attribute
)
)

The content of the Block does not have to wait on loading the script when called from the /src/getDataProps.js file.

This will let your page load before the third-party script itself loads.

A useful example of scripts waiting to load would be loading advertisements. There is no point in having ads before the content is even displayed.

If your third-party script needs to be live as soon as the page loads, you will need to call addScript directly from your custom Block.

If a script needs immediate interactivity

To load a script in a Block as soon as the page’s content loads, you need to load it into the custom Block itself.

Edit the /src/Block.js file to include a call to props.utils.addScript:

import React, { useEffect } from "react"
import { css, StyleSheet } from "aphrodite/no-important"
import { getStyles } from "./getStyles"
import { defaultConfig } from "./configs"

const Block = (props) => {
// React's Effect Hook (useEffect) runs a function when the Block is rendered
useEffect(
() =>
// Add a link to the third-party script
props.utils.addScript(
"https://cdn.jsdelivr.net/algoliasearch/3/algoliasearchLite.min.js",
),
[]
)

// The second parameter is an empty array, [], to make useEffect run just once
const classes = StyleSheet.create(getStyles(props))
return <h1 className={css(classes.example)}>{props.text}</h1>
}

Block.defaultProps = defaultConfig
export default Block

Note the slight difference in syntax: props.util.addScript("URL.js") in the /src/Block.js file instead of utils.addScript("URL.js") in the /src/getDataProps.js file. For more details, please refer to Block Utils in the Element Platform Documentation.

The custom Block has the same effect of loading the third-party script through an added <link> tag to the <head> element of the page.

The difference is that loading the script from /src/Block.js loads it immediately, before the content, while loading it from /src/getDataProps.js will load it after the content.

Examining React’s Effect Hook

The custom Block code above calls the addStyle function inside a function called useEffect(), which is a React Hook called the Effect Hook. For those familiar with React’s class-based lifestyle methods, the Effect Hook is similar to componentDidMount() and componentDidUpdate() by default. The code in the useEffect block is run one time, when the Block loads (mounts), and then again every time the Block updates (renders) for any reason.

However, passing an empty array [ ] to useEffect as its second argument causes the code in the Effect Hook to only run only once, when the Block first loads. Without the Effect Hook, the third-party script would get added to the <head> tag repeatedly, everytime the Block refreshes its display (on every render). If you had multiple custom Blocks all referencing a single third-party script, only one Block would actually need to load the third-party script using addScript, as mentioned previously. Again, because this method modifies the <head> tag, this method of loading third-party scripts (adding a <link> with the addScript function) is not compatible with Google AMP.

Loading a Custom Stylesheet in a Custom Block

There is also the Element addLink util function, which loads a third-party stylesheet into your custom Block by adding a <link> to the <head> element. You could use the addLink call in either /src/getDataProps.js as utils.addLink("URL.css") or in /src/Block.js as props.addLink("URL.css"). For an example of loading a stylesheet using the Element addLink util function, please refer to the previous article discussing using custom font faces in a Block. Note that neither addScript nor addLink are compatible with Google AMP versions of your pages. Furthermore, you are limited to a total of 50KB of CSS with AMP pages. That is why it is recommended to use the built-in tools to style the CSS in your custom Block. For information, please take a look at the article Styling Your Block With CSS in the Element Platform Documentation.

How to Load Third-Party Scripts in VOLT’s Site Designer

You cannot load third-party scripts in VOLT’s Site Designer. This is by design, so that Site Designer is responsive when editing and previewing themes for your VOLT Store. If you need to provide a visual placeholder for any script-generated content while working in VOLT’s Site Designer, you can consider passing the isRendering util in /src/getDataProps.js/ into your block via the data prop key.

The isRendering prop key allows you to display content conditionally. An undefined value for isRendering indicates the Block is in VOLT’s Site Designer, but a true value indicates the Block is rendered by a live VOLT Store or a preview of a theme.

The documentation on isRendering in the Element Platform Documentation explains how to do so. First, you return the isRendering prop in the promise in /src/getDataProps.js:

export getDataProps({ isRendering }, props) => Promise.resolve({ isRendering })

This will make the isRendering prop available as props.data.isRendering in the /src/Block.js file. Note that third-party CSS files (stylesheets) will load in VOLT’s Site Designer, but not third-party scripts (JavaScript files). Thus, you may want to make a placeholder for the content that will be loaded by the third-party script (such as ads or a form) by using the isRendering prop. In other words, you can make a different version of your Block to display as a preview in VOLT’s Site Designer (when isRendering is undefined) compared to live stores and theme previews (when isRendering is true).

Testing the Impact

After you’ve completed integrating your third-party scripts, you can test your page on Google PageSpeed Insights to see how your site is scoring. For more information on this tool, please read “Google PageSpeed Insights Explained” or watch the video “Improving Google PageSpeed Scores.” You may also want to check out the AMP version of your VOLT Store 

To view the AMP version of your store, add /googleamp/ to your VOLT Store’s URL, such as:

https://my-volusion-store.myvolusion.com/googleamp/ 

You can double-check that the AMP version of your VOLT Store is working properly using Google's AMP testing tool or the AMP validator extension for Google Chrome. 

Conclusion

Adding third-party scripts to your VOLT Store gives you tons of options, but potentially at the cost of decreasing your Google PageSpeed Insights score, and possibly your search rankings. Element gives you power to add third-party stylesheets and scripts to your custom Blocks built for the VOLT Store, but it is better to avoid them when you can. If your site can work without third-party scripts or additional dependencies, it will be fastest. However, this is not always possible.

If they are necessary for the non-AMP version of your site (i.e. the desktop version), you can load them using the addScript util function, part of the built-in Element utils. There is a similar function for loading external stylesheets, called the addLink util function. Be aware that loading external scripts or stylesheets will break Google AMP compatibility, so you should avoid using them on the AMP version of your site.

When adding dependencies to your custom Block using npm install, be aware of the effects on bundle size.

To reduce bundle size, you may want to only install the specific functions you are using when working with a library like lodash.

Finally, remember that you will likely obtain the best performance using just what you can accomplish with the React and Aphrodite (CSS-in-JS) packages provided by Element.Often, there are helpful Stack Overflow answers and other resources when you search online for what you are trying to achieve by adding a third-party script.

Keeping Google PageSpeed scores green (90-100) is the best plan for your VOLT Store — because VOLT already has best-in-class SEO and the fastest load times in the industry.