Reputation: 93
The problem is that the website-specific components are quite large and therefore bloat up the code of the individual websites which don't use those specific components. This results for example in a bad lighthouse score (unused code) and bad user experience (longer loading times).
Here is a strongly simplified example component that displays a website specific svg (loaded via gatsby-plugin-react-svg
):
import React from "react";
import Site1 from "../../images/site1.svg";
import Site2 from "../../images/site2.svg";
import Default from "../../images/default.svg";
const Image = () => {
let staticImage = <Default />;
switch (process.env.GATSBY_SITE) {
case "site1":
staticImage = <Site1 />;
break;
case "site2":
staticImage = <Site2 />;
break;
default:
}
return (
<>{staticImage}</>
);
};
export default Image;
I guess/understand this won't work because GatsbyJS/React/Webpack (?) simply does not know what happens in this component and when to show which image.
I tried to use loadable components
to address this issue but had no success. This is the example code from above but with loadable components:
import React from "react";
import loadable from "@loadable/component";
const DynamicImage = loadable(async () => {
switch (process.env.GATSBY_SITE) {
case "site1":
return import("../../images/site1.svg");
case "site2":
return import("../../images/site2.svg");
default:
return import("../../images/default.svg");
}
});
const Image = () => {
return <DynamicImage />;
};
export default Image;
With this code, all three images are still loaded although only one is shown. I would expect that only the used/required image (or component in other cases) is loaded.
Upvotes: 2
Views: 266
Reputation: 31
this should work
import React, { lazy, Suspense } from "react";
const Site1 = lazy(() => import("../../images/site1.svg"));
const Site2 = lazy(() => import("../../images/site2.svg"));
const Default = lazy(() => import("../../images/default.svg"));
const Image = () => {
let StaticImage = Default;
switch (process.env.GATSBY_SITE) {
case "site1":
StaticImage = Site1;
break;
case "site2":
StaticImage = Site2;
break;
default:
}
return (
<Suspense fallback={<div>Loading...</div>}>
<StaticImage />
</Suspense>
);
};
export default Image;
Upvotes: 0
Reputation: 14844
Did you try with the React.lazy
function?
const Github = React.lazy(async () => ({
default: (await import("./github.svg")).ReactComponent,
}));
const Google = React.lazy(async () => ({
default: (await import("./google.svg")).ReactComponent,
}));
const DynamicImage = () => {
<React.Suspense fallback={<div>Loading...</div>}>
{if(CONDITION) && <Github />}
{if(OTHER_CONDITION) && <Google />}
</React.Suspense>
};
See an example here:
Upvotes: 1