【问题标题】:Angular Universal build hangs on prerendering page with API requestAngular Universal 构建挂在带有 API 请求的预渲染页面上
【发布时间】:2018-09-22 16:56:32
【问题描述】:

我正在开发一个基于angular universal starterpokeapi 的小型网络应用程序。由于我想要显示的很多数据实际上并没有改变,我想使用预渲染页面来减少对 API 的请求数量并提高性能。在我的示例中,我在我的应用程序的主页上放了一个口袋妖怪列表,我从 API 中检索到该列表。

export class HomeComponent implements OnInit {

    pokemon$: ReplaySubject<ResourceList> = new ReplaySubject<ResourceList>();

    constructor(private pokedexService: PokedexService, private state: TransferState) { }

    ngOnInit() {
        if (this.state.hasKey(STATE_KEY_POKEMON)) {
            this.pokemon$.next(this.state.get(STATE_KEY_POKEMON, {} as ResourceList));
        }
        else {
            this.pokedexService.getResourceByCategory(ResourceCategory.POKEMON)
                .subscribe((resourceList: ResourceList) => {
                    this.pokemon$.next(resourceList);
                    this.state.set(STATE_KEY_POKEMON, resourceList.results);
                });
        }
    }
}

当我让客户端呈现页面时,这可以正常工作。但是,当我尝试预渲染应用程序时,构建过程会挂起。由于我正在运行 API 的本地实例,因此我可以看到已发出请求并返回 200 状态。构建日志如下所示:

npm run build:prerender

> ng-universal-demo@0.0.0 build:prerender C:\Users\thijs\Development\pokedex universal\angular-universal-pokedex
> npm run build:client-and-server-bundles && npm run compile:server && npm run generate:prerender


> ng-universal-demo@0.0.0 build:client-and-server-bundles C:\Users\thijs\Development\pokedex universal\angular-universal-pokedex
> ng build --prod && ng run ng-universal-demo:server:production


Date: 2018-09-22T16:47:41.687Z
Hash: c49708f1ccb7e73e327a
Time: 8181ms
chunk {0} runtime.6afe30102d8fe7337431.js (runtime) 1.05 kB [entry] [rendered]
chunk {1} styles.34c57ab7888ec1573f9c.css (styles) 0 bytes [initial] [rendered]
chunk {2} polyfills.c174e4dc122f769bd68b.js (polyfills) 64.3 kB [initial] [rendered]
chunk {3} main.19481e4ceb7a5808fe78.js (main) 312 kB [initial] [rendered]

Date: 2018-09-22T16:47:50.816Z
Hash: ee7e30e1f9c277bb5cbf
Time: 5739ms
chunk {main} main.js (main) 38.2 kB [entry] [rendered]

> ng-universal-demo@0.0.0 compile:server C:\Users\thijs\Development\pokedex universal\angular-universal-pokedex
> tsc -p server.tsconfig.json


> ng-universal-demo@0.0.0 generate:prerender C:\Users\thijs\Development\pokedex universal\angular-universal-pokedex
> cd dist && node prerender

我完成预渲染构建的唯一方法是删除 Web 请求。我在想一定还有什么东西在后台运行。我尝试将我的 Observable 切换为 Promise,但这并没有改变任何东西。我错过了什么?

You can find my project on GitHub.

【问题讨论】:

  • 你找到解决办法了吗?

标签: angular typescript angular-cli angular-universal


【解决方案1】:

有点晚了,但如果有人遇到困难,这可能会有所帮助:

类似于上面关于等待宏任务完成的部分, 另一方面是平台不会等待微任务 在完成渲染之前完成。在 Angular Universal 中,我们有 修补了 Angular HTTP 客户端以将其变成一个宏任务,以确保 为给定的渲染完成任何所需的 HTTP 请求。然而, 这种类型的补丁可能不适用于所有微任务,因此 建议您对如何进行做出最佳判断。你 可以看代码参考Universal如何包装任务转 它变成一个宏任务,或者您可以简单地选择更改服务器 给定任务的行为。

基本上,如果您的 http 请求花费的时间过长,则预渲染会挂起并且无法完成。 websocket 连接也是如此(firebase 在 angular-firebase 中使用 WS)。 另外,当我遇到这个问题时,终端中没有错误输出,这使得调试非常困难。 我建议如下:

  • 仅在 CSR 上的 WS 连接,将它们包装在 if 语句中
  • 对于 SSR 或静态预渲染,请使用 rest api 端点并确保您没有收到任何超时错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-12
    • 2020-12-16
    • 2021-05-20
    • 2019-05-22
    • 2022-12-03
    • 1970-01-01
    • 2018-08-02
    • 1970-01-01
    相关资源
    最近更新 更多