私の戦闘力は53万です。メリークリスマス、ミツモアの@teradonburiです。弊社ミツモアでは多種多様な業種のプロに依頼ができるプラットフォームのミツモアを運営しております。Console上で改善が必要な約2.5万ページの速度を開発チームで改善しました。これらのページは主に弊社が提供している各サービスの日本全国の市区町村地域別のランディングページとなります。今回は特に大きく効果があった2つの施策に関して紹介します。CMSのような形式でミツモアのメインサーバからページに必要なコンテンツをAPI経由で取得してページに表示させています。Regeneration)を導入してページの静的再生成を行っていました。ISRに関しては説明するとそれだけで記事になってしまうのでこちらの記事がまとまっているので参考にしてください。Regeneration)です。CMSのようなAPI経由で頻繁に更新されるコンテンツを取得して表示するようなページに適用できます。(かつページパフォーマンスを重視したい)問題となるのはVercelのISRキャッシュを即時に消したくなる場合があるのですが、この問題もNext12.2以降で実装されたrevalidateの機能を使うことで解消できます。Vitalsの指標にて計測を行っています。web.devテクニカルSEOの部分になりますが、ページスピードは検索順位に明確に影響するとのことでUX的にも大事な部分となります。Insightを使用しています。Vitals特に重要な指標が上3つです。Paint):viewport内で最もサイズが大きいコンテンツ要素が表示するまでの時間です。注意点としてはファーストビューではないので、画面上で見えていないコンテンツでも最も時間がかかるコンテンツのレンダリングまでの時間が計測対象となります。Delay):ユーザがページ表示してから入力開始できるまでの遅延時間です。ランディング時にJS実行などがある場合はブロッキングされて入力開始までの時間が遅くなります。Shift):コンテンツがレンダリングするときの表示ズレです。ブラウザ上でJSなどで動的にDOM操作する際に発生します。表示ズレが発生するとユーザが意図しないボタンを押してしまったりと好ましくありません今回、ウェブに関する主な指標の評価を合格することを目的にページパフォーマンスの改善を行っていきました。AutoWebPerfを導入し、それぞれの速度指標に対して定期実行による計測で日々トラッキングする仕組みを作りました。github.comクチコミ星☆のsvgをwebfont化ミツモアのランディングページにはプロのクチコミ評価として☆を表示しています。ミツモアではUIライブラリとしてMaterial-UIを導入しているのですが、調査の結果、内包しているmaterial-iconでの星のコンポーネントを使用するとレンダリングした際にSVGに展開されてプロ数×クチコミUIで大量のDOMが生成されていることがわかりました。Material-UIそこで星をSVGからWebfont化しました。以下は星を表示させるためのReactコンポーネントです。React.memo(SimpleRatingStar.Element)星のstyleは以下の様にclass定義してます。Webfontのため、content属性にWebfontの星の文字を表示しています。以下の例だと\F005の文字が星1つ分、\F089の文字がハーフスターとなっています。(Webfontに格納されている文字によってことなります。sizeでしなければいけなくなるところです。F089)しか使用できません。'\F005\F005\F005\F005\F005';}またWebfontファイルはそのまま使うとしばしば不要な文字が大量に含まれておりファイルサイズが肥大化して逆に読み込みパフォーマンスに影響を与えます。そこでWebfontファイルから不要な文字を削除して軽量化しました。今回使っているのは2文字のみです。opentype.jpまた、Webfontをpreloadすることで読み込みを高速化させています。Time)は15.9秒から10秒に大幅減少、DOM数は8718件から7614件と削減できました。Reactのクライアントサイドレンダリングの無効化FIDの速度を改善させるためにはJSの実行時間が最大の課題でした。NextJSで単純にISRをしていたとしてもこの問題は解決することはできませんでした。そこでブラウザ上でのJS実行を無効にすることができないか画策したところ、まだunstableな機能ではありますが、bundleの埋め込みをやめてReactJSのクライアントサイドレンダリングを無効にする方法があることがわかりました。alistair.blogクライアントサイドのレンダリングを無効にするには以下のフラグをページ単位(NextJSのルーティングのパス単位)に追加するだけです。}ただし、完全な静的HTMLとして払い出しされるためにFE側のReactJSが無効化されてできなくなることがあります。これはReactの仮想DOMの構築を捨てることと同義です。内部ルーティングを行うことができませんのでLinkコンポーネントは使えません。aタグやformタグ(method=GET)に差し替えることで代用できます。Reactの疑似routingが使えないため、都度SSRされることとなります。CSR側でJS実行されてリソース取得が最適化されるため使えません。Managerを無効化した場合の一部ページの計測ではなんとモバイルでも98点のパフォーマンススコアを叩き出しました。TTIは半分以下、TBTはほぼ皆無に筆頭にSpeedIndexやすべての指標が数万のランディングページで改善されました。確定申告の税理士サービスページ速度改善VercelのISRキャッシュクリアページ内コンテンツを更新した際にVercelのISRキャッシュを明示的に消したい場合が往々にしてあります。getStaticProps(ISR)でホスティングされたページのVercelキャッシュをクリアすることができるようになり、この問題は解決しております。APIを作成し、getStaticPropsでホスティングしているページのpathを指定してこのAPIを呼び出すだけです。}}ただ残念ながら、複数ページのVercelキャッシュクリアに関してはワイルドカードや正規表現指定で行うことができないため、大量のページのキャッシュクリア(再生成)に適していません。その場合は従来どおりVercelを再デプロイしてすべてのISRキャッシュをリセットした方が早いです。そもそもrevalidateはgetStaticPropsを裏で実行しているため、大量のページの明示的な事前レンダリングは向いてはいないのでしょう。まとめしばしばパフォーマンスの改善には「推測するな、計測せよ」という格言があります。これはどこがボトルネックなのかをはっきりさせるまでは、推測でスピードハックをしてはならないという話です。計測したところ今回のケースに関しては大量のコンテンツ量によるDOM数がパフォーマンスに影響を与えていたのとReactのフロントエンド実行処理が大きなボトルネックとなっていました。ボトルネックとなっていた本質的な部分の改善をすることで大きなパフォーマンスの改善と繋がりました。Managerなど技術面以外の要素で遅くなる点も明らかになりました。この辺も広告チームと連携を取り、パフォーマンスの意識を持ってもらうことで不要なトラッキングを整理して減らしてもらうことができました。上記のように弊社ミツモア開発陣は日々より良いプロダクト開発の改善に努めています。2022の14日目の記事です。宮内(@myrsn0104)です。2022の6日目の記事です。2021の24日目の記事です。2021の12/23分の記事です。12Search引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。