Skip to content

Commit 0ca2c1f

Browse files
committed
perf(profile): 优化启动性能,精简核心模块并延长代理缓存
- 根据平台条件化同步加载的核心模块,Windows 移除 test/env 依赖 - 代理自动检测缓存时间从 5 分钟延长至 30 分钟 - 更新延迟加载防护栏测试以匹配新的核心模块集合 - 更新性能基线文档,启动时间显著降低
1 parent 210c79c commit 0ca2c1f

6 files changed

Lines changed: 41 additions & 25 deletions

File tree

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
## 1. 核心模块列表精简
22

3-
- [ ] 1.1 修改 `core/loadModule.ps1`:将 `$coreModules` 改为平台条件化列表(Windows: 去掉 test+env,Linux/macOS: 去掉 test)
4-
- [ ] 1.2 修改 `Debug-ProfilePerformance.ps1` Phase 3:同步核心模块加载逻辑与 loadModule.ps1 一致
3+
- [x] 1.1 修改 `core/loadModule.ps1`:将 `$coreModules` 改为平台条件化列表(Windows: 去掉 test+env,Linux/macOS: 去掉 test)
4+
- [x] 1.2 修改 `Debug-ProfilePerformance.ps1` Phase 3:同步核心模块加载逻辑与 loadModule.ps1 一致
55

66
## 2. 代理缓存 TTL 延长
77

8-
- [ ] 2.1 修改 `features/environment.ps1``Invoke-WithCache``-MaxAge``[TimeSpan]::FromMinutes(5)` 改为 `[TimeSpan]::FromMinutes(30)`
9-
- [ ] 2.2 修改 `Debug-ProfilePerformance.ps1` Phase 4 proxy-detect:同步缓存 TTL 为 30 分钟
8+
- [x] 2.1 修改 `features/environment.ps1``Invoke-WithCache``-MaxAge``[TimeSpan]::FromMinutes(5)` 改为 `[TimeSpan]::FromMinutes(30)`
9+
- [x] 2.2 修改 `Debug-ProfilePerformance.ps1` Phase 4 proxy-detect:同步缓存 TTL 为 30 分钟
1010

1111
## 3. Pester 防护栏更新
1212

13-
- [ ] 3.1 更新 `tests/DeferredLoading.Tests.ps1`:核心模块集合从 6 个改为 4 个(`os``cache``proxy``wrapper`),移除 `test``env` 的函数从同步路径白名单
13+
- [x] 3.1 更新 `tests/DeferredLoading.Tests.ps1`:核心模块集合从 6 个改为 4 个(`os``cache``proxy``wrapper`),移除 `test``env` 的函数从同步路径白名单
1414

1515
## 4. 文档与验证
1616

17-
- [ ] 4.1 更新 `profile/README.md`:核心模块列表说明 + 性能基线数据
18-
- [ ] 4.2 运行 `pnpm qa` 验证全部测试通过
17+
- [x] 4.1 更新 `profile/README.md`:核心模块列表说明 + 性能基线数据
18+
- [x] 4.2 运行 `pnpm qa` 验证全部测试通过

