背景
私は現在、AAHubとというウェブサイトを運営しています。このサイトはIonicとAngularを用いて構築されています。
これまでAngularとIonicのフレームワークのバージョンアップには対応してきましたが、スタンドアロンコンポーネントや新しい制御フロー構文への対応は行っていませんでした。
そこで、これらの技術を取り入れることを計画しています。それに伴い、PageSpeed Insightsを使用してウェブサイトのスコアやバンドルサイズの変化を追跡し、パフォーマンスの改善を図りたいと考えています。
サイトの技術スタックについて
- @ionic/angular: v7.5
- Angular 17.0.3
- Firebase 10.7.0
- @angular/fire: 17.0.0-next.0
- Cloudflare Pages
Before→After
Before
- スコア:35点
- バンドルサイズ:4MB
- First Contentful Paint:7.8s
After
- スコア:44点
- バンドルサイズ:2.6MB
- First Contentful Paint:3.4s
他参考
Cloudflareのチュートリアルに従って、Angularのサンプルプロジェクトをこちらにデプロイしてみました。結果として、パフォーマンススコアが100点という素晴らしい結果になりました。これに対して、私のサイトはパフォーマンスがかなり低いことが明らかになりました。
やったこと
- スタンドアロンコンポーネント対応
- IonicModule/AppModule削除
- 不要なpacakgeの削除
- CommonModule削除
- Inject関数を使うように変更
スタート時
- URL:https://83b4ff45.aahub.pages.dev/
- スコア:35点
- バンドルサイズ:4MB
- First Contentful Paint:7.8s
とりあえず、フレームワークのバージョンアップだけした状態です。
ここから色々変更加えて行きます。
スタンドアロンコンポーネント対応
- URL:https://2764bff7.aahub.pages.dev/
- スコア:33点
- バンドルサイズ:4MB
- First Contentful Paint:7.7s
まずは、コマンド一発でAngularのスタンドアロンコンポーネントに対応する作業を行いました。
以下のコマンドを実行することで、ほとんどのコンポーネントをスタンドアロンコンポーネントに変換できました。
ng generate @angular/core:standalone
このコマンドにより、多くのModuleが削除されましたが、一部は自動変換できなかったため、これらは手動で削除する必要がありました。
変換後の現時点で、スコアやバンドルサイズには変化は見られません。スタンドアロンコンポーネントはModuleファイルの削除に関わるものであり、パフォーマンスに直接的な影響はないと聞いていたため、これは予想していた結果です。
IonicModule削除/AppModule削除
- URL:https://acf401b0.aahub.pages.dev/
- スコア:34点
- バンドルサイズ:3.6M
- First Contentful Paint:5.3s
Ionic 7.5のリリースにより、IonicのコンポーネントをUIコンポーネントとして個別に読み込むことが可能になりました。この変更のおかげで、IonicModuleの削除が実現可能になりました。詳細はIonicの公式ブログで確認できます。
上の画像のように、IonicのUIコンポーネントを個別にimportすることにより、IonicModuleを読み込む必要がなくなりました。
この対応を導入した結果、バンドルサイズとFirst Contentful Paintが大幅に改善されました。
*Ionic公式からコマンド一発でIonicModule関係をスタンドアロンコンポーネントの読み込みに変換できるツールが出てます。
https://github.com/ionic-team/ionic-angular-standalone-codemods
不要なモジュールの削除
- URL:https://0ef516c0.aahub.pages.dev/
- スコア:34点
- バンドルサイズ:2.9MB
- First Contentful Paint:3.6s
AngularやIonicとは関連しない部分ですが、私のプロジェクトにはjszipというJavaScriptライブラリが含まれていました。このライブラリはJavaScriptでZipファイルを作成するためのものですが、必要なくなったため削除しました。
このライブラリが意外にも大きな容量を占めていたため、削除することでバンドルサイズが大幅に減少し、First Contentful Paintのスコアも向上しました。
CommonModuleの削除
- URL:https://645d3614.aahub.pages.dev/
- スコア:45点
- バンドルサイズ:2.6MB
- First Contentful Paint:3.7s
プロジェクト内でAngularのCommonModuleがまだ使用されていることに気づきました。これを解決するために、CommonModule全体ではなく、必要なモジュール(例えばNgClassなど)のみを読み込むように変更しました。
Inject関数を使うように変更
- URL:https://ec65e07e.aahub.pages.dev/
- スコア:44点
- バンドルサイズ:2.6MB
- First Contentful Paint:3.4s
- https://pagespeed.web.dev/analysis/https-ec65e07e-aahub-pages-dev/w1uf08puhv?hl=ja&form_factor=mobile
私のプロジェクトでは、これまでconstructorを通じて依存性の注入を行っていましたが、最新の標準としてinject関数の使用が推奨されています。そのため、この新しい方法に対応する変更を実施しました。
パフォーマンスとの直接的な関連性は少ないと考えられますが、念のため測定を行ったところ、First Contentful Paintが若干改善されていることが分かりました。ただ、この改善は偶然の結果である可能性が高いと思います。
まとめ
この記事を書く過程でIonicとAngularに関する様々な変更を試みました。過去1~2年間でIonicもAngularも大きく変化したと感じています。特に注目すべきは、最新の構文への移行を容易にするコマンドが用意されている点で、コマンド一発でほとんど移行できたのはとてもありがたかったです。
今回の変更を適用した私のサイトは、元々の構造が完璧とは言えないため、パフォーマンススコアの改善には苦労しました。この点に関しては今後別のタイミングでがっつり改善を図り、その結果を別の記事で共有したいと考えています。
それでは、ご覧いただきありがとうございました。