Loadable-components: Hydration of app in 5.13.0

Created on 1 Jul 2020  路  19Comments  路  Source: gregberge/loadable-components

馃悰 Bug Report

I just updated to the latest version of loadable-components in my project. On server app renders exactly as expected. When hydration is complete it looks like the app rendered two times. Issues happen only with ReactDOM.hydrate, if I just ReactDOM.render the app everything works as expected. On 5.12.0 hydrate works perfectly.

To Reproduce

I have tried to create a small repo but everything seems to work fine in it

Expected behavior

Same HTML on the server and on the client.

Link to repl or repo (highly encouraged)

See "To Reproduce".

Run npx envinfo --system --binaries --npmPackages @loadable/component,@loadable/server,@loadable/webpack-plugin,@loadable/babel-plugin --markdown --clipboard

Paste the results here:

## System:
 - OS: macOS 10.15.5
 - CPU: (8) x64 Intel(R) Core(TM) i7-4770HQ CPU @ 2.20GHz
 - Memory: 4.53 GB / 16.00 GB
 - Shell: 5.7.1 - /bin/zsh
## Binaries:
 - Node: 13.12.0 - /usr/local/bin/node
 - Yarn: 1.22.4 - /usr/local/bin/yarn
 - npm: 6.14.4 - /usr/local/bin/npm
 - Watchman: 4.9.0 - /usr/local/bin/watchman
## npmPackages:
 - @loadable/babel-plugin: 5.13.0 => 5.13.0
 - @loadable/component: 5.13.0 => 5.13.0
 - @loadable/server: 5.13.0 => 5.13.0
 - @loadable/webpack-plugin: 5.13.0 => 5.13.0

Most helpful comment

client+server 5.13.1 should fix the problem.

All 19 comments

Hey @yashok111 :wave:,
Thank you for opening an issue. We'll get back to you as soon as we can.
Please, consider supporting us on Open Collective. We give a special attention to issues opened by backers.
If you use Loadable at work, you can also ask your company to sponsor us :heart:.

it looks like the app rendered two times

Why do you think it renders twice?

It's more like route rendered two times. We have route-based code-splitting. I'm sorry for unclear description, I'm a bit sick right now.

It's how HTML looks like on server:
Screenshot 2020-07-01 at 12 02 06
It's after hydration:
Screenshot 2020-07-01 at 12 02 45

I can confirm this is occurring in my app too (with server, component and babel-plugin all at 5.13. I only observe the issue when my bundle is built with NODE_ENV=production, I do not see this otherwise.

If loadable/component and loadable/server are updated to 5.13 but loadable/babel-plugin remains at 5.12, then this issue disappears. I am not sure if this is a red-herring, but worth checking in your environment @yashok111.

I have seen such double ups in DOM elements when hydrate() has an SSR mismatch. Usually an error is shown, but with the production env these comments are stripped out.

@clgeoio thank you for your suggestion. I have downgraded the loadable/babel-plugin to 5.12.0 and the issue is disappeared. I have checked NODE_ENV=development and there are no hydrate errors reported in the console.

Good to hear.
I cannot be certain that downgrading loadable/babel-plugin with the others at 5.13 won't produce undesirable effects though.

That's very interesting. Sounds like some problems with hydration resulting a broken state - that's possible if generated HTML does not match.
However you are saying that no error with hydration are reported.

The other problem is that not matching babel version should not work as expected - some logic there got completely reversed.

Actually babel-plugin could be downgraded without any consequences, however that will nullify a few fixes made in between.

Anyway - look like everything is about this line - https://github.com/gregberge/loadable-components/blob/master/packages/component/src/createLoadable.js#L108

Could you try to find it in your own code and add some logging around - I am interested in difference between 12 and 13 version in terms of what it will loadSync

There are no hydrate errors with loadable/babel-plugin at 5.12 and others at 5.13. If loadable/babel-plugin on 5.13 there are warnings in the console.
Screenshot 2020-07-01 at 13 38 58

5.13:

console.log('test');
        console.log('options.ssr !== false ===> ', options.ssr !== false);
        console.log('ctor.isReady && ctor.isReady(props) ===> ', ctor.isReady, ctor.isReady(props));
        console.log('ctor.chunkName && LOADABLE_SHARED.initialChunks[ctor.chunkName(props)]) ===> ', ctor.chunkName, LOADABLE_SHARED.initialChunks[ctor.chunkName(props)])
        console.log(options.ssr !== false && ( // is ready - was loaded in this session
          ctor.isReady && ctor.isReady(props) || // is ready - was loaded during SSR process
          ctor.chunkName && LOADABLE_SHARED.initialChunks[ctor.chunkName(props)]))
        if (options.ssr !== false && ( // is ready - was loaded in this session
        ctor.isReady && ctor.isReady(props) || // is ready - was loaded during SSR process
        ctor.chunkName && LOADABLE_SHARED.initialChunks[ctor.chunkName(props)])) {
          console.log('loadSync');
          _this.loadSync();
        }

        return _this;

Screenshot 2020-07-01 at 14 31 19

looks like condition is always false.

5.12:

console.log('test');
         console.log('options.ssr !== false ===> ', options.ssr !== false);
          console.log('ctor.isReady ===> ', ctor.isReady);
          console.log('ctor.isReady(props) ===> ', ctor.isReady(props));
          if (options.ssr !== false && ctor.isReady && ctor.isReady(props)) {
            console.log('loadSync')
            _this.loadSync();
          }

          return _this;

Screenshot 2020-07-01 at 14 38 16

Ok. In this case please try to find the difference between server output and result of render (not hydrate)
That is the difference? What should be three instead of header?

@yashok111 yep, it all should be false, except the last condition. So what is LOADABLE_SHARED.initialChunks then?

oof... <script id="__LOADABLE_REQUIRED_CHUNKS__" type="application/json">[0,1,2,6,7,8,9,12]</script>, that's all internal numbers...

Recovery plan:

  • (server) expose used chunks names to fix the condition
  • (loadable) allow unsafe loadSync if extra information is not known.

LOADABLE_SHARED.initialChunks:

Screenshot 2020-07-01 at 18 22 08

Same problem for sample app https://github.com/gregberge/loadable-components/tree/master/examples/server-side-rendering
works well with "@loadable/babel-plugin": "5.12.0"

client+server 5.13.1 should fix the problem.

It would be awesome if someone will confirm that the issue got resolved.

The issue is resolved. Thank you @theKashey for fast hotfix!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

salzhrani picture salzhrani  路  3Comments

zzyxka picture zzyxka  路  7Comments

luishdz1010 picture luishdz1010  路  6Comments

yanv1991 picture yanv1991  路  4Comments

ghost picture ghost  路  4Comments