Shopify ブログ

Shopifyテーマチームによる高速なテーマ作成:NarrativeのWebパフォーマンスを向上させた方法

Webパフォーマンスに関するもっとも困難な部分は、プロジェクトを遅くしている修正が必要な箇所をピンポイントで指摘することです。正しいアプローチを取らないと、パフォーマンスの改良につながることを期待しながら、ベストプラクティスのリストを当て推量でチェックするというゲームになってしまいます。

こうしたゲームに興じる時間はありません。確実にパフォーマンスのボトルネックになっている、もっともインパクトの大きい修正に時間を費やす必要があります。

ShopifyではWebパフォーマンスを重く捉えています。マーチャントのオンラインストアが速くなればそれだけ売上が上がり、ビジネスが成功すると理解しています。

Shopifyの無料テーマNarrativeは、テーマのパフォーマンスに関する水準を引き上げようという試みです。プロジェクト全体にわたってパフォーマンスのことを考え抜くことによって、Shopoifyテーマストアにおける最速で機能充実のテーマを作成することができました。

Webパフォーマンスに関しては、型どおりのソリューションはありません。たしかに、開発において適用できるベストプラクティスはあるでしょう。しかし、現実においては、それぞれのプロジェクトに固有の解決策を見極める必要があります。適切なツールと知識を使うことで、プロジェクトにおける最大のボトルネックを見つけ出すことができ、パフォーマンスにとってインパクトが一番大きい修正に注力できるのです。

今回は、Narrative作成時にShopifyテーマチームがパフォーマンスをどのように検討したかを紐解いていきたいと思います。そして、それと同じようにみなさんのプロジェクトでパフォーマンス上の重大なボトルネックを特定して対処するための方法を詳しく見ていきます。

パフォーマンスバジェットの設定

パフォーマンスバジェットは、プロジェクトに必要十分な速度を定義するためのパフォーマンス指標の集まりです。これは重要な制約であり、チーム全体が同意したうえでプロジェクト全体を通じてつねに頭に入れておくべきものです。

デスクトップChrome SpeedIndexSpeedCurveパフォーマンスバジェットの図

パフォーマンスバジェットには、さまざまな形や規模が考えられます。詳細なドキュメントになる場合もあれば、紙に書かれたいくつかの基本指標のみという場合もあるでしょう。チーム全員で時間をとって指標に合意し、そしてより重要なこととして、この合意事項を忘れないために常に目に見えるようにしておきます。

Apple iPhone6、3G接続 デスクトップChrome、ケーブル接続
Speed Index < 5000ms < 2000ms
First Render
< 1600ms
< 1000ms
Total JS < 150kb min+gzip < 150kb min+gzip
Total CSS < 40kb min+gzip < 40kb min+gzip


Shopifyが
Narrativeを構築したとき、バジェット指標はGoogle Rail ModelGoogle LighthouseWebPageTestの推奨事項に影響を受けていました。さらにバジェットは前回のテーマにおける到達点から大きく改善されています。

パフォーマンスバジェットの設定時に重要なことは、テーマが閲覧される環境について考えられるだけのデバイスやネットワーク接続の多様性を考慮することです。ハードウェアの処理能力はハイエンドとローエンドのデバイス間で大きく異なるため、指標に関しては詳細に決める必要があります(例:「iPhone 63G接続」「Moto G3G接続」など)。

パフォーマンスデータの収集

パフォーマンスバジェットの設定ができたら、プロジェクトをそれといかに比較するかを意識する必要があります。

パフォーマンスデータは、ボトルネックの特定と意識の向上という点ではとても重要です。それによってパフォーマンス改善のインパクトレベルを測定することができ、あるソリューションの有効性を主張するうえでの確かな根拠ともなります。パフォーマンスデータの収集は、プロジェクトのパフォーマンスを考慮する際にもっとも重要なプラクティスとなります。

パフォーマンスに対しての意識向上を図るため、Narrativeの開発中にShopifyが使っていたお気に入りのパフォーマンスデータ収集ツールをここでご紹介しましょう。

Google Lighthouse

15秒程度で、Google Lighthouseはハイレベルなパフォーマンス検証をどんなWebページに対しても実行します。結果は簡潔なテキストで表示されるため、PageSpeed Insightsと同様にLighthouseの学習曲線は小さいです。画像、ウォーターフォールチャート、円グラフなどはありません。詳細ドキュメントのリンクが付いた、簡単に読めるテキストの指標となっています。

Google Lighthouseは、テーマのSpeed Indexに関する迅速なパフォーマンス実験をおこなう際には頼りになるツールでした。プロジェクト全体にわたってソリューションを実施する膨大な時間を投じる前に、そのソリューションから得られる改善レベルを素早く確認することができました。

さらに素晴らしいことに、 LighthouseChrome DevToolsに統合されています。

SpeedCurve

WebPageTestのようなサービスを検証のために使用し、何も変更点がないにもかかわらず毎回違うテスト結果を得た経験はないでしょうか?パフォーマンス検証には多様な因子があり、結果としてエラーの変動範囲が広がります。

SpeedCurveは、WebPageTestのデータを保存して繰り返し表示するため、テストのばらつきを防ぐことができます。テスト結果の異常値を検出できるので、より正確な指標を得られます。SpeedCurve1日に少なくとも1度のテストとパフォーマンス結果の表示をおこなうため、プロジェクトのパフォーマンスについて最新の記録を追跡することが可能です。

SpeedCurveNarrativeの開発期間を通じて使用価値がとても高く、新機能をマージしたときのパフォーマンス指標としてコンスタントに参照できました。おかげで、重大なパフォーマンスの問題を引き起こす変更をつねに把握することができ、プロジェクトをパフォーマンスバジェット内に収めることが可能となりました。

Chrome DevTools

パフォーマンスに真剣に取り組み、すべての問題の原因を正確に把握したいなら、Chrome DevToolsが最適です。テーマを深く検証するツールがほとんど揃っていますし、新機能が数ヶ月ごとにリリースされるため常に改良されています。

あまりに大量の機能があり学習曲線は険しいですが、幸いなことにGoogleDevToolsのためのドキュメントに時間をかけて充実させています。

Narrativeの開発中、DevToolsはパフォーマンスのボトルネックになっているコードを正確に把握するため、全般的に活用されていました。また、アニメーションの低フレームレートやスクロールジャンクのソースにおけるランタイムパフォーマンスをテストするうえでも優れたツールです。

パフォーマンスデータを分析してインパクトの大きいソリューションを見つけ出す

さて、プロジェクトの動脈を流れるデータが取れるようになったので、それらが何を意味しているか解明する時間です。パフォーマンスバジェットに戻り、そこの指標と収集したデータを比較してみましょう。パフォーマンスバジェットに沿っていない指標は何でしょうか?どの指標が一番遠いものになっていますか?

改善が必要な重要指標を選択し、コアコンポーネントに分解しましょう。たとえば、First renderは、サーバーのレスポンスタイムとクリティカルレンダーパスの複合的な指標です。クリティカルレンダーパスは、さらにほかの指標が組み合わさっています。こうした水面下にある指標を理解し、どのコードが影響をおよぼしているか特定する必要があります。これらの指標をほかのプロジェクトと比較してみましょう。改善はされていますか?もしそうならどれくらいでしょうか?このようにしてパフォーマンスのボトルネックを発見します。

ボトルネックが特定できたらソリューションの実験を開始します。テストの検証にDevToolsLighthouseを使いましょう。どのソリューションがもっとも速く簡単でしょうか?20%以上の改善が得られるのはどのソリューションですか?インパクトレベルを測るには、最小の仕事で最大の改良が見られるかどうかを判断します。

特定のボトルネックへの実験にフォーカスすることで、パフォーマンスワークは方向性を持ち、ほかのソリューションとの比較が可能になります。特定のボトルネックに影響を与えるものを深く理解できるようになると、可能性のあるソリューションのインパクトレベルを評価しやすくなります。

Narrativeの検証においては、以前リリースした無料テーマと比較しながら、いくつかのボトルネックを特定しました。そこでもっともインパクトが大きいと判断したソリューションを以下に記載します。

1. レスポンシブ画像

一般的に広く認識されているWebパフォーマンスの原則として、送信されるデータ量が少ないほど、ページの読み込み速度が速くなる、ということが挙げられます。Webページの肥大化はインターネット全体に広がり続ける問題であり、Webページサイズを小さくする機会があるならそれは必ず勝機となります。Webページのサイズ縮小は、Speed IndexとFirst renderに影響をおよぼします。この2つの指標は、Shopifyがパフォーマンスバジェットで重視していたものです。

データ分析においていくつかのテーマはページごとに4MB以上の画像データがあることがわかりました。このサイズではページ上のすべての画像を3G接続でダウンロードすると最大で45秒かかります。もっとうまくやれるはずです!

画像ページ(紫色)とそれ以外のアセットの重さの比較

