I was checking the performance of one of my web sites using Page Speed and noticed it complained about assets loading slowly as well as the initial response time from the server being a bit long (500ms-700ms range). My first thought was that it might be the database queries being too slow. I quickly ruled that out (they all took in the vicinity of a few milliseconds).

Then I noticed Stripe was loading on each page load. This only happened in production hence I didn’t noticed it while developing the site. I tried disabling “prefetch” on links to the pricing page but that didn’t help. Stripe library was still being loaded on every page load. Apparently NextJS bundles libraries in this fashion, so looked into dynamically loading Stripe.

Previously I embedded Stripe as the documentation prescribes it:

import { loadStripe } from '@stripe/stripe-js';

const Price = () => {
  const { isLoading, error, getSession } = useStripeSession();

  const handleClick = async () => {
    const stripe = await loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY as string);

    const { response } = await getSession({ priceId });
    const sessionId = response?.id;

    if (stripe && sessionId) {
      await stripe.redirectToCheckout({ sessionId });
    }
  };

  return (
    <button onClick={handleClick} isLoading={isLoading}>Select</button>
  );
};

To avoid loading Stripe on every page load, I had to dynamically import it. This is how I did it:

const Price = () => {
  const { isLoading, error, getSession } = useStripeSession();

  const handleClick = async () => {
    const stripe = await (await import('@stripe/stripe-js')).loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY as string);

    const { response } = await getSession({ priceId });
    const sessionId = response?.id;

    if (stripe && sessionId) {
      await stripe.redirectToCheckout({ sessionId });
    }
  };

  return (
    <button onClick={handleClick} isLoading={isLoading}>Select</button>
  );
};

After pushing this to production, the initial load time dropped from around 500ms to 300ms and the page speed score increased to 100. Conclusion, server likely ran loadStripe on every page load increasing the page load load time. So be aware of this when using external libraries.

Disclaimer: The site runs on NextJS v. 13.0.6 and uses the experimental appDir.