javascript - React SSR 闪烁页面

标签 javascript reactjs webpack server-side-rendering react-loadable

我使用 React、react-router、@loadable/component 创建了一个项目。

现在我正在尝试将 SSR 添加到该项目中。 我使用react-router进行了服务器端渲染。

然后我添加了 @loadable/component 来导入所有页面组件:

import loadable from '@loadable/component';

const routersConfig = [
  {
    path: '/',
    component: loadable(() => import('./Home')),
    exact: true,
  },
  {
    path: '/2',
    component: loadable(() => import('./Home2')),
    exact: true,
  },
];

然后我添加了所有这部分代码:https://www.smooth-code.com/open-source/loadable-components/docs/server-side-rendering/

现在可以了。 但它可以解决问题:加载时内容会闪烁。

我如何理解页面的加载过程:

  1. 浏览器获取 SSR 生成的内容(网络选项卡中的第一个查询)
  2. 浏览器呈现内容(具有左边距和上边距)
  3. 浏览器从 html 下载两个输入点和 vendor (app.js、normalizer.js、vendor.js)
  4. 浏览器执行app.js和normalizer.js。左边距和上边距被删除。
  5. App.js 开始下载页面的 block - home.js。 此时内容消失
  6. 下载 home.js 后,内容会再次出现。

我拍摄了一个视频来说明这个过程。 (对于质量,我很抱歉,stackoverflow 禁止大小超过 2MB 的文件)。我正在限制网络速度来想象所有页面的下载过程。

enter image description here

我的问题是为什么内容消失了?如何解决?

我的代码

服务器.js

const sheetStyledComponents = new ServerStyleSheet();
  const sheetsJssRegistry = createSheetsRegistry();
  const statsFile = path.resolve(process.cwd(), './build-ssr/dist/loadable-stats.json');

  const extractor = new ChunkExtractor({
    statsFile,
    entrypoints: [
      'app',
      'normalize',
    ],
  });


  try {
    const client = ApolloSSRClient();

    const tree = (
      <ApolloProvider client={client}>
        <ApplyTheme sheetsRegistry={sheetsJssRegistry}>
          <StaticRouter location={req.url}>
            <Home />
          </StaticRouter>
        </ApplyTheme>
      </ApolloProvider>
    );

// there is combination of Apollo graphql, jss, styledComponent functions
    const body = await getMarkupFromTree({
      renderFunction: flow(
        sheetStyledComponents.collectStyles.bind(sheetStyledComponents),
        extractor.collectChunks.bind(extractor),
        renderToString
      ),
      tree,
    });

    const scriptTags = extractor.getScriptTags(); 
    // It isn't used yet
    const linkTags = extractor.getLinkTags(); 

    const styleTags = sheetStyledComponents.getStyleTags();

    const html = (await rawHtml)
      .replace(
        '</head>',
        ` 
          ${styleTags}
          <style type="text/css" id='jss-server-side-styles'>
              ${sheetsJssRegistry.toString()}
          </style>
          <script>
            window.__APOLLO_STATE__ = ${JSON.stringify(client.extract())};
          </script>
          ${scriptTags}
          </head>
        `
      )
      .replace('<div id="app"></div>', `<div id="app">${body}</div>`);


    res.send(html);

index.jsx

const SSRApp = (
  <ApolloProvider client={ApolloClient}>
    <ApplyTheme>
      <BrowserRouter>
        <App />
      </BrowserRouter>
    </ApplyTheme>
  </ApolloProvider>
);

loadableReady(() => (
  ReactDOM.hydrate(
    SSRApp,
    document.getElementById('app'),
  )
));

最佳答案

都是我的错。

水合版应用包含BrowserRouter -> Switch -> Router -> HomePage

SSR版本仅包含StaticRouter -> HomePage

因此,在渲染 SSR 版本后,React 删除了所有 DOM 并使用 Router 创建了新的 DOM。

关于javascript - React SSR 闪烁页面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57057720/

相关文章:

javascript - 创建一个获取每个数组项并整理它的 JavaScript 对象

javascript - 如何将对象转换为字符串

javascript - 网页包。是否可以进行入口点依赖导入?

Angular-CLI/Angular2 : Non-standard chars only load correctly in index. html,不在通过 ng serve 的组件中

css - webpack "OTS parsing error"加载字体

javascript - 输入按钮 onClick 移除最近的 div

javascript - 动态导入组件Vue

javascript - 无法读取 null 的属性 'props' - Reactjs

html - 如何在 ReactJS 中动态选择要渲染的元素

javascript - 按钮回调中的日志语句显示未定义