Skip to content

Potential change to support lazy with SSR #1029

@sidhu663

Description

@sidhu663

Apologies if this is the wrong section for this but I'd like to help support lazy(...) with SSR. All the pieces seem to work fine as is

  • chunkextractor collects the used chunks
  • loadableReady on the client correctly preloads all the required scripts

except that when using lazy, it always throws the loadAsync promise on first render. This causes a suspense boundary to trigger even though technically the module is available and loaded. I took a quick look at the code and have a potential fix.

I wanted to get a gut-check on if this is a sensible approach. If so, I can make a more concrete PR. Basically, try to load sync and if the module is available, don't throw the promise. I've tested this with my setup and it works as desired: renders the full content during SSR and hydrates correctly without any flashing

diff --git a/packages/component/src/createLoadable.js b/packages/component/src/createLoadable.js
index 5a3da83..46d82cd 100644
--- a/packages/component/src/createLoadable.js
+++ b/packages/component/src/createLoadable.js
@@ -92,6 +92,18 @@ function createLoadable({
       const cacheKey = getCacheKey(props)
       let promise = cache[cacheKey]
 
+      if (!promise) {
+        try {
+          promise = Promise.resolve(ctor.requireSync(props))
+          promise.status = STATUS_RESOLVED
+          cache[cacheKey] = promise
+          return promise
+        } catch (e) {
+          // We didn't find the module synchronously, so we continue
+          // to load it asynchronously
+        }
+      }
+
       if (!promise || promise.status === STATUS_REJECTED) {
         promise = ctor.requireAsync(props)
         promise.status = STATUS_PENDING

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions