こんにちは。ASKULの はんだ と申します。
普段はLOHACOというECサービスのフロントエンドの開発をしています。
先日、LOHACOのスマホサイトトップ画面(以下、SPトップと呼びます)をリニューアルしました!!
お気づきになられた方いらっしゃいますでしょうか?
具体的に何が変わったのか、どう良くなったのかをご紹介していきます。
元のSPトップってどんな画面だった?
リニューアル前SPトップ
見た目からはわからないですが、レガシーな技術で構築されたページでした。
具体的にはJavaのバージョンが古かったり、Javaフレームワークも古いものが使用されていたり・・・
またSPトップだけではなく、買い物カゴや決済の画面なども同じ技術で構成されています。
そのため、カゴ画面で何かトラブルがあるとSPトップにも影響がある(画面が重くなったり)、その逆もしかり・・という状況でした。
※補足ですが、買い物カゴや決済の画面のリニューアルも着々と進行中であります!
リニューアルにあたってのテーマ
- 探しているものがみつけやすい
- 良い商品が見つけやすい(話題の商品など)
- 有益なキャンペーンお得情報が載ってる(クーポン、SALE、まとめ割など、ポイント倍率が高いもの)
- 何を売っているのか、品揃え感がある
といったユーザーニーズを満たすことに加え、
技術的には
とにかく速いページに!
これを意識しました。
リニューアル後SPトップ
どんなことした?
やったこと① コンテンツ用HTML生成のためのAPI呼び出し非同期化
SPトップには、下記のような「ピックアップ!話題の商品」や「季節のおすすめ」などのコンテンツが20ちょっとあります。
以前はそのほとんどがサーバーサイドでコンテンツ用のAPIを呼び出してHTMLを生成していましたが、今回のリニューアルでファーストビュー以外は非同期化(クライアントサイドAPI呼び出し&描画)しました。
【サーバーサイド描画】
リクエストを受けたら、
サーバー側で沢山のAPIを呼んで ⇒ 処理して ⇒ また呼んで ⇒ 処理して ⇒ なんやかんやして ⇒ やっとクライアントに返す
クライアントへ情報が返されるまでがとても長いです。
シーケンシャルに処理していたのも遅さの原因になっていました。
ページの処理が複雑になればなるほど、また、情報量が多くなればなるほど遅くなっていきます。
高速化を実現するには
- APIを並列に呼び出す
- キャッシュ用のミドルウェアを導入する
などサーバーサイドで対応できるものもありますが、
今回は「必要最低限の情報だけを瞬時に返却する」ことを意識してクライアントサイドの対策を施しました。
【クライアントサイド描画】
クライアントサイド描画(非同期)はリクエストを受けたら、
ファーストビューに必要な情報だけをすぐにクライアントに返す!!
まず返す!
その後、必要な情報を都度クライアント側(JavaScript)から取りに行きます
ユーザーからしてみるとページが表示されるまでいつまでもグルグルしてるとうんざりですが、
非同期化したことでページの読み込みが速くなりました。
Web分析ツールのKISSmetricsによると、
- 79%のユーザーがパフォーマンスに不満を持つと再訪しない
- 52%のユーザーがページスピードを重視
- 1秒遅延するごとに顧客満足度16%低下
- ページ応答が1秒遅れると、コンバージョンが7%減少する可能性がある
- ユーザーの47%が2秒以内にWebページを読み込むことを期待している
という分析結果が出ています。
今回ファーストビューに画像が表示されるのが速くなったので顧客満足度も上がることが期待できます。
またJavaScriptで情報を取得しにいくことでページサイズも減らす事ができました。
試しに「ピックアップ!話題の商品」部分のコードをリニューアル前後で比較してみると・・・
これだけあったソースが
たった1行分に!!
全体だとこのくらいページサイズを減らすことができました。
やったこと② 遅延読み込み
さらにページ速度を速くするために、画像を遅延読み込みしてくれるlazysizesを導入しました。
lazysizesとは画像を遅延読み込みするためのJavaScriptライブラリです。
- jQuery依存なし
- 軽量
- プラグイン豊富
とメリットが多いため採用しました。
導入方法もシンプルです。
①「lazysizes」をGitHubの公式ページからダウンロード ⇒ 解凍し「lazysizes.min.js」をHTMLで読み込み
<script src="lazysizes.min.js" async=""></script>
※LOHACOでは実際はlazysizesのプラグインをバンドルしたjsを読み込んでいます。
②「data-src」属性で画像を指定し、「lazyload」クラスを追加
<img
class="lazyload“
data-src="https://askul.c.yimg.jp/img/product/3L1/2783735_3L1.jpg"
src="https://askul.c.yimg.jp/resource/common/images/blank_01.gif"
alt="LOHACO Water 2.0L 5本“
/>
src属性には仮の画像をセットしています。これは無くてもOKです。
以上で導入完了。とっても簡単です。
では実際どんな動きをするのか「最近見た商品」を例に見てみましょう。
通常は以下のようにsrc属性に表示したい画像のパスを指定すると思います。
<img class="lazyload" src="//askul.c.yimg.jp/img/product/3L1/2783735_3L1.jpg">
ですが今回はlazysizesを利用しているので、src属性には1pxの小さいダミー画像(blank_01.gif)を指定し、data-src属性に実際に読み込みたい画像のパスを指定します。
<img class="lazyload" src="//askul.c.yimg.jp/resource/common/images/blank_01.gif" data-src="//askul.c.yimg.jp/img/product/3L1/7875722_3L1.jpg">
上記コードがスクロール前のコードの状態です。
それを横にスクロールしていくと、
<img class=" lazyloaded" src="//askul.c.yimg.jp/img/product/3L1/7875722_3L1.jpg" data-src="//askul.c.yimg.jp/img/product/3L1/7875722_3L1.jpg">
class="lazyload"がclass="lazyloaded"になり、
src属性にはダミー画像ではなくdata-src属性で指定していた画像パスがちゃんと設定されました。
またlazysizesのプラグインを入れることで画像以外にHTMLファイルの読み込みなんかもlazyできちゃいます。
<div
class="lazyload“
data-include="/content/lohaco-parts/detail-lower/51/5101/2783735.html">
</div>
おまけ
速度改善の一環としてResource Hints対応も入れています。
事前にDNSルックアップできるDNS-Prefetch
<link rel="dns-prefetch" href="CDNのURL">
本来は、リソースを読み込む際にDNSルックアップが走りますが、上記記述をページ上部に入れることによりコストが軽減されます。
事前にネットワーク接続するPreconnect
<link rel="preconnect" href="CDNのURL">
この指定を行うと、ネットワーク接続に必要な動作(DNSルックアップやTCPハンドシェイク、SSL/TLSネゴシエーションなど)を必要になる前に実施してくれます。
そのため指定ホストへのリクエストがすぐに出来るようになります。
まとめ
あれこれやってきましたが、リニューアル前と比較するとChromeのLighthouseでSpeed Indexを約2,000ポイント削減することができました。
速度改善として大きな一歩を踏み出すことができました。
これからも
速く!!
見やすく!!
を意識してお客様にとってLOHACOをもっと使いやすいサイトへと導いていきたいです。
なお、ASKULでは一緒にサイトをグレードアップしてくれるエンジニアも募集してます!