必须在构建阶段执行composer install --no-dev --optimize-autoloader --classmap-authoritative,它通过剔除dev依赖、生成扁平classmap、禁用fallback查找,将冷启动从920ms降至310ms;漏掉此步或误用dump-autoload会导致classmap缺失、加载回退慢路径。

为什么--no-dev不能直接用在Serverless部署里
因为很多require-dev里的包其实是运行时隐式依赖,比如symfony/var-dumper被日志组件调用,sebastian/environment被SDK底层引用。直接加--no-dev会导致冷启动时报Class not found。
实操建议:
- 先跑
composer install --no-dev,再执行composer dump-autoload -a触发一次完整 autoload 检查 - 报错后用
composer depends vendor/package查谁在依赖它(需 Composer 2.5+) - 确认是真需要,就从
require-dev挪到require,哪怕只是“可选但存在即用” - CI/CD 流程里加一行
php -d display_errors=1 -m | grep opcache,防扩展缺失导致 autoload 失败
classmap-authoritative不是锦上添花,是冷启动提速刚需
默认 PSR-4 自动加载靠file_exists()和stat()动态扫描整个vendor/目录,Serverless 每次冷启动都重来一遍——单次轻松破 600ms。真正起效的是这条命令:composer install --no-dev --optimize-autoloader --classmap-authoritative。
它不是“多加个参数”,而是一整套流程:锁定依赖 → 全量扫描 → 写入vendor/composer/autoload_classmap.php → 强制只走 classmap 查找。
常见错误:
- 只跑
composer dump-autoload --optimize:不更新installed.json,也不校验composer.lock,新加类可能不在 classmap 里 - 漏掉
--classmap-authoritative:autoload 回退 fallback 路径,慢得更隐蔽 - classmap 文件本身太大:PHP 7.4+ 下每次冷启动都要
require整个文件进内存,但单次请求通常只用其中不到 5% 的类
怎么让classmap真正变小,而不是假装瘦身
光删tests/、docs/目录不够,关键是要从安装源头剔除——zip 解压时就不放进去,不是装完再扫。
实操建议:
- 在
composer.json里加"archive": {"exclude": ["/tests/", "/docs/", "/examples/", "/.github/"]},对每个大包单独配(如monolog/monolog) - 项目根目录加
.gitattributes,写/tests export-ignore等,配合--prefer-dist确保打包时彻底排除 - 检查第三方包是否含 demo 或 fixture:用
composer show vendor/package看源码路径,必要时 fork 后删减再 require - 别用
find vendor -name tests -type d -exec rm -rf {} +:旧版monolog把StreamHandler示例放tests/下,删了直接Class not found且--classmap-authoritative会让错误更难定位
Docker多阶段构建中,vendor复制前必须清理什么
Builder 阶段装完依赖后,Runtime 阶段只应 COPY /app/vendor,其余全是干扰项。但很多人忘了清理的不只是缓存。
必须清理的三项:
-
/root/.composer:含全局 config 和 auth token,不删会打进镜像 -
/tmp/*和/var/cache/apk/*:Alpine 构建残留,尤其apk add --no-cache后没删干净会带入 musl libc 和 BusyBox 二进制 -
vendor/composer/ClassLoader.php等生成文件:它们是构建产物,不是运行必需;但autoload_classmap.php和autoload_static.php必须保留
顺手验证:du -sh vendor/* | sort -hr | head -5,对比前后大小。真正有效的瘦身,是让vendor/autoload.php require 的第一个文件变小,而不是让du -sh vendor数字下降。











