应紧盯耗时最长的三项:Resolving dependencies超2秒、Generating autoload files超800ms、Executing script post-install-cmd超1.5秒,它们是性能瓶颈的主要源头。

composer install --profile 输出里哪些行最值得盯
直接看耗时最长的几项,别被总时间带偏。重点不是“一共花了多久”,而是“哪一步突然卡住”。Resolving dependencies 超过 2 秒、Generating autoload files 超过 800ms、Executing script post-install-cmd 超过 1.5 秒,基本就是问题源头。
常见干扰项:Loading composer repositories 耗时高,大概率是镜像没生效或缓存损坏;Downloading packages 拖得久,先确认 repo.packagist 配置是否正确(必须含 type: "composer" 且 URL 末尾带 /),再跑 composer clear-cache。
注意:--profile 不显示子命令内部细节,比如某个 post-install-cmd 脚本里调用了 php artisan config:clear,它只会记成“执行脚本耗时 X 秒”,不会告诉你慢在 config 清理还是 cache 扫描。
为什么 Resolving dependencies 卡住,不是网速问题
它卡在 SAT 求解器暴力回溯版本约束,和网络无关。现象是日志停在 Resolving dependencies through SAT 后不动,或反复打印类似 Trying laravel/framework[10.42.0, ..., 10.42.3] 的尝试行。
这时候该做的是:
- 立即加
-vvv重跑:composer update -vvv --profile,看最后几行输出哪个包在反复被 reject - 用
composer why-not vendor/package:version精准定位冲突链,比如composer why-not spatie/laravel-backup:7.0 - 检查根
composer.json是否写了"conflict"或"require"与新包隐式矛盾(例如同时 requireguzzlehttp/guzzle:^7和^8)
Generating autoload files 变慢的三个真实原因
不是代码多,而是加载策略错了。90% 的慢 autoload 生成都来自这三类配置错误:
- 把
autoload-dev的 PSR-4 规则写进了顶层autoload,导致测试工具类也被扫进生产 classmap - 项目里存在未清理的旧包,其
composer.json声明了超宽泛的autoload.psr-4(如"": "src/"),实际只用其中几个类 - 启用了
--classmap-authoritative但没配--optimize-autoloader,结果 classmap 文件为空,运行时 fallback 到全盘扫描
验证方式:删掉 vendor/composer/autoload_classmap.php,再跑 composer dump-autoload -o,对比生成前后文件大小——如果仍只有几百字节,说明 classmap 没真正覆盖到核心类。
post-install-cmd 脚本慢,怎么快速判断是不是它
别急着改脚本,先隔离验证。临时注释掉 composer.json 里的 "scripts" 段,再跑 composer install --profile。如果 Executing script 行消失且总时间骤降,就坐实了。
常见坑点:
-
php artisan vendor:publish在无交互模式下会卡住等待用户选择,应加--force和--all -
phpunit --generate-configuration这类命令默认扫描整个tests/目录,大项目里可能触发数百次file_exists() - 某些包的脚本依赖环境变量(如
APP_ENV),CI 中未设会导致 fallback 到慢路径
真正要改的不是脚本内容,而是它的触发时机:生产部署用 --no-scripts,把发布、清缓存等操作拆到 CI 的独立步骤里,避免每次 install 都重跑。
所有耗时分析都基于一次干净安装。如果之前装过一半又中断,--profile 的数据会被残留缓存干扰,务必先 rm -rf vendor + composer clear-cache 再测。











