【问题标题】:Preact Router doesn't render until async routes are resolvedPreact Router 在异步路由解决之前不会渲染
【发布时间】:2018-01-09 02:32:24
【问题描述】:

我有一个应用程序,它在服务器端渲染,然后在客户端渲染以添加功能,但是,虽然第一次有意义的绘制时间大约是 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 是从服务器发送的,然后被渲染。但是一旦客户端脚本被执行,&lt;div id="app"&gt;&lt;/div&gt; 就会被刷新,因为AsyncRoute 还没有加载,这意味着没有什么可以渲染,所以页面变白了。 AsyncRoute 加载后,&lt;div id="app"&gt;&lt;/div&gt; 终于有了内容,所以页面被重新渲染。

我的问题是,在解决所有动态导入之前,如何才能使路由器或应用程序不会在客户端(上图)上呈现?

注意:我不能简单地这样做:

import(path).then(render)

因为当我添加更多组件时,我将无法分辨要导入哪些路径,因此AsyncRoute 组件

【问题讨论】:

    标签: javascript html css preact server-side-rendering


    【解决方案1】:

    这里的关键是要知道你在服务哪个路径,并将它的包作为&lt;script defer&gt;放在head中,所以当preact被加载时(可能是通过script标签身体的底部),你的路径的 JS 被加载并且你的 div 不会变成空白。

    或者,换句话说,loadComponent 需要的脚本实际上在缓存中可用。

    【讨论】:

    • 请正确阅读问题。那不是我问的。你只是在回避这个问题。
    • 如果以这种方式出现,我感到非常抱歉。您能否分享一下您是如何在AsyncRoutes 上进行 SSR 的,因为 renderToString 基本上没有履行require.ensureSystem.import 的承诺就退出了
    • 我渲染初始视图所需的东西,并延迟加载其余部分,这意味着我不打算立即加载它,因此我可以获得非常快的第一次绘制(交互时间不太重要了,因为它是一个污点),然后我延迟加载初始块(称为主块),这反过来又延迟加载当前视图中交互所需的其他块。目前,使用 preact-router 模块,意味着一旦初始块加载(延迟),dom 清除并且屏幕变白,然后在其他需要的块加载后(import('chunk')),视图重新绘制(大约 2 秒后) )
    • 我想要的是,一旦初始块被延迟加载,我会等到使用require 动态导入的所有其他块,这是当前视图所必需的,然后再重新渲染。
    • 酷,我想我明白你在说什么。因此,当您进行 SSR 时,您首先会看到所有内容,然后当 AsyncRoute 获取文件时,在下载文件时内容变为空白。
    【解决方案2】:

    酷,我想我明白你在说什么。

    因此,当您进行 SSR 时,您首先会看到所有内容,然后当 AsyncRoute 获取文件时,在下载文件时内容变为空白。

    对吗?

    在这种情况下,我给你做了一个简单的演示:https://github.com/prateekbh/preact-async-ssr

    解决方案不是很干净(到目前为止,即使在 React 领域也找不到任何干净的解决方案),但这是我所做的:

    在删除 SSRed 标记之前,我将其保存在一个变量中,然后将其用作 AsyncRoute 中的加载器组件。详情在这里:https://github.com/prateekbh/preact-async-ssr/blob/master/client-routes/App/app.js#L25-L39

    如果这有帮助,请告诉我。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-04-18
      • 1970-01-01
      • 2016-05-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-16
      相关资源
      最近更新 更多