サイトを高速化したらロード時間は1.6秒に、Lighthouseは100を獲得、その際に実施した手順を解説
Post on:2019年12月17日
サイトのロード時間とパフォーマンスを改善するために再構築した結果、ロード時間が1.6秒に短縮され、Lighthouseのスコアで100を獲得した際に、実施した手順を紹介します。
HTMLとCSSベースの改善が主で、ロード時の数ミリ秒間の表示、スマホ用CSSファイルの分割など、いろいろなサイトやブログの改善にも役立つと思います。
当ブログにも改善すべき点があるのが分かったので、対応したいですね。
I rebuilt my portfolio🌻 Now it loads in 1.6s 🎉 Here's how I did
by Saurabh Daware
下記は各ポイントを意訳したものです。
※当ブログでの翻訳記事は、元サイト様にライセンスを得て翻訳しています。
はじめに
私の個人サイトは今までロード時間は4.2秒、パフォーマンスのスコアは43でした。このスコアを改善するため、私はサイトを再設計することにしました。
まずは、その結果から報告します。
ロード時間は1.6秒に短縮され、Lighthouse(Chromeの機能拡張)のスコアは100を獲得しました。サイトはバニラJavaScriptで構築し、外部スクリプトまたはスタイルシートは使用していません(Googleフォント用のものを除く)。
Lighthouseによる測定結果
注意: この記事は、個人サイトのロード時間を短縮することを目的としています。
※EコマースをバニラJavaScriptで構築することは素晴らしいアイデアではありません。
要約
サイトのパフォーマンスを改善するために、私がしたことは下記の通りです。
- rel="preload"を使用する。
1<link rel="preload" href="assets/css/index.css" as="style" media="all" onload="this.onload=null;this.rel='stylesheet'"> - CSSファイルをindex.cssとmobile.cssに分割し、スマホのみmobile.cssをロードさせる。
1<link rel="stylesheet" href="assets/css/mobile.css" as="style" media="screen and (max-width:768px)"> - 画像の遅延読み込み
- CDNを使用する(私が使用したCloudinaryは、リクエスト時に画像の幅を変更できるため、レンダリングする画像と同じサイズの画像をロードできます)。
- OffscreenCanvasを使用する(現在はChromeでしか動作しないため、あまりお勧めはしません。OffscreenCanvasは無視して、通常のスクリプトとしてサポートされていないブラウザにロードする回避策をいくつか試しました)。
改善方法 1: リソースのプリロード
ブラウザはリンクをクリックすると、そのリンク先のHTMLファイルの解析を開始します。<script>, <link>, <style>タグが検出されると、ドキュメントのペイントが変更されるため解析は停止します。つまり、初期ペイントがブロックされます。
リソースをプリロードすることにより、この初期ペイントをブロックすることなく、ファイルをロードできます。したがって、これらのファイルのロードは通常通りに開始されますが、ペイントはCSSやJavaScriptがロードされる前に作成されます。
超クールでしょ? まぁ、大きな力には大きな責任が伴います。サイトがロードされた時に、下記のようには表示されたくないでしょう。
ロードされた数ミリ秒間の表示
これはCSSをロードせずにペイントされているからです。最初の数ミリ秒間はこのように表示されます。
これを改善する方法はあるでしょうか?
私が実施した方法を紹介します。
ビジターがサイトをロードした時、最初に表示したいのは背景だけで、CSSがロードされたらコンテンツをロードするようにします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<head> <!-- Other head tags --> <link rel="preload" href="assets/css/index.css" as="style" media="all" onload="this.onload=null;this.rel='stylesheet'"> <style> html,body{ background-color: blue; } .lazyload, .main-container{ display:none; } </style> </head> <body> <header> <!--Header content --> <h1 class="lazyload">Hi, I am Saurabh welcome to my website!</h1> </header> <main class="main-container"> <!-- Main Content --> </main> <!-- Remaining HTML --> </body> |
こうすることで、メインコンテンツとヘッダの一部のテキストが非表示になります。
index.cssには、下記を加えます。
1 2 3 |
.lazyload, .main-container{ display: block !important; } |
これで<style>のルールを上書きし、コンテンツを表示します。
私が実際に使用したコードでは、テキストが表示される際にはアニメーションを伴うようにしました。
実際にはアニメーションで表示
改善方法 2: CSSファイルの分割
スマホ用のスタイルシートが多い場合は、そのコードをデスクトップ時にロードさせてもまったく意味がないので、スマホ用のCSSを分割するのは理にかなっています。
スマホ用のCSSファイルを分割するのは、簡単です。<link>タグのmedia属性で、一致するデバイスでのみCSSファイルをロードするように定義します。
1 2 |
<link rel="stylesheet" href="assets/css/index.css" as="style" media="all"> <link rel="stylesheet" href="assets/css/mobile.css" as="style" media="screen and (max-width:768px)"> |
このコードで、mobile.cssファイルはスクリーンサイズが(max-width:768px)に一致するデバイスにのみロードされます。
改善方法 3: 画像の最適化
画像の遅延読み込み
Chrome 75でloading属性が追加され、loading="lazy"が使用できるようになりました。
参考: Chromeに実装される新機能『loading属性』について解説、ついにブラウザがネイティブで遅延ロードをサポート
それまでは、私は以下のようにしていました。
1 2 3 4 5 6 7 8 9 10 11 12 |
<img id="projectimage-1" src="placeholder.webp"> <img class="lazyimage" data-cover="projectimage-1" style="display:none;" src="actualimage.webp"> <script> function loadProjectImage(e){ const image = e.target; document.getElementById(image.dataset.cover).src = image.src; } document.querySelectorAll('.lazyimage') .forEach(imgEl => imgEl.addEventListener('load', loadProjectImage)) </script> |
CDNの使用
CDNとはコンテンツ配信ネットワーク(Content Delivery Network)の略で、通常のサーバーよりも画像のレスポンスが速くなります。私が使用したCDN(Cloudinary)には便利なオプションがあり、最適化の高速化に役立ちました。
画像を.webpで提供することは、画像最適化の優れた手段です。Cloudinaryでは、.webpを使用して画像URLの.pngや.jpgを変更するだけで、webp画像を自動生成してくれます。また、URLでパラメーターを渡すことで画像のサイズを変更することもできます。
例えば、下記のような感じです。
1 |
https://res.cloudinary.com/saurabhdaware/image/upload/c_scale,w_500/v1552455020/saurabhdaware.in/projects/eotm-portfolio.webp |
「w_500」は、画像の幅を500pxするということです。この値を変更するだけで、どんな幅の画像にも対応できます。しかも、JavaScriptでこの値を動的に変更して、レンダリングとまったく同じサイズの画像を読み込むこともできます。
幅を500pxにした画像
【訳者注】この記事では生成した画像をキャプチャして掲載しています。
ボーナス: OffScreenCanvas
上記とは別に、私はOffScreenCanvasを使用してWebワーカーのヘッダアニメーションをレンダリングしましたが、OffScreenCanvasは実験的な機能であるため、実動にはまだ適していないと思います。
ライブラリを使用しないことで高速になったとは言いません。しかし、フレームワークを使用しないことで、どのファイルをプリロードし、いつどのファイルをロードし、どのようにバンドルするかを決めることができました。
ただし、ライブラリを使用してもサイトを高速化することはできます。適切に処理する必要がありますが、ポートフォリオのような小さいサイトの場合は、サイト全体よりもファイルサイズが大きいライブラリを使用しない方が合理的だと思います。
最後に、高速化した私のサイトを紹介します。
要素をホバーまたはタップすると、面白い効果が得られると思います。
sponsors