冷启动慢的主因是vendor/autoload.php未启用classmap优化,必须在构建阶段执行composer install --no-dev --optimize-autoloader --classmap-authoritative并显式运行composer dump-autoload --optimize --classmap-authoritative,同时确保构建与运行时PHP版本及扩展一致。

冷启动慢,90%不是代码问题,而是 vendor/autoload.php 每次都重新扫描整个 vendor/ 目录——必须用 composer install --no-dev --optimize-autoloader --classmap-authoritative 在构建阶段生成扁平 classMap,否则冷启动卡在文件系统遍历上,稳稳 600ms+。
为什么只跑 composer install 不够
很多人在 Dockerfile 里写 composer install --no-dev 就以为完事了,结果冷启动还是慢。根本原因是:install 默认只生成 PSR-4 动态映射,每次请求都要调用 file_exists() 和 stat() 扫描 vendor 下成百上千个目录找类文件;Serverless 每次冷启动都重来一遍。
-
--optimize-autoloader会生成$classMap = array(...),把所有类路径硬编码进数组,跳过 I/O -
--classmap-authoritative强制关闭 fallback 查找逻辑,查不到就报错,不退回到慢路径 - 这两个参数必须一起用,单独加
--optimize-autoloader仍可能 fallback 到 PSR-4 - 检查是否生效:打开
vendor/autoload.php,搜索$classMap = array(—— 没这行就等于没优化
composer dump-autoload 必须显式执行
dump-autoload 是真正决定自动加载行为的命令,install 只是调用它一次。如果依赖没变但代码结构变了(比如新增类、改命名空间),install 不会重生成 classmap。
- 正确流程:先
composer install --no-dev --prefer-dist,再显式composer dump-autoload --optimize --classmap-authoritative - 漏掉第二步,
vendor/autoload.php加载的仍是未优化版本,冷启动照慢 - 函数运行时没有 PHP CLI 环境,根本跑不了这条命令,必须塞进 CI/CD 或
Dockerfile - AWS Lambda 或阿里云 FC 日志里出现
Class not found,八成是这一步漏了
构建阶段环境必须和运行时一致
本地 PHP 版本、扩展缺失或 platform 配置不对,会导致生成的 autoload_static.php 路径错位、类找不到,甚至启动直接失败。
- 在
composer.json的config段显式声明:"platform": {"php": "8.2"} - 构建时用官方镜像(如
public.ecr.aws/sam/build-php8.2),而非本地 PHP 环境 - 禁用无用扩展(如
mysqli、pdo_pgsql),它们会在容器启动时白占内存和初始化时间 - 避免引入
imagick等 Serverless 平台不支持的扩展,优先选 Bref 兼容组件
classmap 范围越大,冷启动越慢
哪怕用了 --classmap-authoritative,如果 autoload_classmap.php 文件达几 MB,PHP 7.4+ 每次冷启动都要 require 整个文件进内存,而单次请求通常只用到其中不到 5% 的类。
- 在
composer.json的autoload段加"exclude-from-classmap": ["tests/", "docs/", "examples/"] - 配合
.gitattributes设置export-ignore,确保打包时彻底剔除测试、文档等非运行时文件 - 用
composer show vendor/package-name查第三方包源码路径,删掉 demo/folder 等冗余内容再require - 漏掉这步,
--classmap-authoritative反而放大问题:classmap 越大,加载越慢,且错误更难定位
最易被忽略的是构建时 PHP 版本与运行时不一致,以及 dump-autoload 被当成可选步骤跳过——这两点一出,前面所有优化都归零。











