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

Angular应用初始化时如何加载本地/assets目录下的所有资源

在Angular初始化前预加载/assets全部资源的实现方案

核心思路

利用Angular的APP_INITIALIZER令牌,在应用启动初始化阶段执行资源预加载任务,确保所有/assets资源加载完成后再启动应用。


步骤1:创建资源预加载服务

实现一个服务来处理资源清单获取和批量加载逻辑:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({ providedIn: 'root' })
export class AssetPreloadService {
  constructor(private http: HttpClient) {}

  async preloadAssets(): Promise<void> {
    // 加载预定义的资源清单文件
    const resources = await this.http.get<string[]>('/assets/resources.json').toPromise();
    
    // 根据资源类型选择加载方式
    const loadPromises = resources.map(resource => {
      if (resource.match(/\.(png|jpg|jpeg|gif|svg)$/i)) {
        // 图片资源用Image对象加载
        return new Promise<void>((resolve, reject) => {
          const img = new Image();
          img.onload = () => resolve();
          img.onerror = () => reject(new Error(`加载资源失败: ${resource}`));
          img.src = resource;
        });
      } else {
        // 非图片资源(字体、JSON等)用Fetch API加载
        return fetch(resource).then(res => {
          if (!res.ok) throw new Error(`加载资源失败: ${resource}`);
        });
      }
    });

    // 等待所有资源加载完成
    await Promise.all(loadPromises);
  }
}

步骤2:配置APP_INITIALIZER

在根模块中注册初始化钩子,将预加载服务绑定到应用启动流程:

import { NgModule, APP_INITIALIZER } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http';
import { AssetPreloadService } from './asset-preload.service';
import { AppComponent } from './app.component';

// 初始化工厂函数,返回预加载任务的Promise
function initAppPreload(preloadService: AssetPreloadService) {
  return () => preloadService.preloadAssets();
}

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule, HttpClientModule],
  providers: [
    {
      provide: APP_INITIALIZER,
      useFactory: initAppPreload,
      deps: [AssetPreloadService],
      multi: true
    }
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

步骤3:维护资源清单(或自动生成)

手动维护清单

在/assets/resources.json中列出所有需要预加载的资源路径:

[
  "/assets/images/logo.png",
  "/assets/icons/menu.svg",
  "/assets/fonts/roboto.woff2",
  "/assets/data/app-config.json"
]

自动生成清单(可选)

写一个Node.js脚本,在构建前自动遍历/assets目录生成清单:

const fs = require('fs');
const path = require('path');

const assetsDir = path.join(__dirname, 'src/assets');
const resourceList = [];

// 递归遍历assets目录
function scanAssets(dir) {
  const files = fs.readdirSync(dir);
  files.forEach(file => {
    const fullPath = path.join(dir, file);
    const stats = fs.statSync(fullPath);
    if (stats.isDirectory()) {
      scanAssets(fullPath);
    } else {
      // 转换为应用内可访问的相对路径
      const relativePath = '/' + path.relative(assetsDir, fullPath).replace(/\\/g, '/');
      resourceList.push(relativePath);
    }
  });
}

scanAssets(assetsDir);
// 写入清单文件
fs.writeFileSync(path.join(assetsDir, 'resources.json'), JSON.stringify(resourceList, null, 2));

在package.json中添加构建前的执行脚本:

"scripts": {
  "generate-resources": "node generate-resources.js",
  "build": "npm run generate-resources && ng build"
}

注意事项

  • 资源加载失败会阻断应用启动,可在预加载方法中添加错误捕获逻辑,根据业务需求决定是否降级处理
  • 大型资源会增加启动时间,建议区分核心资源和非核心资源,仅预加载必要资源
  • 生产环境需注意资源路径的baseHref配置,避免路径错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 23:54:52