本記事では、この2年間で国際サイトの店舗が体験最適化において行ってきた取り組みと探求をまとめました。そして、良好な成果を上げてきましたので、これを共有することで、他の同様のシナリオにも役立つことを願っています。
パフォーマンス最適化は、大きく分けてネットワークパフォーマンス最適化とインタラクション体験最適化の2つに分類できます。
- インタラクション体験最適化:ページのインタラクション体験を最適化します。スクロールがスムーズか、クリックのフィードバックがタイムリーか、操作にラグがないかなど。
- DOMの再描画と再レイアウトを避ける
- DOM操作は可能な限り減らすか、操作を統合する
- アニメーション要素は、
absolute
などのドキュメントフローから外れた配置を可能な限り採用する
- ユーザー操作へのフィードバックをタイムリーにし、リフレッシュレートを60fpsに保つ
- 各JSタスクが1000/60=16.67ms以内に完了するように保証する
- 複雑な計算はワーカープロセスに任せる
- DOMの再描画と再レイアウトを避ける
- ネットワークパフォーマンス最適化:ほとんどの場合、ファーストビューのパフォーマンス最適化を行います。
- TTFB(Time To First Byte)の時間を短縮する
- DNSクエリ、TCPハンドシェイク、SSL接続の確立を減らす
- 302リダイレクトを避ける
- バックエンドのRT(応答時間)を短縮する
- リソースダウンロード時間を短縮する:HTMLコンテンツの削減、gzip圧縮の有効化など
- フロントエンドのブロッキングリソースの読み込み時間を短縮する
- 同期CSSリソースを減らす
- 同期JSタグを避ける
- 適切なキャッシュを追加する
- ServiceWorkerなどの手段による事前読み込みとプリレンダリング
- TTFB(Time To First Byte)の時間を短縮する
国際サイトの店舗に具体的に適用すると、ユーザーのバックエンドで構築され、フロントエンドのシナリオを生成するページでは、最適化において、依然として上記の方針に従っています。以下に、店舗の実際の状況を考慮した上で、体験最適化に関して行ったいくつかの試みを紹介します(コンプライアンス上の問題により、一部のビジネスデータは匿名化されています)。
ネットワークパフォーマンス最適化策
PC店舗 - 装飾バックエンド画像最適化
背景
店舗は、販売者が自分でページを構築できるシナリオです。多くの販売者は、背景画像をアップロードすることで店舗の美観を高めることを好みます。しかし、これらの画像は非常にサイズが大きく、1920 * xxxサイズの画像は1MB以上になり、Wi-Fi以外のネットワーク環境では読み込みが遅くなります。
解決策
この最適化は、単純な画像圧縮では解決できません。多くの場合、圧縮すると画像が著しく劣化し、販売者からクレームのチケットが発行されるためです。そのため、画像のサイズを削減するための別の方法が必要でした。観察すると、ほとんどの場合、背景画像の中央部分は通常のモジュールで覆われており、フロントエンドで見えるのは、中央モジュールの表示幅以外のコンテンツであることがわかります。そこで、画像の中央部分を単色で覆うことを試みました。これにより、ユーザーがアップロードする背景画像のサイズを大幅に削減できます。
実装の原理は非常にシンプルです。背景画像をcanvasに描き、その中央の1200px幅の部分を単色で塗りつぶします。コアとなる実装コードは以下の通りです。
/**
* 用纯色填充指定区域
*/
coverArea (canvas) {
const { coverColor, coverWidth } = this.props
if (!this.state.needCover) {
return canvas
}
const w = canvas.width
const h = canvas.height
const ctx = canvas.getContext('2d')
const gap = (w - coverWidth) / 2
// 清除中间 1200px 部分的内容
ctx.clearRect(gap, 0, coverWidth, h)
ctx.fillStyle = coverColor
// 用给定的颜色填充中间 1200px 的内容
ctx.fillRect(gap, 0, coverWidth, h)
return canvas
}
テストの結果:1920 * 1080ピクセルの詳細な風景画像(JPEG形式)の場合、元の画像は1.6MBでしたが、トリミング後は464KBとなり、元のサイズの約30%(464/(1.6*1024)=0.2832)に削減され、大幅な改善が見られました。以下の図をご覧ください。
最適化後、ページの表示速度が向上するだけでなく、CDNのトラフィック消費も軽減され、一石二鳥の効果が得られます。
PC店舗 - サードパーティモジュールユーザーパフォーマンス最適化
背景
現在、サードパーティテンプレート1の静的リソースは、AliyunのCDNを使用しており、ドメインは shopmod-icbu.alicdn.com
です。海外ノードが少なく、リソースの読み込みが遅いため、ユーザー体験に影響を与えています。
そのため、より多くの海外拠点を持つAkamaiサービスプロバイダーのCDNを介して転送することで、海外ユーザーがサードパーティテンプレートの店舗にアクセスする速度を向上させ、サードパーティテンプレートを利用する販売者のユーザーアクセス体験を向上させることを試みました。
解決策
shopmod-icbu.alicdn.com/1dbb3279357007484e7778d9a1060811/web-index.css
を http://i.alicdn.com/@shopmod/1dbb3279357007484e7778d9a1060811/web-index.css
に置き換え、i.alicdn.com が転送を行うようにしました。
店舗のフロントエンドのJSファイルは、shop-render
が参照するintl-mod-loader
によって非同期で読み込みが制御されています。
セカンダリモジュールの場合、ownType
は*
であり、リソースアドレスはshop-render
のconfigによって決定されます。
サードパーティモジュールの場合、ownType
は**
であり、リソースアドレスはサードパーティモジュールのmodule-data
内のmdsのassetsCss
、assetsJs
によって決定されます。モジュールデータのassetsCss
、assetsJs
アドレスはバックエンドアプリケーションで変更されます。
効果
ファーストビューは以前の最適化に加えてさらに**12.4%削減され、滞在時間も4.6%増加し、直帰率は5.2%**低下しました。
PC店舗 - モジュール非同期化
背景
ホームページのバックエンドRTは、店舗全体または国際サイト全体と比較してやや長く、最終的にファーストビューの速度に影響を与えていました。
分析
店舗のホームページのバックエンドRTは**0ms
であり、全体のRTは**0ms
程度であることがわかります。したがって、ホームページのRTを削減することが改善の出発点となります。なぜホームページのRTが平均値をはるかに上回るのかというと、ホームページがユーザーによるカスタム装飾をサポートしており、モジュール数が固定されておらず、各モジュールのレンダリングとデータ取得に時間がかかるためです。
以前、バックエンドの同僚と一緒にレンダリングチェーン全体を追跡したところ、商品推奨関連モジュールのバックエンドデータ取得時間が長く、平均して1つのカテゴリモジュールに約**0ms
かかることがわかりました。もしユーザーがホームページに10個の商品推奨モジュールを装飾した場合、バックエンドRTだけで少なくとも**0ms
* 10(はい、私たちが導入しているミドルウェアのレンダリングロジックはすべてのモジュールを直列にレンダリングします)が必要となり、さらに**0ms
のネットワーク転送時間を加えると、TTFBは**0ms
になります。そのため、私たちが採用した最適化戦略は、カテゴリモジュールの非同期化です。
結果
まず、ユーザーの使用頻度が高いモジュールに対して非同期化改修を行い、リリース後に良好なデータが得られました。ファーストビューは約100ms改善されました。
全体のRT時間が短縮され、TTFBは約**12%**低下しました。
モバイル店舗 - WeexからReactアイソモーフィックへの移行
背景
古いモバイル店舗はWeexベースの非同期レンダリングページで、ファーストビューは**s+
でした。複雑な最適化作業を経て、かろうじて**s
程度に改善されましたが、開発効率に深刻な問題がありました。当時、詳細な分析を行った結果、モバイル店舗のフロントエンドアーキテクチャをアップグレードし、WeexからPC店舗と同じReactアイソモーフィックなH5店舗へ移行することを決定しました。
詳細な背景については、社内ネットワークに「ICBU店舗フロントエンドアーキテクチャの現状と進化の方向性」という記事を執筆しましたが、コンプライアンス上の問題があるため、ここでは公開しません。
解決策
モバイル店舗の状況は非常に複雑で、公式モジュールとサードパーティモジュールがあり、公式モジュールは50以上、サードパーティモジュールは数え切れないほど存在します。そのため、一度にリファクタリングを完了してからリリースすることはできず、運用しながら段階的に移行できる解決策が必要でした。店舗のモジュールはほとんどが純粋な表示を主とし、インタラクションの多いモジュールは補助的であるという背景を考慮し、私は2つの解決策を提案しました。
- Raxコード変換ソリューション
- その名の通り、RaxベースのWeexコードをBabelトランスパイラツールを使ってReactに変換し、モジュールの移行プロセスを加速するものです。
- Rax Reactハイブリッドレンダリングソリューション
- 余分なサードパーティモジュールや優先度の低いその他のモジュールについては、ハイブリッドレンダリングソリューションを通じて、新しいアーキテクチャの下で新旧両方のモジュールを直接実行し、モジュールが多すぎて移行できない問題を解決します。
結果
プロジェクト全体は2つのフェーズに分けて実施されました。
- フェーズ1では、単一のリストページを手動で移行しました。これは主に、ReactアイソモーフィックなH5ページがビジネス要件を満たせるかどうかを検証するためでした。
- フェーズ2では、前述の2つのソリューションを通じて、店舗全体を直接移行しました。
成果としては:
- フェーズ1
- パフォーマンス:リストのファーストビュー性能は、
***s
(最適化後のWeex)から***s
に向上し、**39.7%**削減されました。 - ビジネス面:リストのスクロール深度は**3.82%向上し、リストから詳細への遷移は4.3%向上、広義のABテストは3.2%**向上しました。
- パフォーマンス:リストのファーストビュー性能は、
- フェーズ2
- パフォーマンス:全体のファーストビューは、
***s
から***s
に向上し、**37.5%**削減されました。 - ビジネス面:SEOトラフィックは前日比で日平均**29.075%増加し、滞在時間は7.681%上昇、広義のABテストは18.673%**上昇しました。
- パフォーマンス:全体のファーストビューは、
ストリーミングレンダリング
いくつかの一般的な最適化ソリューションを実施した後、店舗のPCおよびモバイル側のパフォーマンスは***s
以内に収まりました。この時点で店舗のTTFBは約***ms
であり、まだ最適化の余地がありました。そこで、[ストリーミングレンダリング改修]を行いました。
ストリーミングレンダリングは、HTTP 1.1のチャンク転送エンコーディングの特性を利用し、サーバーがHTMLをチャンクに分けて返し、ブラウザが受信時にページを段階的にレンダリングできるようにするものです。これにより、ページのファーストビュー表示が促進され、ユーザー体験が向上します。
成果
PC店舗とモバイル店舗の両方でストリーミングレンダリングが順次導入され、バックエンドRTの大幅な低下により、TTFBはともに約***ms
削減されました。具体的な成果は以下の通りです。
- PC:
- パフォーマンス面:ファーストビューは約**8%**削減されました。
- ビジネス面:当時、リリース時にABテストを実施しなかったため、具体的なビジネスデータは観察されていません。
- モバイルサイト:
- パフォーマンス面:ファーストビューの時間が**8.69%**削減されました。
- ビジネス面:
- 平均訪問深度は相対的に**1.024%**向上しました。
- 平均訪問時間は相対的に**0.020%**低下しました。
- ワンステップABコンバージョンは相対的に**0.318%**向上しました。
- アプリ:
- ファーストビューは50%のグレースケール条件下で、約**7.2%**削減されました。
- ビジネス面:
- 訪問深度は相対的に**2.090%**低下しました。
- 訪問時間は**2.093%**低下しました。
- ワンステップABコンバージョンは相対的に**0.547%**向上しました。
同時に、ストリーミングレンダリングのエンジニアリング導入ソリューション [[流式渲染工程化]]も生み出しました。
インタラクション体験最適化
PC店舗 SPA改修効果
背景
PC店舗は元々、従来のバックエンドレンダリングによるマルチページアーキテクチャでした。各タブをクリックするたびに、通常のページレンダリングを行ってページを更新する必要がありました。 ストリーミングレンダリングや時間のかかるモジュールの非同期化など、多くの最適化ソリューションを実施してきましたが、ページを切り替えるたびにブラウザがページ全体をリフレッシュする必要があり、このような体験は依然として十分ではありませんでした。 そこで、PC店舗を再度アップグレードし、フロントエンドの手段を用いて擬似シングルページアプリケーションにしました。
解決策
既存のレンダリングソリューションは以下の通りです。
ブラウザがリクエストを送信
-> バックエンドがデータを取得
-> Reactアイソモーフィックサービスを呼び出してモジュールをレンダリング
-> アイソモーフィックな結果を完全な文字列として結合し、ブラウザに返す
-> ブラウザが静的リソースを解析・読み込み、ページをレンダリング
-> JS読み込み完了後、Reactでページ全体を再描画し、イベントバインディングなどの二次レンダリングを行う
-> レンダリング完了。
改修後のソリューションは以下の通りです。
成果
店舗のシングルページ改修リリース後のABテスト比較では、実験グループは対照グループと比較してファーストビューが約**5%削減され、ab_rateは相対的に1.5%向上し、直帰率は相対的に1.7%低下しました。 その後、プリロード機能がリリースされた後(ABテストは実施せず)、さらにパフォーマンスが向上し、ファーストビューは16%**削減されました。
モバイル店舗 - SPA改修 - タブデータプリロード
戦略
モバイル店舗タブプリロード:ホームページに1.5秒滞在した後、他の後続タブデータのプリロードを開始し、ユーザーがタブを切り替える際の体験を高速化します。
成果
リリース後、モバイルMサイトのファーストビューは約**20%**改善されました。
モバイル店舗 - ProductTab無限読み込み改修
背景
モバイル店舗のProductTabページは、元々一部の製品の概要のみを表示しており、さらに表示するには新しいページに遷移する必要がありました。以下の図をご覧ください。
新しいページに遷移するとユーザー離脱が発生するため、現在のページで直接すべての商品を無限に読み込めるようにすれば、理論的にはより良いユーザー体験が得られるはずです。なぜ以前にこれが実施されなかったのか疑問に思い、以前のモバイル店舗の担当者に相談したところ、元のWeex店舗のホームページはシングルページアプリケーションであったため、それ自体が大量のメモリを消費しており、Productページでさらに無限読み込みを行うと、デバイスのメモリに大きな負荷がかかり、クラッシュやフリーズを引き起こす可能性があるため、当時は新しいページを開いて対応していたとのことでした。
その後、店舗はH5改修を行い、Weexの技術体系を採用しなくなり、同時にビジネス上でも現在のページで商品を無限に読み込むという要望がありました。そのため、ProductTabの無限読み込み改修を実施しました。
解決策
無限読み込みによるメモリ負荷の問題を依然として懸念していたため、プロジェクトのリリースプロセス中に1ヶ月間にわたる実験を行い、同時に技術的な関連保障も行いました。
成果
最終的なABテスト比較では、ab_rateは相対的に1.288%向上しました。
まとめ
店舗は、体験最適化を開始した当初のPCとモバイルがどちらも十分に最適化されていない状況から、現在ではPCのファーストビューが最適化前の60%、モバイルが最適化前の37.5%となり、大幅な改善を達成しました。
この過程で、ストリーミングレンダリングを迅速に導入するソリューションも生み出しました。また、ビジネスデータにおいても、訪問深度、滞在時間、コンバージョンなど、良好な成果を上げています。
この過程で協力してくれた同僚と、上司のサポートに感謝します。
Footnotes
-
サードパーティのエコシステムデザイナーによって開発されたテンプレート ↩
この記事は 2021年4月29日 に公開され、2021年4月29日 に最終更新されました。1621 日が経過しており、内容が古くなっている可能性があります。