生产环境类加载慢主因是未启用Composer优化模式,需运行composer install --no-dev --optimize-autoloader生成静态classmap;同时须配置OPcache预加载并验证preload脚本正确性。

autoload 加载慢,先看是不是没开优化模式
生产环境类加载慢,八成是因为还在用未优化的 PSR-4 动态查找——每次 class_exists() 或 new 一个类,PHP 都得按命名空间逐级拼路径、反复 stat() 文件是否存在。这不是“查得慢”,是“查得太多”。
- 必须运行
composer install --no-dev --optimize-autoloader(或composer dump-autoload -o),它会把所有 PSR-4 映射固化为一张静态数组,跳过目录遍历 - 检查
vendor/composer/autoload_classmap.php是否存在且非空;若为空或根本没生成,说明项目里有不合规的 autoload 配置(比如"App": "src/"少了末尾反斜杠) - 别在开发中频繁跑
-o:它会全量扫描,越扫越慢;开发阶段保持默认即可,优化只留给部署环节
用 --profile 定位 autoload 生成卡在哪一步
composer dump-autoload --profile 能直接告诉你为什么生成 autoload 文件要花好几秒——不是玄学,是哪条路径在反复扫描、哪个包在拖后腿。
- 输出里如果出现类似
[1240.5ms] Scanning /path/to/vendor/some-bad-package/src,说明该包没声明psr-4,Composer 正在暴力穷举所有 PHP 文件建 classmap - 若耗时集中在
Scanning tests/或Scanning docs/,大概率是composer.json里误把"tests/": ["tests/"]写进了autoload.classmap,而不是autoload-dev - 对比
composer dump-autoload --profile和composer dump-autoload -o --profile的耗时差异:后者应明显更短;如果差不多,说明优化被悄悄降级了——去检查是否有路径重叠或命名空间不合法
autoload_classmap.php 越来越大?小心 classmap 配置污染
一个 3MB 的 autoload_classmap.php 不是“功能强”,是隐患:每次请求都要完整反序列化或 require 进内存,而实际用到的类往往不到 5%。
- 删掉所有无意义的 classmap 条目:
"docs/": ["docs/"]、"resources/": ["resources/"]、"tests/": ["tests/"]——这些不该进生产 autoload - 检查第三方包是否“带毒”:运行
composer show --tree,找那些在require-dev里却声明了autoload的包(如某些旧版phpunit插件),它们的测试类可能被意外扫入主 autoload - 确认
vendor/composer/autoload_psr4.php里没有你项目的测试命名空间(如"Tests\": "tests/");如果有,说明autoload-dev规则泄漏到了生产构建中
OPcache + preload 没配对,autoload 优化就白做
就算 autoload_classmap.php 生成得再干净,如果 PHP 每次都要从磁盘读取、解析、编译它,性能提升就大打折扣。
- 确保
opcache.enable=1且opcache.enable_cli=1(CI 环境也需要) - 启用
opcache.preload:写一个preload.php,里面只用require加载vendor/autoload.php和关键 autoload 文件,不要加任何逻辑判断 - 注意权限:
opcache.preload_user必须设为 FPM worker 用户(如www-data),否则 preload 失败且无报错, autoload 回退到最慢路径
最容易被忽略的是:preload 脚本一旦出错(比如 require 了一个不存在的文件),FPM 启动直接失败,但错误日志可能被淹没在系统日志里;上线前务必手动执行一遍 php -d opcache.preload=/path/to/preload.php -m | grep opcache 验证。



















