wwwave'sTechblog |ウェイブのエンジニアブログ

株式会社ウェイブのエンジニアによるテックブログです。会社の話や Ruby、Vue.jsについてなど技術的な話をしていきたいと思います。

Coolmic webサイトパフォーマンス改善してみた 〜 FP 1秒への道 〜

f:id:sys_wwwave:20200331184540p:plain

はじめに

ウェイブのKSです!!
弊社運営サイト、Coolmic では、Webサイトパフォーマンス改善がミッションとなりました。
今回は、初回対応として、影響範囲が狭く、大きな成果が出る方法で対応を行いました。

事前知識

適切なwebサイトパフォーマンス改善を行うため、最低限必要な知識は以下かと思います。

レンダリングの仕組みについては、ぜひ、前回の記事も合わせてご覧ください🤗

目標

具体的なミッション内容は以下です。

  • ミッション:TopページのFPを1秒にする。

サイトアクセス時、画面が真っ白な時間がかなり長いため、FP改善が目標となりました。
要件としては、ファーストビューを早くし、読み込み中とユーザーに認識させることです。

現状把握

PageSpeed Insights

まずは、目標とのギャップの確認です。
3秒以上の改善が必要とわかりました。

点数 FP
f:id:sys_wwwave:20200331155241p:plain f:id:sys_wwwave:20200331155254p:plain

Chrome DevTools Performance

次に、どこに原因があるかの調査を行いました。
今回は、外部リソース(JS)のダウンロード、実行までが大半を占めていることが判明いたしました😓

f:id:sys_wwwave:20200331160035p:plain

外部リソースの正体

以下のように属性未指定で使用しているscriptタグでした。 HTML Parseをブロックしているため、main.jsの実行が完了するまで、画面が真っ白な状態になっておりました😨

<script src="//en-assets.coolmic.me/main.js"></script>

改善方法検討

要件を満たしつつ最適な改善を行うため、以下の案で対応を行いました。

  • main.jsを非同期ダウンロード、実行にする
  • ファーストビューのデザインはSSRにする

すべてVue.jsでCSRをしていたため、ファーストビューで必要なデザインはSSRで対応致しました。
具体的な対応イメージは以下となります。

f:id:sys_wwwave:20200331165530p:plain

改善結果

PageSpeed Insights

気になる点数は、一気に跳ね上がりました🙌
ただし、残念ながら一発では目標となる数値には届かず。。。
別途、改善が必要となります。

点数 FP
f:id:sys_wwwave:20200331163903p:plain f:id:sys_wwwave:20200331163915p:plain

Chrome DevTools Performance

無事に、目標通りの結果となっております。
main.jsの実行前に、FPのタイミングとなりました。

f:id:sys_wwwave:20200331164116p:plain

おわりに

初回対応としては、いい結果になったかと思います。
改善結果が数値として出てくるのは嬉しいですね。
ただ、ここからの改善がなかなかやっかいです💪

初回アクセス時の体感は早くなったかと思いますが、改善が必要な箇所はまだまだあります。
現在、サイト全体のSPA化移行も行なっているので、別途ご紹介できたらと思います😀

質問、大歓迎ですので、お気軽にコメントしていただけたらと思います!!!

ブラウザレンダリングの仕組み

ウェイブでエンジニアをしているKSです!

本記事では、Chrome DevTools を用いてレンダリングプロセスをご説明致します!

参照サイトとして、私が所属してるプロジェクトCoolmic(スマホ版のみ)を使用致します。
※ 2020/02/15 時点でのレンダリングの流れとなります。Coolmic では、現在、パフォーマンス改善を行っており、レンダリングの流れが変わる可能性がありますのでご了承ください。

f:id:sys_wwwave:20200304112008p:plain

web エンジニアの方は、自社サイトなどと照らし合わせながら本記事を読んでいただけると、イメージ湧きやすいかと思います!!

はじめに

Coolmic では、サイトパフォーマンス改善がミッションとなりました。 しかし、レンダリングの仕組みを断片的にしか把握していなかったため、適切な改善が行えない状況でした。 そこで、パフォーマンス改善前にレンダリングの仕組みを勉強し、社内勉強会を開催したため、その発表内容の一部を本記事にまとめました!

DevTools は回線を Fast 3G にしております!

注意事項

DevTools の使い方に関しては、本記事では説明致しません。
メルカリの記事が大変参考になりますので、ご参照ください。

また、パフォーマンス指標の FCP のタイミングまでのレンダリングプロセスについてまとめております。
パフォーマンス指標に関しても説明致しませんので、ご了承下さい。

レンダリングの仕組み

全体把握

◆ プロセス

大きく4つのプロセスがあります。
ただ、Painting の後に Scripting のプロセスが実行されることもあります。
以下の流れは一例と思っていただいて問題ありません。

f:id:sys_wwwave:20200303182838p:plain

◆ 全体イメージ図

f:id:sys_wwwave:20200303200745p:plain

1. Download HTML(Loading)

レンダリングに必要な HTML のデータをダウンロード。
※ 時系列をわかりやすくするため、あえて HTML のダウンロードのみ項目を分けました。