profile/Debug-ProfilePerformance.ps1

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ if ($Phase -eq 2) {
160160

161161
$sw.Restart()
162162

163-
# 3.1 loadModule.ps1 — 加载 6 个核心 psutils 子模块 + PSModulePath + OnIdle 注册
163+
# 3.1 loadModule.ps1 — 加载核心 psutils 子模块(平台条件化) + PSModulePath + OnIdle 注册
164164
$loadModuleScript = Join-Path $profileRoot 'core/loadModule.ps1'
165165
. $loadModuleScript
166166
Lap '3.1-loadModule (core psutils + OnIdle)'
@@ -217,7 +217,7 @@ if (-not $SkipProxy) {
217217
try {
218218
$proxyState = Invoke-WithCache `
219219
-Key "proxy-auto-detect" `
220-
-MaxAge ([TimeSpan]::FromMinutes(5)) `
220+
-MaxAge ([TimeSpan]::FromMinutes(30)) `
221221
-CacheType Text `
222222
-ScriptBlock {
223223
Set-Proxy -Command auto

profile/README.md

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,14 @@ profile.ps1
3939
├── Phase 2: mode-decision (~90ms)
4040
│ 判定 Full / Minimal / UltraMinimal 模式
4141
42-
├── Phase 3: core-loaders (~290ms)
43-
│ ├── 同步加载 6 个核心 psutils 子模块
42+
├── Phase 3: core-loaders (~200ms)
43+
│ ├── 同步加载核心 psutils 子模块(Windows 4 个 / Linux 5 个)
4444
│ ├── PSModulePath 兜底(自动发现)
4545
│ ├── 加载用户别名配置
4646
│ └── 注册 OnIdle 事件(延迟全量加载)
4747
48-
└── Phase 4: initialize-environment (~600ms)
49-
├── 代理自动检测(缓存 5 分钟)
48+
└── Phase 4: initialize-environment (~350ms)
49+
├── 代理自动检测(缓存 30 分钟)
5050
├── UTF-8 编码设置
5151
├── 工具初始化(starship, zoxide, fnm, sccache)
5252
└── 别名注册
@@ -245,14 +245,20 @@ Register-EngineEvent -SourceIdentifier PowerShell.OnIdle -MaxTriggerCount 1 -Act
245245

246246
如果你的代码在启动期间(Initialize-Environment 执行时)被调用,需要的 psutils 函数必须在核心模块中。
247247

248-
当前核心模块(`core/loadModule.ps1` 第 1 层同步加载):
248+
当前核心模块(`core/loadModule.ps1` 第 1 层同步加载,按平台条件化):
249+
250+
**全平台:**
249251
- `os.psm1``Get-OperatingSystem`, `Test-Administrator`
250252
- `cache.psm1``Invoke-WithCache`, `Invoke-WithFileCache`
251-
- `test.psm1``Test-EXEProgram`
252-
- `env.psm1``Sync-PathFromBash`, `Add-EnvPath`
253253
- `proxy.psm1``Set-Proxy`
254254
- `wrapper.psm1``Set-CustomAlias`, `Get-CustomAlias`
255255

256+
**仅 Linux/macOS 额外加载:**
257+
- `env.psm1``Sync-PathFromBash`, `Add-EnvPath`
258+
259+
**已移出同步路径(通过 OnIdle 全量加载覆盖):**
260+
- `test.psm1``Test-EXEProgram` 已被 `Get-Command` 批量检测替代
261+
256262
**⚠️ 禁止在同步路径中调用非核心模块函数**(如 `Get-Tree``Register-FzfHistorySmartKeyBinding`),否则会触发 PSModulePath 自动导入 psutils 全量模块(~600ms 回退)。延迟加载防护栏会在 `POWERSHELL_PROFILE_TIMING=1` 时检测并警告。
257263

258264
### 修改验证流程
@@ -277,7 +283,7 @@ pnpm qa
277283

278284
| 平台 | 总耗时 | initialize-environment |
279285
|------|--------|----------------------|
280-
| Windows | ~1150ms | ~600ms |
281-
| Linux | ~1100ms | ~850ms(含 PATH 同步 + fnm) |
286+
| Windows | ~750ms | ~350ms |
287+
| Linux | ~550ms | ~200ms |
282288

283289
如果总耗时超过基线 200ms 以上,使用 `Debug-ProfilePerformance.ps1` 定位具体步骤。

profile/core/loadModule.ps1

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,17 @@ $psutilsRoot = Join-Path $moduleParent 'psutils'
33
$moduleManifest = Join-Path $psutilsRoot 'psutils.psd1'
44
$modulesDir = Join-Path $psutilsRoot 'modules'
55

6-
# ── 第 1 层:同步加载核心子模块(仅 profile 启动路径必需的 6 个) ──
6+
# ── 第 1 层:同步加载核心子模块(仅 profile 启动路径必需的) ──
77
# 使用 Import-Module 逐个加载(.psm1 不支持 dot-source,必须走模块系统)
8-
# 加载顺序按依赖关系:os → cache(依赖 os) → test → env → proxy → wrapper
9-
$coreModules = @('os', 'cache', 'test', 'env', 'proxy', 'wrapper')
8+
# 加载顺序按依赖关系:os → cache(依赖 os) → [env 仅 Linux/macOS] → proxy → wrapper
9+
# - test.psm1 已不在同步路径使用(Phase 4 用 Get-Command 替代 Test-EXEProgram)
10+
# - env.psm1 仅 Linux/macOS 需要(Sync-PathFromBash),Windows 上延迟到 OnIdle
11+
$coreModules = if ($IsWindows -or $env:OS -eq 'Windows_NT') {
12+
@('os', 'cache', 'proxy', 'wrapper')
13+
}
14+
else {
15+
@('os', 'cache', 'env', 'proxy', 'wrapper')
16+
}
1017
foreach ($mod in $coreModules) {
1118
$modPath = Join-Path $modulesDir "$mod.psm1"
1219
try {

profile/features/environment.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ function Initialize-Environment {
150150
# 自动检测代理(缓存 5 分钟避免每次 profile 加载都做 TCP 探测)
151151
if (-not $SkipProxy) {
152152
try {
153-
$proxyState = Invoke-WithCache -Key "proxy-auto-detect" -MaxAge ([TimeSpan]::FromMinutes(5)) -CacheType Text -ScriptBlock {
153+
$proxyState = Invoke-WithCache -Key "proxy-auto-detect" -MaxAge ([TimeSpan]::FromMinutes(30)) -CacheType Text -ScriptBlock {
154154
Set-Proxy -Command auto
155155
$result = if ($env:http_proxy) { 'on' } else { 'off' }
156156
return $result

tests/DeferredLoading.Tests.ps1

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ Set-StrictMode -Version Latest
55
延迟加载防护栏 — 静态 Pester 测试
66
.DESCRIPTION
77
扫描 profile 同步路径文件中的 Get-Command -Name 调用,验证引用的函数名
8-
属于 6 个核心子模块的导出函数集合,防止 PSModulePath 自动导入 psutils 全量模块。
8+
属于核心子模块的导出函数集合,防止 PSModulePath 自动导入 psutils 全量模块。
9+
核心模块为平台最小集:os、cache、proxy、wrapper(test 和 env 已移出同步路径)。
910
#>
1011

1112
Describe '延迟加载防护栏' {
@@ -14,8 +15,10 @@ Describe '延迟加载防护栏' {
1415
$script:ProfileRoot = Join-Path $script:ProjectRoot 'profile'
1516
$script:PsutilsModulesDir = Join-Path $script:ProjectRoot 'psutils' 'modules'
1617

17-
# 10.1: 收集 6 个核心子模块的导出函数列表
18-
$script:CoreModuleNames = @('os', 'cache', 'test', 'env', 'proxy', 'wrapper')
18+
# 10.1: 收集核心子模块的导出函数列表
19+
# 核心模块为平台最小集(test 已被 Get-Command 替代,env 仅 Linux 需要)
20+
# 测试使用最严格的白名单(Windows 集合),确保同步路径不依赖 test/env
21+
$script:CoreModuleNames = @('os', 'cache', 'proxy', 'wrapper')
1922
$script:CoreFunctions = [System.Collections.Generic.HashSet[string]]::new(
2023
[System.StringComparer]::OrdinalIgnoreCase
2124
)

0 commit comments

Comments
 (0)