レポート

東京Node学園祭の最終回(!?)に参加してきました!

この記事を読むのに必要な時間:およそ 5 分

seyaさん「State of SEO for SPA」

seyaさん@sekikazu01によるState of SEO for SPAでは,SPA(Single Page Application)とSEO(Search Engine Optimization)の関係について発表がありました。

seyaさん

seyaさん

seyaさんはSPAとSEOの関係について調べた際に,⁠SEOするならサーバーサイドレンダリング必須」⁠サーバーサイドレンダリング不要論」⁠SEOだけならプレレンダリングだけで十分」などといった情報の洪水に巻き込まれたそうです。この発表では,結局のところSEOを改善するためには(=HTMLが適切に解釈されるためには)どのようにすれば良いのかを,実際に計測した結果を元に,ケースごとにまとめて紹介しました(情報が錯綜している背景には,解決したいケースによって解決方法が変わる事情があります⁠⁠。

SPAとSEOに対する誤解について

SPAにおけるSEOがよく語られるときには,⁠GooglebotはJavaScriptを実行しないから,SPAで開発するとページが表示されず,正しくインデックスされない」⁠GooglebotはAjaxを待ってくれないから,コンテンツを表示したページがインデックスされない」などと言われます。まずこれらの情報は不正確であることを,Reactでレンダリングされたページに対してGooglebotが解釈するかどうかを実験した結果を踏まえて説明しました。

Reactでレンダリングされる

Reactでレンダリングされる

ただし,SPAがSEO観点で問題があることも事実です。GooglebotはChrome41相当(約3年前)の機能しか持たないため,新しめのJavaScriptの文法が利用されるとSPAが正しく描画されません。

さらに,Ajaxの実行にはタイムアウトが設定されており,場合によってはデータをコンテンツに反映させた状態で,解釈してくれないことがあります。そしてこのタイムアウトの時間は決まっているわけではなく5秒のこともあれば20秒のこともあるとのことです。

またJavaScriptを実行するサイトはすぐにインデックスされず,Render QueueにJavaScriptの実行を委譲します。Queueの待ち時間に1週間かかるることもあり,しばらくの間,期待したものがインデックスされないこともあります ⁠このレンダリングエンジンの問題とRender Queueの問題については,先日開催されたChrome Dev Summit 2018にて,将来的には緩和されると話がありました⁠⁠。

SPAにおけるSEOの改善方法について

次に,代表的なSEOを改善する方法を説明しました。⁠Chrome41相当のGooglebotに正しくJSを解釈させる」⁠メタ情報のみ(Server Side Rendering)して返す」⁠Dynamic Renderingを行う」⁠SSG(Static Site Generator)を活用する」⁠SSRする」という方法をあげ,Dynamic Renderingが万能のソリューションになると話しました。

Dynamic Rendering

Dynamic Rendering

「SPAでSEO意識するならSSR」とまで言われるSSRとSPAについての関係も取り上げました。原理的にはSSRはSEOの対策になるはずですが,タイムアウトの可能性は依然残るため,インデックスされなかった実例もあり,万能のソリューションにはならないとのことです。

最後に,どのケースのときにどの解決策を取ればいいかをまとめました。これまでの氾濫した情報が整理され,とてもタメになる発表でした。

フローチャート

フローチャート

比較表

比較表

React におけるパフォーマンスチューニング by 辻健人

辻建人@maxmellon_9039さんによる「Reactにおけるパフォーマンスチューニング」は,業務の中で出会ったパフォーマンス不足にどう立ち向かったかの体験談と,パフォーマンスチューニングの指針や心構えについての発表でした。

辻さん

辻さん

パフォーマンスチューニングについての詳しい解説はReact製のSPAのパフォーマンスチューニング実例にまとめられているとのことです。

辻さんはAirSHIFTというサービスを開発しており,その開発中に顧客から表示の遅さを指摘されたことがあり,原因調査とパフォーマンスチューニングを始めたそうです。原因調査の第一歩として,Chrome DevToolsで該当のページのパフォーマンスを確かめたところ,Scripting(JavaScriptの実行)に多くの時間がかかっていたとのことでした。

そこで問題の解決に向けて動き出すのですが,辻さん曰く,パフォーマンスチューニングをする上での心構えを「推測するな,計測せよ」と説きました。

処理時間を計測するために

処理時間の計測のためには,User Timing APIが利用できます。これは計測したい箇所の前後にmarkを入れることで,Dev Tools上でその実行にかかった時間がみれるようになる機能です。Reactではv16で自動的にマークを入れてくれるようになり,計測が行いやすくなります。しかし,ユーザーのどの行動でどの関数が実行されたかがわかりにくいため,それを見やすくするライブラリredux-action-timing-middlewareを作成しました。これはどの操作で,どのコンポーネントがレンダリングされたかを,reduxのアクションの発火に関するイベントだけprefixに絵文字を入れることで,DevTools上で見やすくしてくれます。

発火していることが見やすい

発火していることが見やすい

パフォーマンスをあげるために

パフォーマンスを向上させるためには関数の処理時間を減らすと良く,そのためには関数内の無駄な処理をなくすことが効果的であるとします。計測ツールで確認したところ辻さんのアプリケーションは同じ処理を何回も呼び出しており,それはReactのReconcilation(差分レンダリングを行うかどうかの判定)であったとのことです。

Reconcilationを減らすためには,画面全体におけるコンポーネントの木構造を小さくすることに加え,不要なReconcilationをさせないことを意識すると良いと言います。前者はreact-virtualizedのようなライブラリで画面外のコンポーネントは描画しないようにして対処,後者はコンポーネントにshouldComponentUpdateを書いて対処します。

また細かく差分レンダリングを行うために,コンポーネントの粒度は小さくします(コンポーネントの粒度が大きいと,コンポーネントの一部しか書き変わらなくても,そのコンポーネント全体に書き換えの処理が走ってしまいます⁠⁠。

パフォーマンスチューニングの結果

この地道な活動の結果,4倍低速環境で374%の改善,10秒のスピードアップを達成しました。パフォーマンスの計測をする際は,ユーザーと同じ環境で計測すべきであり,4倍低速環境での計測はその意図があるとのことです。

パフォーマンスは機能追加とともに落ちていくので,今後は定期的にパフォーマンス測定を行っていきたいと述べていました。

改善した結果

改善した結果

また発表では触れられていませんでしたが,資料の付録に楽にshouldComponentUpdateを実装するためのハウツーがまとまっています。ケース別によくまとまっていますので,興味がある方は参照してください。

著者プロフィール

井手優太(いでゆうた)

都内でフロントエンドエンジニアをしている。

URL:https://github.com/sadnessOjisan

バックナンバー

2018年

バックナンバー一覧