composerを速くするプラグイン・prestissimoを作った

Posted by Hiraku on 2016-01-24

composerが遅くてお嘆きの日本のPHPerの皆さんこんにちは。 表題の通り、追加インストールするだけでcomposerが速くなるプラグインを作りました。

# インストール
$ composer global require hirak/prestissimo
# アンインストール
$ composer global remove hirak/prestissimo

インストールした状態でlaravel/laravelをcreate-projectすると、26秒とかでダウンロード完了しました。Laravelは50個ぐらい依存パッケージがあり、同じ環境で普通にインストールすると5分ぐらいは最低かかるので、10倍以上速くなってます。

laravel

2016/1/13(水)にPHPBLT#2というイベントがあり、その中で同じデモをしてきました。

Composer並列化プラグイン #phpblt from Hiraku Nakano

発表後、早速使ってくれた方々からバグ報告を受けて修正し、今はまともに使えるようになっていると思います。

引き続き不具合などあればgithubのissueに書いていただけると幸いです。日本語でOKです。

https://github.com/hirak/prestissimo

どういう仕組みなのか

composerは日本で実行すると大変遅く感じます。かかっている時間の大半はpackagist.orgとgithub.comからファイルをダウンロードする時間で、この部分だけでも解決するとかなり速くなります。

composerがファイルをダウンロードする部分のコードはfile_get_contents、すなわちPHP組み込みのhttpストリームラッパーを使っています。

ストリームラッパーは素朴ですが、毎回コネクションを切断するため、繰り返し同じサーバーからダウンロードする場合は非効率です。この辺はcurlを使い、同じcurlリソースを使いまわしながらダウンロードすると解決します。

prestissimoでは、プラグインでcurlを使ったダウンローダーに差し替えます。 また依存関係解決後のイベントをフックし、必要なzipファイルを並列で一気に取得し、キャッシュを事前に作っておくことでダウンロード時間を大幅に短縮しています。

並列ダウンロードに失敗すると、既存の直列ダウンロードにフォールバックするので、prestissimoは互換性を担保しています。

なぜプラグインにしたのか

composerのダウンロード機構が遅いというのはもう何年も前から話題になっていて、度々githubのissueやpull requestとして議論になっていました。私自身も適当にcurl版を実装してpull requestを投げたことがあります。

一方で、既存のComposer\Util\RemoteFilesystemには認証など色々な機能が含まれており、互換性を保ったまま差し替えるのは割と面倒でした。 ダウンロード機構はcomposerの根幹部分です。品質の低いPull Requestをマージして動かなくなることがあれば大変です。

プラグインとして、本体とは別に実績を積んで、品質を上げてからP-Rにする方が受け入れて貰えやすいと思ったので、この形式を取っています。

というわけで、フィードバックへのご協力よろしくお願いいたします。

直近の課題としては、テスト駆動で書かなかったのが祟ってカバレッジが18%というゴミみたいな数字になってるので、少しずつユニットテストを書いているところです。

PHPの最新記事