繁体   English   中英

Angular Universal 构建挂在带有 API 请求的预渲染页面上

[英]Angular Universal build hangs on prerendering page with API request

我正在开发一个基于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,但这并没有改变任何东西。 我错过了什么?

你可以在 GitHub 上找到我的项目

有点晚了,但如果有人挣扎,这可能会有所帮助:

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM