1

I would like to trigger a dynamic import of a react component only after an image is loaded to prioritise first paint. The problem is, it's a context provider component and having some trouble as a result.

So I have a dynamic import here in the file auth.js:

   const AuthContextPreloader = hasWindow
   ? lazy(() => import("./AuthContextPreloader"))
   : null;

And I have an image here in a separate component:

   <img
      ref={() => hasWindow && imageLoaded()}
      className={styles.optionsImageImg}
      alt={"nav"}
      src={didLoad && thumb.jpg}
      type="image/jpeg"
    />

And once loaded I a send state up the component tree to hand down to AuthContextPreloader

    const imageLoaded = () => {
      setheroLoaded(true);
     };

Some pseudo-code to try and achieve this in auth.js:

  useEffect(() => {
    props.heroLoaded && **trigger the lazyload**;
  }, [props.heroLoaded]);

But totally unsure how to implement that. Thank you.

1 Answer 1

4

You should not be concerned about when your component will be loaded. Your concern should be when to render it. Something like that:

const AuthContextPreloader = hasWindow
  ? lazy(() => import("./AuthContextPreloader"))
  : null;

function ComponentWhereWouldBeRenderedAuthContextPreloader(props) {
  return props.heroLoaded ? <Suspense><AuthContextPreloader /> </Suspense> : null;
}

This way you will not consider yourself with internals, but will render your current application state.

Edit

From the comments it is clear that your concern not the component itslef, but it's large dependency.

In this case you can do something like this:


function ComponentWhereWouldBeRenderedAuthContextPreloader(props) {
  return props.heroLoaded ? <AuthContextPreloader /> : null;
}

function AuthContextPreloader(props) {
  let [dependencyState, setDependencyState] = useState("not_loaded");
  useEffect(function () {
    import("large-dependency")
      .then(function (module) {
        // return either default, or named exports that you need, or skip this step
        return module.default;
      })
      .then(function (dep) {
        // do something with dependency and then change state
        setDependencyState("loaded");
      });
  }, []);
  if (depenencyState === "not_loaded") return null;
  return ...;
}
Sign up to request clarification or add additional context in comments.

6 Comments

The reason I am concerned with when is because that component imports firebase (70kb+), that's why I am deferring the import.
But it will not be rendered until heroRendered
Also, if you concerned about firebase, you can load and initialize it dynamically in useEffect, so it would be imported only after component will render
@user1088793 do you need to import the entire firebase default module? Or have you considered using more selective imports?
@ezhikov this lazy loads the module by default regardless of the condition I believe..
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.