3

I'm working on a React webpage using the Gatsby framework and I'm doing continuous deployment using AWS while I get a good page speed value.

One of the improvement opportunities is Remove unused Javascript and it explains this:

Sorry, follow this link. I don't have 10 of reputation to post images :(

Sorry, follow this link. I don't have 10 of reputation to post images :( x2

This is the code where I'm creating the map (using @react-google-maps/api):

    useEffect(() => {
        const loadScriptByURL = (id, url, callback) => {
        const isScriptExist = document.getElementById(id);
        
        if (!isScriptExist) {
            let script = document.createElement("script");
            script.type = "text/javascript";
            script.src = url;
            script.id = id;
            script.onload = function () {
            if (callback) callback();
            };
            document.body.appendChild(script);
        }
        
        if (isScriptExist && callback) callback();
        }
        
        loadScriptByURL("recaptcha-key", `https://www.google.com/recaptcha/api.js?render=${SITE_KEY}`, function () {
        console.log("Script loaded!");
        });
    }, []);

This is the code where I'm calling recaptcha:

        <LoadScript
            googleMapsApiKey='...'>
            <GoogleMap
                mapContainerClassName={styles.mapSection}
                center={defaultProps.center}
                zoom={defaultProps.zoom}
                onUnmount={() => {}}
                onLoad={() => {}}>
                <Marker position={markerLocation} onClick={infoToggleOpen}>
                    ...
                </Marker>
            </GoogleMap>
        </LoadScript>

What's the most proper way (or the easiest one) to solve the Remove unused Javascript error for these plugins? How can I use React.lazy() or loadable-components (because I tried and it doesn't work for me) to solve this?

juansedo
  • 46
  • 1
  • 4

1 Answers1

0

Some comments aside:

  • With const isScriptExist = document.getElementById(id); you are pointing directly to the DOM while in React, you create and manipulate a virtual DOM (vDOM) to avoid high-performance actions for the browser like this. In addition, these kind of actions, outside the scope of React (without using hooks) may cause some odd behavior because you may be blocking React's hydration process.

    You can achieve the same effect using useRef hook, keeping the scope of React, refName.current (refName is your id where the ref should be applied) which hold exactly the same information as your document.getElementById.

  • As you said, the saved kB of the scripts are quite meaningless, especially the utils.js but it's a good point trying to improve them.

Using React.lazy is a way of loading (more) asynchronously the component to avoid an initial blocking requests for the browser, loading your components more efficiently. In your case:

// import <LoadScript> from 'somewhere';
import <GoogleMap> from 'somewherex2';
import React, { Suspense } from 'react';

const LoadScript = React.lazy(() => import('./LoadScript'));

const YourComponentName=()=>(
       <>
        <Suspense fallback={<div>Loading...</div>}>
          <LoadScript
              googleMapsApiKey='...'>
              <GoogleMap
                  mapContainerClassName={styles.mapSection}
                  center={defaultProps.center}
                  zoom={defaultProps.zoom}
                  onUnmount={() => {}}
                  onLoad={() => {}}>
                  <Marker position={markerLocation} onClick={infoToggleOpen}>
                    ...
                  </Marker>
              </GoogleMap>
          </LoadScript>
        </Suspense>
      </>
)

You will need to make some trials with the React.lazy and the imported component. Keep in mind that React allows you to use a fallback component (Suspense).

Ferran Buireu
  • 28,630
  • 6
  • 39
  • 67