Wowgineer Notes

WowTechエンジニアの徒然開発日記

Wowgineer Notes

〜新たな"Wow"を生み出す〜

Reduxのパフォーマンス改善でImmutable Dataの概念にぶち当たった話

f:id:yamamoto5555:20200821113553j:plain

Web開発チームの山本です。

以前の記事でReduxのStore設計について書いた通り、Reduxの道へと踏み出したのですが、その後パフォーマンス面での課題にぶち当たったので、今回はReduxでパフォーマンス改善に取り組んだことについて紹介します。

背景

お客様によりWowTalkを使っていただくため社内の浸透をサポートする集計機能を実装しました(詳しくはこちら)。その中の最終アクティブでは、アカウントに所属するユーザーの最終アクティブを表示しています。この最終アクティブの画面の表示が、ユーザーの多いアカウントでは遅いという問題がありました。最終アクティブ画面以外にも影響が出ていたため、早急に改善する必要がありました。

f:id:yamamoto5555:20201006105315p:plain

 

課題

今回は、4000人以上のアカウントで最終アクティブのページの読み込みが遅いのが、顕著に現れたので、Google Dev Toolsを使用し計測してみました。計測方法としては、MacBook Proを使用し、4000人ほどのアカウントで試しました。最終的には、数万人のアカウントも使用できるようにすることが今回のゴールです。

 

・計測対象の操作

サイドバーから最終アクティブをクリックするが、表示の反応が遅れるのと、最終アクティブのリストが表示されるのが遅いです。

f:id:yamamoto5555:20201013103743g:plain

 

・合計のレンダリング時間

f:id:yamamoto5555:20201013101046p:plain

 

・APIのリクエストとレスポンス時間

f:id:yamamoto5555:20201013101108p:plain

 

Reduxの仕組み

Reactで安否確認機能というサービスも開発していますが、同じ規模のアカウントでユーザーの読み込みに時間に、これほど時間がかかることはなかったため、今回はRedux起因の問題であると予想を立てました。

 

redux-loggerで出力しているLogでは、明らかにリストとして表示しているユーザー情報をStoreに更新した時の処理に時間がかかっていました。デバックしてみると、4000人のユーザー情報でループ処理が実行されていました。調べてみたところ、Reduxのimmutabilityに関係していました。

 

ReduxとImmutable Data

Redux と React-Redux は、どちらもをshallow equality checkingを採用しています。shallow equality checking(またはreference equality)とは、2つの異なる変数が同じオブジェクトを参照しているかどうかをチェックします。 また、shallow equality checkingとよく比較されるのが、deep equality checking です。deep equality checkingは、2つのオブジェクトのプロパティのすべての値をチェックします。Immutable Dataに関しては、Reduxのドキュメントにも詳しく記載されています。

今回は、このshallow quality checkingによって、Storeに4000人のユーザー情報を入れる場合、それの差分を確認するためにループ処理が実行され、時間がかかっているのではと考えました。

 

改善内容

Storeに入れてしまうと、shallow quality checkingで時間がかかってしまうため、ユーザー情報は、Storeに入れないで、グローバル変数の中に入れることにしました。local stateに入れるのは、UIなどの管理は向いているかなと思ったのですが、今回のユーザー情報は、最初に取得するだけで、そのあとに更新などは必要ないため、グローバル変数に格納することになりました。

redux.js.org

 

また、その他の改善点としては、最終アクティブの画面ではソート機能やフィルター機能があるため、毎回数万規模で部門のフィルターで時間がかかってしまうため、最初の20件のみを表示するように変更しました。

 

改善結果

上記の改善施策やその他細々した修正をした結果、2秒かからないくらいになりました。

f:id:yamamoto5555:20201030104344p:plain

 

まとめ

Reduxのshallow equality checkingによって、データ量が多いものをStoreで管理しようとするとかなり時間がかかることが分かりました。サーバーの負荷を減らすためにも、今回はフロント側での処理で対応しました。

数万人までのアカウントで利用できるようにするのが目標でしたが、今後10万人近いアカウントにも対応が必要になる可能性もあります。その時は今のやり方では限界がくると思うので、再度修正が必要です(またその時考える)。

Reduxのパフォーマンス改善をする中でも、React部分の無駄な再レンダリングなど多々あり、まだまだ改善の余地がありそうです。これからも継続的に、改善していきたいです!

 

補足:

今回が初めてのパフォーマンス改善だったので、チューニングの基礎などが書かれていたWebフロントエンド ハイパフォーマンス チューニングという本を読みました。Reduxのパフォーマンス改善には直接関係していませんが、いろいろなテクニックが書かれており、今後にも開発にも役立ちそうでした。

 

Webフロントエンド ハイパフォーマンス チューニング
 

 

参考リンク 

 

 

我々ワウテック技術開発部はこのような環境で開発をしています。
興味を持った方がいらっしゃればいつでもご連絡下さい。

f:id:wowtech-dev:20190313163146j:plain