f:id:sys_wwwave:20200303114118p:plain

↓ 拡大

f:id:sys_wwwave:20200303114410p:plain

2. Loading

2-1. Parse

レンダリングエンジンが処理しやすいデータ構造体にデータ変換。

  • HTMLファイル → DOM Tree
  • CSSファイル → Style Rules(CSSOMツリー)

◆ DOM Tree

f:id:sys_wwwave:20200303194438p:plain

◆ Style Rules

f:id:sys_wwwave:20200303194456p:plain

◆ Devtools

f:id:sys_wwwave:20200303114845p:plain

2-2. Download Resources

リソース(Javascript, CSS, Image)のダウンロード。

◆ Devtools

f:id:sys_wwwave:20200303114852p:plain

3. Scripting

Javascript が実行されるタイミング( = レンダリングブロック )。
Evaluate Script のタイミングで Javascript が実行されている。

◆ Devtools

f:id:sys_wwwave:20200303114845p:plain

↓拡大

f:id:sys_wwwave:20200303124805p:plain

★レンダリングブロックについて

ここで、一度レンダリングプロセスから話を脱線致します。
先ほどの Loading フェーズで、Parse 完了までの時間が長いと感じた方も多いかと思います。
私自身もその一人です。

Q なぜ、FCP までの時間の大半を占めているのか🤔
A レンダリングブロックされているから😇

f:id:sys_wwwave:20200303154552p:plain

では、具体的に、何がレンダリングブロックに繋がっているというと、各リソース(HTML, CSS, Javascript)すべてが原因なり得ます。

◆ HTML, CSS の場合

レンダリング ツリーを構築するために DOM と CSSOM の両方が必須です。
そのため、HTML と CSS の両方がレンダリング ブロック リソース と言えます。

ファーストビューで不必要なデータを含めず、できるだけ早くレスポンスを返すことができるようにすることが重要です。
PageSpeed Insights でも重要なcssはインラインで配信することをおすすめされております。

◆ Javascript の場合

script タグを適切に使用しないと、大幅なレンダリングブロック発生原因となります。
重要なのは、属性の種類です。

サイト仕様に合わせて、async or defer どちらかを適切に使用することが重要です。

各属性のJavascriptダウンロード、実行タイミングが時系列でわかるこちらの記事も合わせてご参照いただけるとわかりやすいです。

属性 Javascript実行タイミング
なし(デフォルト) Parse をストップさせ、ダウンロード完了後、即座に実行される。
async 非同期でダウンロード完了後、即座に実行される
defer 非同期でダウンロードし、Parse 完了を待つ
Parse 後かつ DOMContentLoaded 前に実行される

4. Rendering

4-1. CalculateStyle

DOM Tree と Style Rules を紐づけて、Render Tree 生成。
具体的には、どのスタイルがどの要素に適用されるのかをマッチングさせる。

◆ Render Tree

f:id:sys_wwwave:20200303194639p:plain

◆ Devtools

f:id:sys_wwwave:20200303120201p:plain

↓拡大

f:id:sys_wwwave:20200303120223p:plain

4-2. Layout

Render Tree を元に、要素の位置と大きさの情報を考慮した Layout Tree 生成。
以下の影響するプロパティーの変更があった場合に呼ばれる。

height, width, padding, margin, top, right, left, bottom, box-shadowなど

◆ Layout Tree

f:id:sys_wwwave:20200303194818p:plain

◆ Devtools

f:id:sys_wwwave:20200303120201p:plain

↓拡大

f:id:sys_wwwave:20200303120324p:plain

5. Painting

5-1. Paint

画面上への描写指示、Paint Records の作成。
並列で、Layer Tree も作成。

◆ Paint Records

Layout Tree を元に、要素の重なり(z-index)を考慮した Paint Records を生成。

f:id:sys_wwwave:20200303194841p:plain

◆ Layer Tree

Layout Treeを元に、Layer Tree(レイヤーツリー)を作成します。
Layer の分離は要素の変更の際の計算量を少なくする。

f:id:sys_wwwave:20200303194922p:plain

◆ Devtools

f:id:sys_wwwave:20200303120201p:plain

↓拡大

f:id:sys_wwwave:20200303120420p:plain

5-2. CompositeLayers

Main Thread に代わって Compositor Thread が実行。
まず、先程の作成した Paint Records を元に各レイヤーのピクセル単位で色を当て込んでいきます。
ラスタライズが完了したレイヤーは一つの合成レイヤーにまとめられ最終的にGPUに渡され画面に表示されます。

Painting の処理完了後、サイトが描画されます!

◆ Devtools

f:id:sys_wwwave:20200303120201p:plain

↓拡大

f:id:sys_wwwave:20200303120448p:plain

おわりに

レンダリングプロセスのどこに時間がかかっているか把握することができました🤗
最良なパフォーマンス改善を行うためには、仕組みの理解が大切だと改めて感じました。

また、パフォーマンス改善内容はサイトによって様々だと思いますので、目標設定に応じた適切な対応が必要です。

次回予告

Coolmic パフォーマンス改善してみた 〜 FP 1秒への道 〜

参考サイト

トップに戻る