Open Daniel15 opened 4 years ago
The workaround I ended up using is to not render the lazy component at all during snapping. I created a custom useIsPrerendering
hook that returns true
for react-snap, true
for the first render from a regular user (to ensure the HTML is identical so it can properly rehydrate), and false
for subsequent renders:
import {useEffect, useState} from 'react';
export const isPrerendering = navigator.userAgent === 'ReactSnap';
/**
* React hook that returns `true` if prerendering or on initial render (to allow rehydration,
* or `false` otherwise).
*/
export function useIsPrerendering(): boolean {
const [isPrerender, setIsPrerender] = useState(true);
useEffect(() => {
if (!isPrerendering) {
setIsPrerender(false);
}
}, []);
return isPrerender;
}
Then in my code I just always return the loading state in that case:
const Chart = React.lazy(() => import('react-google-charts'));
export default function LazyChart(props: Props) {
const placeholder = <LoadingPlaceholder />;
const isPrerendering = useIsPrerendering();
if (isPrerendering) {
return placeholder;
}
return (
<React.Suspense fallback={placeholder}>
<Chart foo="bar" />
</React.Suspense>
);
}
function LoadingPlaceholder() {
return (
<div>
Loading...
</div>
);
}
Bug Report
Current Behavior I have a create-react-app based site that contains a page that lazily loads a library:
This is so the page loads immediately when navigated to (via React Router), but the library can be deferred as it's not critical to the page.
However, when I run
react-snap
, it inserts a<script>
tag for the lazy library directly in the<head>
of the resulting HTML:which results in the "lazy" chunk actually blocking render and loading before all the other JS. This seems unexpected, particularly given it doesn't have an
async
attribute, and kinda defeats the purpose of prerendering, as rendering of the HTML is now blocked by the loading of this JS file.Is that expected?
Reproducible demo Can provide if you say that this is unexpected behaviour
Expected behavior/code Looking for confirmation as to what should happen here.