Speee DEVELOPER BLOG

Speee開発陣による技術情報発信ブログです。 メディア開発・運用、スマートフォンアプリ開発、Webマーケティング、アドテクなどで培った技術ノウハウを発信していきます!

開発者向けSEO対策 ページスコア改善 第1段

※この記事は、Speee Advent Calendar7日目の記事です。 昨日の記事はこちら tech.speee.jp

こんにちは、Speeeのヌリカエでエンジニアをしています。21新卒の染谷です。
ヌリカエのTopページのページスコアを改善しました。この記事はどのようなことを考え、何をしてページスコアを改善していったのかという奮闘記になります。
まだまだ改善すべきページはあるのでそのうち第2段があるかも!?

ヌリカエの構成技術

  • バックエンド: Ruby 2.6.5 + Ruby on Rails 6.0.4.1
  • フロントエンド: slim + jQuery + Stimulus

ページスコアとは

この記事で言うページスコアとは、PageSpeed InsightsやLighthouseを実行した時に表示されるスコアのことです。Webサイトの読み込み速度をサーバ応答時間やコンテンツのレンダリング時間などを考慮してスコアが計算されます。0~100の数値で計測され、高い数値ほど良いWebサイトという評価を受けます。同じコンテンツのWebサイトであればページスコアが高い方が検索上位に表示されるため、SEO的に重要な指標の一つです。
また、スコア的にはPageSpeed Insightsの方がLighthouseよりも正しいとよく言われます。ただし、LighthouseはGoogle Chromeのデベロッパーツールから使用できるのでlocalhostでも実行できる点は調査向きでとても便利です。

何故ページスコアを上げるのか

SEO的に重要だからです。
というのももちろんなのですが、いちエンジニアとしてページスピードが遅いサイトはいかがなものなのかと思っています。ユーザ体験的にページスピードが遅いと「なんだこのサイト。それとも電波悪いのか?」と思ってしまうため、なるべく避けたいです。そのためにページスコアを改善し、ページスピードを速くします。

改善前

改善前のTopページをPageSpeed Insightsで計測したものです。
f:id:gyaogate:20211201162003p:plain 30点、、、低い、、、
CLS(Cumulative Layout Shift) 以外アウトですね。
ここからページスコア70点を目標として改善します。

調査

まずはPageSpeed Insightsの計測結果ページにある 計算ツールはこちら。 をクリックして下記画像を見ます。これでどの項目をどれほど速くしたらページスコアが上がるかが分かります。
f:id:gyaogate:20211201162039p:plain 配点が大きく、改善できたらページスコアが大幅上昇にそうなところは LCP(Largest Contentful Paint)TBT(Total Blocking Time) ということがわかります。

Largest Contentful Paint

LCPは最大コンテンツ描画の時間です。ヌリカエのTopページでは職人さんが写った画像がLCPに当たります。これをresizeするなり、元の画像を小さくすれば解決できそうと目星がつきました。

Total Blocking Time

TBTは何が影響しているかこのままだとわかりません。そんな時はLighthouseでページスコアを計測します。
f:id:gyaogate:20211201162043p:plain f:id:gyaogate:20211201162047p:plain

Minimize main-thread work を見ると Script Evaluation がTBTを落としている原因のようです。つまりjsですね。
ここからさらに View Origin Trace ボタンを押して Performance タブの内容を見ていきます。
f:id:gyaogate:20211201162057p:plain Long Taskと赤くなっているので先ほどのEvaluate Scriptはこれですね。
そしてさらにこれを拡大していくと
f:id:gyaogate:20211201162102p:plain むむ、何やらLayoutがどうたらこうたらと言われています。jsの中のLayoutで怒られているので多分jsによる強制的にクラスがあてがわれてガチャガチャと要素が動いているのでしょう。
ただし、どのコードがそれに当たるかまではLighthouseから読み取れないので、ローカル環境でコードをコメントアウトしてはLighthouseで計測を繰り返していきます。
コードを二分探索的にコメントアウトしては計測して行き、最後にそれっぽいjsだけをコメントアウトして見ると
f:id:gyaogate:20211201162107p:plain f:id:gyaogate:20211201162119p:plain 🎉 TBTめっちゃ速くなった!🎉

ちなみにカルーセルで使っているslick.jsが原因だとわかりました。
f:id:gyaogate:20211201162125p:plain

slick.jsを使わずにカルーセルを実装するようにリファクタリングする必要がありそうです。

Speed Index

最後にサーバ応答時間を調査します。
サーバ応答時間はSI(Speed Index) に該当するのでLCPとTBT程、ページスコア的には影響しないのです。しかし、サーバ応答時間が長いとユーザ体験の悪さに繋がります。
この記事を書いている時には既に改善したものをリリースしてしまっているので、改善前のコードをローカル環境で実行して計測します。
f:id:gyaogate:20211201162131p:plain