レスポンシブ画像を使用すると、モバイルユーザーを考慮しながらもテーマ全体で節約できるデータ総量の比重の大きさゆえに、ハイレベルなインパクトが約束されます。HTMLCSSJSなど、ほかのアセットの最適化によって節約できる数KBのデータに比べると、レスポンシブ画像が提供するデータサイズ縮小の機会は、数百KBに及びます。

Narrativeのデモストアでは最初のレンダリングタイムが最大で50%下がり、ページサイズが全体で85%削減できました。

2. 画像のレイジーローディング(遅延読み込み)

Speed Indexを向上させるためのもう1つの方法として、画像が読み込まれる順番を検討しました。ページの中程にある画像がトップにある画像より先にダウンロードされていることに気づきました。その結果、表示優先度の高いコンテンツのレンダリングに時間が長くかかり、Speed Indexを遅くしていました。

画像ダウンロード優先順位の不適切なウォーターフォールの例

ダウンロード画像の優先順位を決めるために、レイジーローディングというテクニックを使う必要がありました。レイジーローディングにより、ダウンロードする画像の順序とタイミングをコントロールできるようになります。このコントロールを追加することで、デバイス上で必要な画像のみをダウンロードさせることが可能です。

たとえば、ユーザーがホームページに着いてすぐにナビゲーションメニューから別のページに移るのであれば、なぜホームページの残りの画像をダウンロードする必要があるのでしょうか?それは帯域幅の無駄使いになるのでは?すぐに目にする画像や次に見ることになる画像のみをダウンロードするよう制限することで、デバイスがダウンロード処理する画像データの量を削減が可能となります。

画像のレイジーローディングで可能なもう1つの優れたテクニックは、プレースホルダー画像を使うことです。これもSpeed Indexの減少に結びつきます。まず低品質画像(300px)を素早く表示させ、ダウンロードができたら高品質画像を表示させる方法としてプレースホルダーを利用しました。

レイジーローディングは基本的にJavaScriptによって実現でき、少し調べればいろいろなライブラリがすぐ見つかると思います。Shopifyは画像のレイジーローディングを処理するためにLazySizesというオープンソースのライブラリを選択しました。とても軽くレスポンシブ画像も扱えるという利点があります。

3. クリティカルスタイルと非同期CSS

Webブラウジングにおいて、ページの読み込みはデバイスのCPUをもっとも消費させるタスクです。ブラウザがページをレンダリングする過程は、クリティカルレンダリングパスとして知られています。Google クリティカルレンダリングパスについての優れたドキュメントを用意しているので、詳細を知りたい場合はこちらをご覧ください。

最初のレンダリングまでに55%以上のCPUがアイドル状態になっていることをテーマの検証中に発見しました。これが何を意味するのか最初はわからず、不気味にさえ思いました。ページを読み込む重要なタスクの最中に、なぜCPUが何もしないままでいられるのでしょう?

CPUがレンダリングをブロックするアセットのダウンロードを待つ間にアイドルになっていることを示すチャート

いくつかのリサーチの後、外部のレンダリングブロックファイルによるリクエストをブロッキングする簡単な実験をおこない、CPU使用の差異をChrome DevToolsで観察しました。レンダリングを開始する前にHTMLドキュメントとメインのCSSファイルをダウンロードするのを待っているため、CPUはアイドル状態にあることがわかりました。外部のCSSファイルを除外したところ、デバイスはHTMLのダウンロードが終わり次第レンダリングを開始することができました。

ページのスタイリングのためにはメインのCSSファイルが必要で、そこに疑問の余地はありません。では最初のページレンダリングをブロックすることなく、そのファイルを使用し、非スタイルコンテンツのフラッシュ(ブラウザデフォルトのスタイリング前のコンテンツが一瞬表示される現象)を避けるにはどうしたらいいのでしょうか?解決策はクリティカルCSSを組み込み、外部CSSを非同期でロードすることでした。

NarrativeはメインのCSSファイルから手動でスタイルをコピー&ペーストしてLiquidスニペットに移すという方法でクリティカルスタイルにアプローチしました。このアプローチは、PenthouseCriticalCSSなどのライブラリを使う洗練された方法に比べると柔軟性に欠けますが、時間内で可能な最良の方法でした。このクリティカルスタイルへのアプローチは、テーマの将来にとって良いことであると自信を持っています。

4. JavaScriptのクリーンアップと最適化

機能性豊かなホームページということをテーマの売りポイントにしたいと、Narrativeのデザイナーは明確に目標設定していました。デベロッパーからすると、「機能性豊か」というのはJavaScriptが重いことだと捉えられます。

