我使用 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/
现在可以了。 但它可以解决问题:加载时内容会闪烁。
我如何理解页面的加载过程:
- 浏览器获取 SSR 生成的内容(网络选项卡中的第一个查询)
- 浏览器呈现内容(具有左边距和上边距)
- 浏览器从 html 下载两个输入点和 vendor (app.js、normalizer.js、vendor.js)
- 浏览器执行app.js和normalizer.js。左边距和上边距被删除。
- App.js 开始下载页面的 block - home.js。 此时内容消失
- 下载 home.js 后,内容会再次出现。
我拍摄了一个视频来说明这个过程。 (对于质量,我很抱歉,stackoverflow 禁止大小超过 2MB 的文件)。我正在限制网络速度来想象所有页面的下载过程。
我的问题是为什么内容消失了?如何解决?
我的代码
服务器.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/