composer在windows原生和wsl2的/mnt/c/下极慢,主因是杀毒软件扫描、ntfs/9p文件系统i/o瓶颈及php cli配置错配;真正高效方案是将项目移至wsl2的~/(ext4)、禁用defender对.vhdx扫描,并调优php配置。

Composer在Windows原生环境下慢,95%不是网络或工具本身问题,而是杀毒软件扫描、NTFS小文件I/O瓶颈、PHP CLI配置错配三者叠加导致的;WSL2本身不慢,但项目放在/mnt/c/下就和原生Windows一样卡——真正快的是把项目移到WSL2的~/(ext4)路径,并禁用Defender对.vhdx的扫描。
为什么composer install在/mnt/c/下比在~/下慢5–10倍
WSL2通过drvfs(9P协议)挂载Windows磁盘,所有文件操作都要跨内核转发:每次touch、stat、open都触发syscall翻译,而vendor/里动辄上万个PHP文件,I/O延迟直接从毫秒级拉到百毫秒级。这不是“网络慢”,也不是“CPU不够”,是文件系统层不可绕过的开销。
实操验证方式:df -T .输出中Type列为drvfs或9p→ 当前路径危险;若为ext4→ 安全。
- 别信“VS Code Remote-WSL打开
//wsl$/Ubuntu/home/xxx”这种路径——它走SMB共享,同样慢 -
/tmp虽快(tmpfs),但composer install会失败:vendor需硬链接支持,tmpfs不支持 - WSL1的
/mnt/c/确实比WSL2快些,但inotify失效,symfony/flex、phpstan等工具会出问题
Windows原生PHP下composer install卡住不动的真实原因
Windows Defender默认对%TEMP%\composer*、%APPDATA%\Composer、%LOCALAPPDATA%\Composer\files、项目vendor/实时扫描,每次解压ZIP包、写autoload_static.php都被拦住检查。进程监视器里能看到大量CreateFile被阻塞,日志停在Extracting阶段不动。
- 必须手动添加完整路径到Defender排除列表,
%LOCALAPPDATA%这类环境变量它不识别 - 查真实
%TEMP%路径:命令行运行echo %TEMP%,例如输出C:\Users\Alice\AppData\Local\Temp,就加这个完整路径 - 别只加
vendor/——%TEMP%\composer_archive*才是高频扫描点,漏掉照样卡 - 第三方杀软(火绒、360)同理,关掉“云查杀”或“主动防御”里针对ZIP/PHP的深度规则
WSL2中composer提速最关键的三件事
移路径、禁扫描、调配置——缺一不可。其他优化(如并发下载、镜像源)都建立在这三者之上,否则收效甚微。
- 项目必须放在WSL2原生路径:
cp -r /mnt/c/project ~/projects/myapp,然后进~/projects/myapp执行命令 - 禁用Defender对
.vhdx扫描:PowerShell管理员模式运行Set-MpPreference -ExclusionPath "C:\Users\Alice\AppData\Local\Packages\Ubuntu_123456789\LocalState\ext4.vhdx" - 全局配置生效:
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/+composer config -g parallel-downloads 8 - 确认PHP CLI没拖后腿:
php -i | grep "opcache.enable_cli"输出应为off;php -d xdebug.mode=off $(which composer) install可临时绕过Xdebug
容易被忽略的权限与缓存陷阱
在WSL2中以sudo运行composer,会导致~/.composer/cache属主变成root,后续普通用户执行composer update会报Permission denied;缓存目录若被误建在/mnt/c/下,又回到I/O瓶颈。
- 始终用当前用户运行
composer,不要sudo - 检查缓存路径:
composer config -g cache-dir,确保输出是/home/xxx/.composer-cache这类WSL本地路径 - 清理旧缓存:
composer clear-cache,再重新composer install,避免残留NTFS路径缓存干扰 - 私有Git仓库若未开启
download zip功能,"config": {"use-zip": true}会失败,此时需关掉该配置











