フロントエンドのパフォーマンス改善

この記事は [UMITRON Advent Calendar 2024](https://adventar.org/calendars/9995) 24日目の記事です。

---

フロントエンド (React) のパフォーマンス改善を行ったので、それに関して個人的に感じたことをまとめておこうと思います。

## パフォーマンス改善の流れ

![frontend_performance_profiling_001.png](https://files.tearoom6.biz/aa513736-9a3a-48f5-99ee-bd212daf13e4.png)

### はじめに

特に時間的余裕がある場合、できることから手当たり次第に試していくよりは、きちんと原因を突き止めて改善した方がよいというのを改めて感じました。典型的な改善テクニックや以前うまくいった改善方法が、今回も大きく効くとは限らないですし、思わぬところにボトルネックがあるというのは往々にしてあることなので、まずはボトルネックの調査を行うのが遠回りのようで近道、急がば回れな感じがします。幸いにして、今は調査ツールも豊富ですし、原因特定には必ずしも時間はかからないように思います。

### ステージング環境で調査

開発環境でも現れているボトルネックに関しては、開発環境で調査して直してしまうのが良いと思います。しかし、開発環境では顕著に現れないが、本番環境だと明確になるようなケースもあるかと思います。

そのような場合には、まず本番環境とデータベースを共有しているステージング環境でパフォーマンスの調査を行うのが良いかと思います。

本番環境ではなくステージング環境で調査を行うのは、一つには、予期せぬユーザ影響を与えるのを避けたいのと、フロントエンド特有の問題として、コードに minify/compress がかかっている場合、非常に調査がやり辛いということがあり、minify/compress を解除したステージング環境を別途用意するか、一時的にステージング環境の minify/compress を解除するなりして、調査を進めたいという理由からです。調査に用いるツール側が対応していれば sourcemap を用意するでもいいと思います。

### 開発環境で再現・修正

原因を特定できた後には、開発環境で部分的にでも再現できる状況を作っておくことも重要です。

その上で、開発環境で修正を行い、改善が確認できたものを、ステージング環境に上げて、そこでも改善が確認できれば、本番環境にデプロイします。

### 繰り返し改善

長年、パフォーマンス改善を放置していると、パフォーマンス上のボトルネックが幾重にも重なっていることがあります。こべりついた汚れのように、表層を剥がしたら、またその奥に汚れが見つかるみたいな感じで、何層にもパフォーマンス上、悪さをしている箇所が見つかる場合があります。プロファイリングを行って、一番割合の大きなところを改善すると、その次に割合の大きなところが目立つようになります。

一番大きなボトルネックを解消した後も満足せずに、まだ改善できるところはないかと繰り返し調査をすることは大事です。

また、一気にあらゆる改善を実施するよりは、段階的に改善することで、きちんと原因箇所の特定が正しかったことを検証できますし、予期せぬ副作用のロールバックもやりやすくなるため、細かいデプロイが可能な場合はそのほうがおすすめです。

## React 特有のボトルネック

React はパフォーマンス面も優れていて、そんなに規模が大きくないアプリケーションであれば、適当に使っていてもそんなに重いなと感じることも少ないですが、やはり徐々に機能や規模が複雑になるにつれて、重く感じる場面も増えてきます。

今回の調査では、再レンダリング周りを見直すこと (範囲の限定、抑制等) がパフォーマンスに大きく影響しました。
React では、状態等が変わると、必要なコンポーネントの再レンダリングが発生しますが、再レンダリングの範囲や頻度が大きければ、そこで大きなコストが生じてしまいます。

具体的な改善手法は、以下の記事が非常によくまとまっていて、参考になりました。
どういう時に、どのような範囲で再レンダリングが起きるのかを理解しておけば、かなり調査が捗ると思います。

[React re-renders guide: everything, all at once](https://www.developerway.com/posts/react-re-renders-guide) (邦訳されている記事もありました: [React再レンダリングガイド: 一度に全て理解する #Next.js - Qiita](https://qiita.com/yokoto/items/ee3ed0b3ca905b9016d3))

ただ、上述した通り、思わぬところでボトルネックが潜んでいることはあります。今回調査した中では、使用しているライブラリ (Video.js) の loading spinner (ぐるぐるしているやつ) の描画に無駄にリソースを消費しているなんてのが見つかりました。

## 調査ツール

僕は普段 Chrome を用いていますが、付属の DevTools を用いた実測だけでも分かることは相当多いです。
特に Performance パネルは多用しました。

![frontend_performance_profiling_002.png](https://files.tearoom6.biz/98c2d99f-7e04-49f2-8c89-46b855eaa2f8.png)

また、 React の再レンダリングの調査に関しては [React DevTools](https://chromewebstore.google.com/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi) の Profiler パネルを併用すると、問題のある箇所を見つけやすいです。ただし production build で利用するためには、専用の設定変更が必要なので、ご注意ください。

![frontend_performance_profiling_003.png](https://files.tearoom6.biz/666a51e7-901d-4d4e-a75e-3a65fc756cc1.png)

これらのツールの使い方は、既に他の多くのまとまった記事があるので、そちらに譲ります。

## まとめ

まとめると、以下のようになります。

- 場当たり的な修正ではなく、まずは現状調査を
- 大きなボトルネックが解消するまで繰り返し改善
- ブラウザ付属の DevTools でも十分に調査可能

あまり具体的な内容までは記載しておらず物足りないかもしれませんが、参考になったら嬉しいです。

---

ウミトロンは、「持続可能な水産養殖を地球に実装する」というミッション実現に向けて、日々プロダクト開発・展開にチーム一丸となって邁進しています。
ウミトロンのニュースや活動状況を各種SNSで配信していますので、ぜひチェックいただき、来年も応援よろしくお願いします！

Facebook https://www.facebook.com/umitronaqtech/
X https://x.com/umitron
Instagram https://www.instagram.com/umitron.aqtech/
Linkedin https://www.linkedin.com/company/umitron