Lazy loaded image
Angular性能调优指南:优化打包体积
Words 1791Read Time 5 min
2025-7-3
2025-7-3
type
status
date
slug
summary
tags
category
icon
password
👉
在当今快速发展的 Web 生态中,Angular 作为一款强大的前端框架,被广泛用于构建复杂且功能丰富的大型应用。然而,随着业务需求的增长和第三方依赖的引入,应用的打包体积可能会悄然膨胀,导致首屏加载时间变长、用户体验下降。对于开发者而言,如何在不牺牲功能的前提下优化打包体积,已成为提升 Angular 应用性能的核心挑战之一。
本文将利用 Angular 的一些性能特性来将应用程序拆分成更小的 chunk,分别是:
  • 独立组件懒加载 (Standalone lazy-loading)
  • 局部模板加载 (Partial template loading)
通过这两种特性,可以帮助你打造更快、更轻量的现代 web 应用。

收集关键指标数据

在优化应用程序性能时,最忌讳的是缺乏数据支持,仅凭直觉或试错来进行优化。
第一步应当是收集关键指标数据。这里推荐使用 source-map-explorer 工具包来生成分析报告。
首先需要安装工具包:
然后在 package.json 中添加分析脚本:
简单解释下这个脚本的执行流程:
  1. 执行生产环境构建(保留 source map)
  1. 基于构建结果生成可视化分析报告
👉
建议将此脚本添加到项目中,以便随时生成打包文件的空间占用分析。
运行脚本后生成的报告将展示:
  • 各 JavaScript 模块的磁盘空间占用比例
  • 第三方库和 Angular 组件的具体占比情况
  • 可优化的高占用模块清单
notion image
👉
报告中显示的是未压缩文件大小,实际生产环境中的压缩后体积会显著减小。
通过分析报告,我们可以识别出:
  1. 可进行懒加载的组件或功能模块
  1. 不常用但体积较大的依赖库(如 PDF 生成、复杂图表等)
  1. 重复引入或可优化的代码片段
这些发现将为后续的代码分割和性能优化提供明确依据。

实现应用全懒加载 (Fully Lazy-Loaded)


现在你已经知道了应用中哪些部分体积最大,下一步就是尽可能让你的应用实现全懒加载。
理想情况下,应用的每一个页面都应该被拆分成独立的 bundle 进行加载。那么,如何实现这种状态呢?
当前最佳方案是利用 Angular 的独立组件(Standalone Components)带来的简化懒加载功能。
接下来我们来看一下如何使用独立组件将路由中的一个页面轻松改造成懒加载模式。
以下是一个当前未启用懒加载的路由配置示例:
👉
如果你还在使用传统的 NgModule 组件模式,要实现这个界面的懒加载会相当繁琐,建议先迁移到独立组件。
要让这个页面变成懒加载,我们只需将 component 替换为 loadComponent,像这样:
就这么简单!
现在,这个路由就变成了懒加载模式。WatchCourseComponent 组件及其所有依赖项都将从主包 (main bundle) 中移除。
如果这个页面需要依赖重量级的库(比如 PDF 处理库或图表库),那么所有这些重量级依赖现在都会从你的主应用包中剥离出去,只在用户真正访问该界面时才按需加载。
现在,你可以回到你的路由配置中,在所有容器页面的路由配置上应用 loadComponent。这样,你就能拥有一个 “全懒加载”的应用,其中每一个主要页面都拥有自己独立的包。
此时,你的主包 (main bundle) 将主要包含 Angular 框架本身,几乎不包含其他内容,特别是那些重量级的第三方依赖库。
这本身就应该能显著提升你的应用初始加载性能。 但我们的优化旅程,还能更进一步!

使用 @defer 实现条件性模板延迟加载

现在让我们介绍另一种性能优化技术——它类似于路由懒加载,但作用在更细粒度的模板层面。
回顾当前代码,我们已经对 WatchCourseComponent 实现了路由级懒加载:
但假设这样一个场景:WatchCourseComponent 作为课程播放器,需要支持多种课程类型:
  • 音频课程(audio lessons)
  • 数字下载(digital downloads)
  • 测验评估(assessments)
这些功能都属于同一个课程播放界面。然而,如果某个课程仅包含视频课时,加载音频课件的代码就完全多余了。
理想情况下,音频课件的代码应该仅在用户点击音频课时才按需加载,而非提前加载。这样可避免加载用户当次会话中根本不会使用的代码!
但当前组件只能整体加载,无法实现部分加载。因此我们需要模板层面的条件性延迟加载机制。
这正是 Angular 强大的 @defer 功能的用武之地:
工作机制解析:
  1. @defer 会将代码块内的内容拆分为独立包(类似路由懒加载)
  1. when 条件触发时,才加载 <audio-player> 相关代码
  1. @if 控制组件渲染时机,与 @defer 配合实现精准按需加载
效果对比:
优化前
优化后
音频播放器代码包含在 WatchCourseComponent 主包中
音频播放器被拆分为独立包
即使用户不访问音频课也会加载
仅当用户打开音频课时才加载

性能优化完整路线图

简单总结一下,Angular 应用性能调优的核心步骤如下:
  1. 量化分析
    1. 使用 source-map-explorer 等工具生成包体积报告,精准定位性能瓶颈
  1. 路由级懒加载
    1. 迁移至独立组件(Standalone Components),全量启用 loadComponent 实现全界面懒加载
      → 主包仅保留 Angular 框架和基础依赖
  1. 模板级懒加载
    1. 对复杂组件使用 @defer 实现条件性模块加载
      → 进一步剥离非核心依赖(如图表/PDF等重型库)
如果要保证持续优化,可以在每轮优化后重新生成包体积报告,验证效果并定位新瓶颈,形成闭环优化流程。
上一篇
前端架构实战:构建可扩展的插件化系统
下一篇
2025年应该怎样初始化 Angular 项目