我有一个应用程序,它在服务器端渲染,然后在客户端上渲染以添加功能,但是,尽管第一次有意义的绘制时间约为 1000 毫秒,但一旦客户端脚本下载,页面就会变成白色,几秒钟后它再次渲染(客户端)。
经过一些调试,我意识到这是因为我正在这样做:
Preact.render(<App />, document.getElementById('root'));
其中应用是:
import { Component } from 'preact';
import { Router } from 'preact-router';
import AsyncRoute from 'preact-async-route';
export default class App extends Component {
handleRoute = e => {
this.currentUrl = e.url;
};
render() {
return (
<div id="app">
<Router onChange={ this.handleRoute }>
<AsyncRoute path="/" getComponent={() => import('../routes/portfolio').then(module => module.default)} />
</Router>
</div>
);
}
}
现在的问题是,html是从服务器发送的,然后呈现。但是,一旦执行客户端脚本,<div id="app"></div>
就会刷新,因为AsyncRoute
尚未加载,这意味着没有要呈现的内容,因此页面变为白色。加载AsyncRoute
后,<div id="app"></div>
最终具有内容,因此页面将重新呈现。
我的问题是,在解决所有动态导入之前,我怎样才能使路由器或应用程序不会在客户端(上图)上呈现?
注意:我不能简单地这样做:
import(path).then(render)
因为当我添加更多组件时,我将无法分辨要导入哪些路径,因此AsyncRoute
组件
这里的关键是知道你正在服务哪条路径并将其捆绑包作为<script defer>
放在头部,所以当 preact 被加载时(可能是通过正文底部的script
标签),你的路径的 JS 被加载并且你的div 不会变成空白。
或者,换句话说,loadComponent
需要的脚本实际上在缓存中可用。
很酷,我想我明白你在说什么。
因此,当您SSR时,您首先会看到所有内容,然后在AsyncRoute
获取文件时,内容在下载文件时变为空白。
对吗?
在这种情况下,我做了一个简单的演示:https://github.com/prateekbh/preact-async-ssr
该解决方案不是很干净(即使在 React 土地上到目前为止也无法找到任何干净的解决方案),但这是我所做的:
在删除 SSR 标记之前,我将其保存在变量中,然后将其用作 AsyncRoute 中的加载器组件。详情请见:https://github.com/prateekbh/preact-async-ssr/blob/master/client-routes/App/app.js#L25-L39
让我知道这是否有帮助。