prismic-gatsby icon indicating copy to clipboard operation
prismic-gatsby copied to clipboard

Lazy-load prismic-dom for usePrismicPreview

Open angeloashmore opened this issue 4 years ago • 5 comments

We can lazy-load prismic-dom in usePrismicPreview. This should reduce the common bundle size by code-splitting the library.

angeloashmore avatar Mar 15 '20 19:03 angeloashmore

Would you consider making the entire preview functionality lazy? For example, putting a configuration flag in options to disable all Prismic preview functionality and therefore avoid loading all preview dependencies.

I have a situation where I preview only on a staging site and never on production, so would set the flag differently in these two environments and save some bytes.

tony2nite avatar Apr 21 '20 15:04 tony2nite

Hi @tony2nite, definitely, I think it makes sense to allow splitting off previews completely. Thanks for the suggestion.

If usePrismicPreview and mergePrismicPreviewData are loaded using import(), it should already code-split and lazy load. This would need confirmation since I haven't tried that.

An extra plugin option to disable previews would need to do the following:

  • Disable writing the type paths file (details here)
  • Disable setting plugin options on window in gatsby-browser.js (details here)

I'd appreciate someone testing code splitting the preview hook + function and/or even a PR for disabling the bullet points above. Thanks!

angeloashmore avatar Apr 22 '20 19:04 angeloashmore

I went ahead and tested lazy loading mergePrismicPreviewData and it works a treat with code splitting. Here's the hook I wrote for my own pages:

/**
 * Prismic preview hook
 * @param {object} staticData Data object from Gatsby page
 */
export function usePreview(staticData) {
  const [data, setData] = useState(staticData);

  useEffect(async () => {
    if (window.__PRISMIC_PREVIEW_DATA__) {
      const { mergePrismicPreviewData } = await import(
        /* webpackChunkName: "gatsby-source-prismic" */ 'gatsby-source-prismic'
      );

      setData(
        mergePrismicPreviewData({
          staticData,
          previewData: window.__PRISMIC_PREVIEW_DATA__
        })
      );
    }
  }, []);
  return data;
}

Usage:

export default function MyPage({ data }) {
	const liveData = usePreview(data)
	...
}

Might be worth documenting that kind of pattern, since pulling in all ~30kb of the source for previews for every page is a gotcha.


Note: I'm working on the assumption that Gatsby code-splits routes anyway, so there's no need to lazy load usePrismicPreview on /preview. Pretty sure that's the case...

madeleineostoja avatar Apr 28 '20 00:04 madeleineostoja

@angeloashmore I'm just doing some performance improvement to my website and I noticed that the gatsby-plugin-prismic-preview is quite large - 106 KB Parsed and 29 KB zipped. I'm on the latest version of the plugins

Do you have any plans/advice on reducing this?

kb1995 avatar Sep 03 '21 17:09 kb1995

Hey @kb1995, yes, this is definitely something I will be looking at. The initial version was written to get it working. There are optimization we can make like lazy loading and using less dependencies.

For now, there isn't anything you can do in your project to reduce the bundle size but reducing the bundle size is a priority.

angeloashmore avatar Sep 03 '21 18:09 angeloashmore