stereobooster / react-snap

👻 Zero-configuration framework-agnostic static prerendering for SPAs
MIT License
5.04k stars 391 forks source link

Page/animation flickering upon initial page load #406

Closed chriseickemeyerGH closed 4 years ago

chriseickemeyerGH commented 4 years ago

This isn't a react-snap only issue, it's an issue with prerendering in general but I still thought I'd file this issue. I have an app where a loading spinner fires before fetching data, and disappears after the data has been fetched. However, data flashes and then disappears quickly upon page load (on desktop only I believe), and then the loading spinner starts up. I've had a different app in the past with an opening animation, and a similar thing happened using a different prerendering package.

The page flickering does not happen using when using only JS apps without prerendering.

Any ideas why this happens or how to solve it?

Here's my app where this happens. View it on desktop to see the flickering. https://votertest-52c39.web.app/

stereobooster commented 4 years ago

You prerendered it, HTML there. The React loads, and when it loads the first thing is does is... loading data. If you load data you draw spinner on the screen, so react erases all previous HTML and draws a spinner, later all data received and it draws page back. You need to save data with the page not only HTML or use react-prerendered-component (see readme).

chriseickemeyerGH commented 4 years ago

Didn’t see it was directly addressed in the Readme 🤦‍♂️

chriseickemeyerGH commented 4 years ago

Edit: Nvm, figured it out.

I'm a little bit confused on how to use react-prerendered-component. The example shown in the Readme is this:

import loadable from "@loadable/component";
import { PrerenderedComponent } from "react-prerendered-component";

const prerenderedLoadable = dynamicImport => {
  const LoadableComponent = loadable(dynamicImport);
  return React.memo(props => (
    // you can use the `.preload()` method from react-loadable or react-imported-component`
    <PrerenderedComponent live={LoadableComponent.load()}>
      <LoadableComponent {...props} />
    </PrerenderedComponent>
  ));
};

const MyComponent = prerenderedLoadable(() => import("./MyComponent"));

I assume this boilerplate goes above the initialization of the component, around import React from "react" and other top level imports?

Is MyComponent the only part of this to be used in the JSX?

Is LoadableComponent an already imported component, or is it part of the general boilerplate?

Am I importing MyComponent from it's relative src path? e.g. const MyComponent = prerenderedLoadable(() => import("../components/MyComponent"));, or is it just created within whatever component it is in and uses the content of LoadableComponent?

I'd very much appreciate an explanation how to use it properly.