大量のJS起動時のパフォーマンスの低下につながり、最終的にページのレンダリングとインタラクティブ性を遅らせることになります。以前リリースしたテーマの検証により、ShopifyはテーマのJavaScriptへのアプローチ次第で改善の余地があると理解していました。Narrativeにおける目標として、クリーンで軽いJSを開発することに重点を置きました。

ページ読み込みをJSが引き継ぐ箇所の例

「軽い」というのはどういうことでしょうか?この表現はしばらくの間、フレームワークやプラグインに関してフロントエンドの界隈でよく聞かれたものです。軽さとは以下の3つのポイントに要約できます。

・ジョブの遂行にあたってできる限り少ないコードを使用している

・必要なときの直前またはページのアイドルタイムにコードを実行する

・強制的なDOMの再計算を最小限におさえる

これらのルールは以下のようないくつかの方法で明示することができます。

・プロジェクトで使用しない機能がたくさん入っているライブラリは避ける

・ページ読み込み時に実行されるJSの量を少なくする

・トリッキーなレイアウトを組む際にはJSではなくflexboxを使用する

JSを知れば知るほどクリーンで軽量なコードを書くようになります。Kyle SimpsonsYou Don’t Know JSシリーズや、Frontend Mastersの講座をチェックすることをお勧めします。

5. スクロールハンドラの最適化

スクロールハンドラはブラウザが提供するもっとも魅力的な機能ですが、残念ながら同時にもっとも危険でもあります。スクロールジャンクは、スクロールハンドラの誤用によって引き起こされる、目立ちやすく不快なサイドエフェクトです。

Narrativeはスクロールに関していろいろな動きを実装しています。スクロール連動アニメーション、スティッキーヘッダー、スティッキーエレメント、レイジーローディング画像など。これらのスクロールが組み合わさって目立ったジャンクな事象を引き起こさないように注意を払い、1秒で60フレームのなめらかな動きをページごとに実現しています。

Paul Lewisは彼の記事「入力ハンドラのデバウンス」においてこのトピックを広範囲に取り上げています。

デザイナーと開発者のコラボ

NarrativeデザイナーのGuillaume Grangerは、Narrativeを機能性豊かで商品のストーリーを語るのに適したホームページになるようにデザインしました。本質的にこうした追加機能がもたらしかねない重さのため、効率の良い体験への要求はより重要性を増していました。

デザインフェーズにおける開発者との連携は成功のためには不可欠でした。効率性に配慮して実現可能なデザインになっていることは両サイドにとって重要なのです。Guillaumeはこう言っています。

「非凡な体験を生み出すためのすべての努力は、実行の段階で少しでも瑕疵があれば崩壊してしまいます。パフォーマンスとブラウザの互換性は犠牲にできないものです。」

その結果、パフォーマンスという観点でのどの部分によりフォーカスすべきなのか、そして効果的な行動を実現するためにデザインのどんな修正が必要なのか、その点への意識が高まりました。

SpeedCurveの創設者Mark Zemanは実用的なデジタル体験のためにデザイナーが果たすべき役割について多くを語っています。「速くてリッチなユーザーエクスペリエンス」はおすすめです。

インパクトをもたらそう

Webパフォーマンスに関して、型どおりのソリューションはありません。個々のプロジェクトは固有のパフォーマンスのボトルネックを持ち、それらは個別の見極めを必要とします。適切にツールを用いることでプロジェクトの最大のボトルネックを発見できます。

プロジェクトのボトルネックを特定できたら、次のことを忘れないようにしましょう。

・目標設定のためにパフォーマンスバジェットを作成する

・頻繁にパフォーマンスデータを収集する

・パフォーマンス指標とその基礎コンポーネントを探究する

1つの問題に対して複数のソリューションを実験する

・インパクトレベルによってソリューションを優先付けする

・パフォーマンスに関する発見を同僚とシェアする

・ほかの部署と連携し、パフォーマンスを考慮して彼らの仕事のレベルアップに貢献する

あなたのテーマのパフォーマンスでボトルネックになっていることは?

Shopifyコミュニティで教えてください!

原文:Thomas Kelly 翻訳:深津望

 

Shopifyパートナープログラムでビジネスを成長させる
マーケティング、カスタマイズ、またはWebデザインや開発など提供するサービスに関係なく、Shopifyパートナープログラムはあなたを成功へと導きます。プログラムの参加は無料で、収益分配の機会が得られ、ビジネスを成長させる豊富なツールにアクセスできます。情熱的なコマースコミュニティに今すぐ参加しましょう!

今すぐ登録