composerが遅くてお嘆きの日本のPHPerの皆さんこんにちは。 表題の通り、追加インストールするだけでcomposerが速くなるプラグインを作りました。
# インストール
$ composer global require hirak/prestissimo
# アンインストール
$ composer global remove hirak/prestissimo
インストールした状態でlaravel/laravelをcreate-projectすると、26秒とかでダウンロード完了しました。Laravelは50個ぐらい依存パッケージがあり、同じ環境で普通にインストールすると5分ぐらいは最低かかるので、10倍以上速くなってます。
2016/1/13(水)にPHPBLT#2というイベントがあり、その中で同じデモをしてきました。
発表後、早速使ってくれた方々からバグ報告を受けて修正し、今はまともに使えるようになっていると思います。
引き続き不具合などあれば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%というゴミみたいな数字になってるので、少しずつユニットテストを書いているところです。