serverless冷启动优化关键在构建阶段:必须用目标php版本执行composer install --no-dev --optimize-autoloader,并补运行dump-autoload --optimize --classmap-authoritative,生成autoload_static.php与权威classmap,禁用无用扩展。

Serverless 环境下,Composer 镜像本身不加速冷启动;真正起效的是 vendor 目录中生成的 classmap 和运行时初始化方式。所谓“镜像预载”是误称,关键在构建阶段是否生成了可跳过文件遍历的 autoload_static.php 与 classmap 数组。
为什么 composer install --no-dev --optimize-autoloader 必须在构建阶段执行
Lambda 或其他 Serverless 平台没有写入权限、无网络、无 PHP CLI 环境,运行时无法执行任何 composer 命令。漏掉这步,vendor/autoload.php 仍走 PSR-4 动态查找路径,每次冷启动都要扫描所有 vendor 子目录——实测某 Laravel 微服务因此多耗 600ms+。
- 必须用与目标运行时完全一致的 PHP 版本(如
php8.2)执行,否则autoload_static.php中的类路径可能错位 -
--no-dev不仅省体积,更避免开发依赖(如phpunit)触发额外 autoloader 注册逻辑 - 只跑
composer install不够:若代码结构变更(如新增类),它不会重生成 classmap;必须显式加--optimize-autoloader
composer dump-autoload --optimize --classmap-authoritative 的不可替代性
dump-autoload 是最终决定自动加载行为的命令,install 只是调用它一次。很多团队 CI 流程里只跑 install,结果 vendor/composer/autoload_classmap.php 还是空的或未更新。
- 检查是否生效:打开
vendor/autoload.php,搜索$classMap = array(—— 没这行就等于没优化 -
--classmap-authoritative强制关闭动态查找,哪怕类文件被误删也不会 fallback 到文件系统扫描,既提速又防隐患 - 该命令必须在
install之后再执行一次,尤其当composer.json中有autoload变更时
Docker 构建时用 AWS 官方镜像而非本地 PHP 环境
本地 PHP 缺少 zip、mbstring 或 curl 扩展,会导致 autoload_static.php 生成异常,Lambda 启动时报 Class not found,但错误堆栈往往不指向 autoload 文件。
- 用
public.ecr.aws/sam/build-php8.2这类官方构建镜像,已预装全部必要扩展和工具链 - 命令示例:
docker run --rm -v $(pwd):/var/task public.ecr.aws/sam/build-php8.2 /bin/sh -c "cd /var/task && composer install --no-dev --optimize-autoloader" - 禁止在容器内执行
composer update—— 会污染composer.lock,破坏部署一致性
PHP 扩展与 php.ini 配置对冷启动的实际影响
每个启用的扩展都在容器启动时初始化,而 Serverless 每次冷启动都重来一遍。这不是理论开销,而是可测量的毫秒级延迟叠加。
- 启用
opcache.enable=1但没配opcache.preload?只缓存 opcode,不预热脚本,冷启动仍要解析全部 PHP 文件 - gd 扩展(尤其带 freetype 支持)增加 80–150ms 启动延迟;若函数不处理图像,直接禁用
- 未禁用
mysqli、pdo_pgsql等无用扩展,白占内存且拖慢初始化——在 Dockerfile 中用docker-php-ext-disable显式关掉
真正卡住冷启动的从来不是“有没有 Composer”,而是 vendor/autoload.php 加载时要不要遍历目录、PHP 运行时要不要加载一堆用不到的扩展、以及 classmap 是否被强制信任。这些细节全在构建阶段决定,运行时改不了。











