You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

升级至Angular 18后页面渲染超时及构建失败问题求助

Angular 18 组件渲染超时问题解决方案

问题现象

升级到Angular 18后,图片轮播组件出现以下异常:

  • 从其他页面导航进入组件时可正常运行
  • 直接刷新页面或执行ng build时,触发渲染超时错误,构建失败

错误信息如下:

[vite] Internal server error: Page /guide did not render in 30 seconds.
      at Timeout.<anonymous> (C:\Users\mbagi\Developer\xxx\angular-client\node_modules\@angular\build\src\utils\server-rendering\render-page.js:90:90)
      at Timeout.timer (c:/Users/mbagi/Developer/xxx/angular-client/node_modules/zone.js/fesm2015/zone-node.js:2320:21)
      at _ZoneDelegate.invokeTask (c:/Users/mbagi/Developer/xxx/angular-client/node_modules/zone.js/fesm2015/zone-node.js:459:13)
      at _ZoneImpl.runTask (c:/Users/mbagi/Developer/xxx/angular-client/node_modules/zone.js/fesm2015/zone-node.js:226:35)
      at invokeTask (c:/Users/mbagi/Developer/xxx/angular-client/node_modules/zone.js/fesm2015/zone-node.js:540:14)
      at Timeout.ZoneTask.invoke (c:/Users/mbagi/Developer/xxx/angular-client/node_modules/zone.js/fesm2015/zone-node.js:524:33)
      at Timeout.data.args.<computed> (c:/Users/mbagi/Developer/xxx/angular-client/node_modules/zone.js/fesm2015/zone-node.js:2301:23)
      at listOnTimeout (node:internal/timers:573:17)
      at process.processTimers (node: internal/timers:514:7)

问题原因

  1. SSR下的无限更新循环:Angular 18默认启用SSR,服务端渲染时setInterval会持续运行,不断更新img信号值,导致页面始终处于未稳定状态,触发30秒超时限制。
  2. 复现代码语法错误:复现步骤中imgs被错误定义为模板字符串而非数组,导致imgs.length为字符串长度,pointer持续递增,进一步加剧更新频率。

解决方案

1. 仅在客户端执行定时器

使用Angular的isPlatformBrowser工具,确保定时器只在浏览器环境启动,避免服务端渲染时持续执行。

2. 组件销毁时清理定时器

实现OnDestroy接口,在组件销毁时清除定时器,防止内存泄漏。

3. 修正数据结构错误

确保imgs是数组类型,而非字符串。

修正后的组件代码

import { Component, OnInit, signal, OnDestroy, Inject } from '@angular/core';
import { PLATFORM_ID } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';

@Component({
  selector: 'app-root',
  standalone: true,
  template: `
    @if(img(); as img){
      <img [src]="img" />
    }
  `,
  styles: '',
})
export class AppComponent implements OnInit, OnDestroy {
  imgs = [
    'https://cdn.pixabay.com/photo/2023/09/02/03/15/water-8228076_1280.jpg',
    'https://media.istockphoto.com/id/157482223/de/foto/water-splash.jpg?s=2048x2048&w=is&k=20&c=tovlRmZEzpSmlXEL9OH8iANIK2w16YQD8QDDtsmxs3U=',
    'https://media.istockphoto.com/id/157482222/de/foto/gefrorene-tropfen-wasser.jpg?s=2048x2048&w=is&k=20&c=ASd2SEWIz7EEiSQLeCdrf6zA-eR9ExAyFCzZLG1tXco='
  ];

  img = signal('');
  intervalId: any;
  pointer = 0;

  constructor(@Inject(PLATFORM_ID) private platformId: Object) {}

  ngOnInit(): void {
    this.img.set(this.imgs[0]);
    // 仅在浏览器环境启动定时器
    if (isPlatformBrowser(this.platformId)) {
      this.startImageRotation();
    }
  }

  startImageRotation(): void {
    this.intervalId = setInterval(() => {
      this.pointer = (this.pointer + 1) % this.imgs.length;
      this.img.set(this.imgs[this.pointer]);
    }, 1000);
  }

  ngOnDestroy(): void {
    // 清理定时器
    if (this.intervalId) {
      clearInterval(this.intervalId);
    }
  }
}

问题复现步骤

  • 创建新Angular项目:
ng new test
  • 将app.component.ts替换为以下代码(注意其中的imgs定义错误):
import { Component, OnInit, signal } from '@angular/core';

@Component({
  selector: 'app-root',
  standalone: true,
  template: `
    @if(img(); as img){
      <img [src]="img" />
    }
  `,
  styles: '',
})
export class AppComponent implements OnInit {
  imgs = `['https://cdn.pixabay.com/photo/2023/09/02/03/15/water-8228076_1280.jpg',
  'https://media.istockphoto.com/id/157482223/de/foto/water-splash.jpg?s=2048x2048&w=is&k=20&c=tovlRmZEzpSmlXEL9OH8iANIK2w16YQD8QDDtsmxs3U=',
  'https://media.istockphoto.com/id/157482222/de/foto/gefrorene-tropfen-wasser.jpg?s=2048x2048&w=is&k=20&c=ASd2SEWIz7EEiSQLeCdrf6zA-eR9ExAyFCzZLG1tXco=']`;

  img = signal('');
  intervalId:any;
  pointer=0;

  ngOnInit(): void {
    this.img.set(this.imgs[0]);
    this.startImageRotation();
  }

  startImageRotation(): void {
    this.intervalId = setInterval(() => {
      this.pointer = (this.pointer + 1) % this.imgs.length;
      this.img.set(this.imgs[this.pointer]);
    }, 1000);
  }
}
  • 启动开发服务:
ng serve

此时会触发渲染超时错误。

内容的提问来源于stack exchange,提问作者mbagiella

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 14:52:02