最准测法是用 curl 测 packages.json 的 time_starttransfer:需带 Composer UA 和 Accept: application/json 头,静默丢弃响应体,仅输出 TTFB;须取三次中位数,测前确认 DNS、防频控、超时设为 5 秒,丢弃 >1.5s 结果;测前必须清 Composer 缓存并验证是否真发新请求;路径须匹配 Composer 版本(2.2+ 用 /packs/,旧版用 /packages.json)。

用 curl 测 packages.json 的 time_starttransfer 最准
Composer 启动时第一件事就是拉 packages.json,这个请求的首字节时间(TTFB)直接决定 Resolving dependencies 卡多久。只测域名根路径或 / 会受重定向、HTML 返回干扰;只看 time_total 混入了下载体时间,不反映真实解析延迟。
正确命令必须带这些参数:
-
-H "User-Agent: Composer/2.9.6"(用composer --version查你的真实版本) -
-H "Accept: application/json"(避免镜像返回 HTML 或 403) -
-s -o /dev/null -f(静默丢弃响应体,只计时) -
-w "\nTTFB: %{time_starttransfer}s\n"(专注首字节耗时)
示例:
curl -s -o /dev/null -f \
-H"User-Agent: Composer/2.9.6" \
-H"Accept: application/json" \
-w"\nTTFB: %{time_starttransfer}s\n" \
https://mirrors.aliyun.com/composer/packages.json
别信单次结果,要跑 3 次取中位数
CDN 节点调度、本地 DNS 缓存、TLS session 复用都会让单次 time_starttransfer 波动极大。实测同个镜像三次可能分别是 0.12s / 0.87s / 0.21s——取平均会掩盖异常值,取中位数才稳。
脚本里建议这样写:
- 每次测前加
getent ahosts mirrors.aliyun.com确认没走错 DNS 解析 - 每轮之间
sleep 0.5,防 CDN 频控限流 - 超时强制设
--max-time 5,避免某次卡死拖慢整个流程 - 丢弃
time_starttransfer> 1.5s 的结果(基本可判定该镜像当前不可靠)
测完必须清缓存再验证
即使 curl 显示 TTFB 很低,composer install 还是慢?大概率是缓存没清干净。Composer 会优先读本地 cache-dir 里的旧 packages.json,哪怕你刚切了新镜像,它仍按缓存里的 URL 去校验——根本没走新源。
验证前务必执行:
-
composer clear-cache(不是cache-clear,后者已废弃) -
rm -rf $(composer config --global cache-dir)/repo/(彻底删元数据缓存) -
composer update --no-cache -v 2>&1 | grep "Downloading.*packages.json"(确认终端真发出了新请求)
注意镜像路径是否匹配你的 Composer 版本
Composer 2.2+ 默认走 /packs/ 路径(如 https://mirrors.aliyun.com/composer/packs/packages.json),而 2.1 及更早版本只认 /packages.json。如果你脚本测的是 /packs/,但本地是 2.1,实际运行时会 fallback 到官方源,测速结果完全失效。
检查方式很简单:
- 运行
composer --version - 若低于
2.2,测速 URL 必须用/packages.json,且得确认该镜像是否还支持旧协议(例如清华源 2023 年后已停用旧路径) - 升级推荐:
composer self-update,新版对/packs/支持更稳定,同步延迟也更低


















