wsl2 中跑 Flowise 源码时,
pnpm build竟然会内存不足,第一次出现这个情况,于是就有个这个研究最后发现占用大部分内存的是
import { ChatMistralAI } from '@langchain/mistralai。
一、前置条件与适用场景
前置条件:
-
已安装 Node.js 和 TypeScript (
tsc) -
项目结构完整,且可正常编译
-
对 TypeScript 项目性能优化或排查崩溃有需求
适用场景:
-
编译速度异常慢
-
出现
JavaScript heap out of memory错误 -
想分析 TypeScript 编译过程(AST 构建、类型检查、代码生成)
-
需要找到具体耗时文件或复杂类型的定位方法
二、生成性能追踪文件
下执行以下命令:
npx tsc --generateTrace ./tsc-trace
说明:
-
npx:使用项目本地node_modules中的 TypeScript,避免版本冲突 -
tsc --generateTrace:开启性能追踪 -
./tsc-trace:输出追踪文件的目录(执行后会在当前目录创建tsc-trace文件夹)
可选命令:
NODE_OPTIONS="--max-old-space-size=8192" npx tsc --generateTrace ./tsc-trace
- 为 Node.js 提高内存上限,避免项目编译时内存不足
npx tsc --generateTrace ./tsc-trace --extendedDiagnostics
- 输出更详细的诊断信息,例如每个阶段的统计耗时、文件数量、类型实例化次数等
三、查看输出文件
生成目录 tsc-trace 下主要包含:
| 文件 | 作用 |
|---|---|
trace.json | 核心性能追踪文件,包含所有事件数据,Chrome 火焰图可直接加载 |
types.json | 辅助文件,记录项目中所有类型的 ID 和名称,可结合 trace.json 分析泛型耗时或类型实例化情况 |
四、在 Chrome 中加载并分析火焰图
-
打开 Chrome 浏览器
-
在地址栏输入
chrome://tracing回车 -
页面左上角点击 Load 按钮,选择
tsc-trace/trace.json文件,或直接将文件拖拽进去
概述:
-
时间轴 (Timeline):横向表示时间,纵向显示线程或类别
-
线程 (Thread):常见如
Renderer、Browser、GPU -
事件块 (Event Blocks):矩形宽度表示事件持续时间
-
支持缩放、筛选线程或事件类型
五、火焰图事件解读
火焰图中的事件大致可以分为顶层、主要阶段和详细事件。以下表格总结了常见核心事件及分析价值:
| 层级 | 事件名称 | 含义与作用 | 分析价值 & 诊断线索 |
|---|---|---|---|
| 顶层 | program | 整个编译任务,从开始到结束 | 宽度表示总构建时间,可作为性能基准 |
| 主要阶段 | createProgram | 准备阶段:查找源文件、读取配置、生成 AST | 宽度大可能说明文件多或磁盘 I/O 高 |
| 主要阶段 | check | 类型检查阶段:遍历代码、推断类型、检查错误 | 宽度大表示类型复杂度高或泛型使用密集 |
| 主要阶段 | emit | 输出阶段:生成 .js, .d.ts, .js.map 文件 | 宽度大可能说明 Source Map 或写入耗时 |
| 详细事件 | checkSourceFile | 单个源文件类型检查耗时 | 可定位慢文件,矩形越宽耗时越长 |
| 详细事件 | instantiateType / instantiateSignature | 泛型实例化,计算最终类型 | 泛型调用多、嵌套深会增加 check 阶段耗时 |
| 详细事件 | emitSourceFile | 单文件生成输出和 Source Map | 可定位单文件 emit 耗时 |
| 详细事件 | checkExpression | 表达式类型检查,如函数调用、对象字面量 | 宽度大表示类型推断耗时高,可能优化泛型或类型定义 |
实用建议:
-
先看顶层
program宽度,判断总构建时间 -
若
check阶段耗时长,可进一步分析checkSourceFile,定位慢文件 -
若
instantiateType/instantiateSignature占比高,可考虑优化复杂泛型 -
emit阶段慢时,可关注 Source Map 或文件写入优化