4.73s、、、遅いですね。この画面ではこれ以上わからないので、TBTを調べた時と同様に二分探索でコメントアウトしつつ、計測します。また、重いSQLが主な原因であることが多いので、SQL発行の時間を見つつ目星をつけていきます。
重いSQLをコメントアウトして見ると

f:id:gyaogate:20211201162136p:plain

🎉 応答時間めっちゃ速くなった!🎉

f:id:gyaogate:20211201162141p:plain

どうやら事例という「クライアントがエンドユーザのお家をどんな施工工事をしたか」の情報を持ってくる処理に時間が掛かっていたようです。SQL実行で700ms使っているところがありました。
どうにかしてSQL実行時間を短くする必要があります。

*事例はリリースしてからそこそこ時間が経っています。重いことに気がつかなかった理由はローカル環境に事例の画像がなく、表示されないという本番環境との差異があったためです。ステージング環境でも画像なかった。本番と環境合わせるの大事。

改善

Largest Contentful Paint

これは画像の問題です。ImageMagickを使いpngからjpegへ可逆圧縮し、できるだけサイズを小さくします。また、PC用とスマホ用で同じサイズの画像が使われていました。スマホ用はPC用に比べたら横幅は短くて良いので画像の左右をトリミングしてサイズを小さくします。

ステージング環境での計測結果です。

before

f:id:gyaogate:20211201162144p:plain

after

f:id:gyaogate:20211201162148p:plain うーむ。LCPがちょこっとだけ速くなりました。あまり効果なかったかも?

Total Blocking Time

カルーセルに使っているslick.jsが重いことがわかったので、カルーセル系のライブラリは使わずにjQueryだけで同じ挙動ができるようにリファクタリングします。
ライブラリ使わずにカルーセル作るの簡単なようでめちゃ大変だった、、、
ライブラリの偉大さを実感しました。

ステージング環境での計測結果です。

before

f:id:gyaogate:20211201162152p:plain

after

f:id:gyaogate:20211201162156p:plain

ローカルで検証したのと同じくらい速くなってる!スコアは25点伸びているので本番環境でも結果が期待できそうです。

Speed Index

事例のデータを生成するSQLが原因なのでSQLチューニングをします。といってもそう簡単にできないので困りものです。joinする回数を減らせば速くなるのでしょうが、テーブル設計からやり直すとなると影響範囲が大き過ぎて膨大な工数がかかります。
なので今回は低レベルキャッシュを使います。memcacheやRedisといったインメモリに保存することで事例のSQLが実行されたら1日の間、インメモリに配列としてデータを保存し、保存されている間はSQL実行せずにインメモリからデータ読み込みをするようにします。これでお手軽に700msの時間短縮になりました!
*ただし1日の間は同じデータが表示されることと、最初の1回目はSQL実行で700ms時間がかかるので使い過ぎには注意です。

ステージング環境での計測結果です。

before

f:id:gyaogate:20211201162159p:plain

after

f:id:gyaogate:20211201162202p:plain

beforeとafterでSIにあまり差がないですが、ステージング環境もローカル環境と同じで事例のデータが少ないため、このようになっています。
ヌリカエ開発チームでは、ステージング環境でLighthouse計測し、ページスコアに問題がなかったらリリースという運用をしています。しかし、画像がない事例は表示させない という実装をしてから本番環境と差異が出てしまっていたようで今まで気づきませんでした。本番と環境合わせるの大事(2回目)。

結果

最後に改善で行った開発を全てマージし、LighthouseとPageSpeed Insightsで計測した結果です。
f:id:gyaogate:20211201162207p:plain f:id:gyaogate:20211201162211p:plain 🎉めっちゃページスコア上がってる!🎉

あの30点台だった頃が考えられないくらいページスコアが上がりました。
PageSpeed Insightsでは安定して60点台を出せるようになりました。
ステージング環境ではLCPが思ったより速くなりませんでしたが、本番環境ではしっかりと成果が出ています。SIもしっかり成果が出ました。
ただし、残念なことにTBTはイマイチですね。一つ不可解なのは、TBTがLighthouseでは230msと速いのに対して、PageSpeed Insightsだと990msとまだまだ遅い点です。PageSpeed InsightsはPerformanceタブのように詳細が見れないので謎です。

最後に

コンテンツ量と開発速度、そしてページスコアはトレードオフの関係にあると思います。コンテンツ量は良質なWebサイトを作るために致し方がないところがあるので、開発速度とページスコアを考えながら理想のコンテンツを作成するのがエンジニアの腕の見せ所だと思っています。
良質なWebサイトを作るためにページスコアを意識して開発していきましょう!!

Speeeでは一緒にサービス開発を推進してくれる仲間を大募集しています! もしSpeeeに興味を持っていただいた方は以下で社内メンバーのカジュアル面談を公開しているので、お気軽にご連絡ください💁

tech.speee.jp

エンジニアだけでなく、様々なポジションで募集中なので、「どんなポジションがあるの?」と気になってくれてた方は、こちらチェックしてみてください!もちろんオープンポジション的に上記に限らず積極採用中です!!!