Quantcast
Channel: CSSタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 8660

Webページ表示速度高速化、始めます!

$
0
0

背景

  • 先週からWebページ高速化を勉強しはじめて、なんとか最初の改善リリースを終えました。
    • TOPページとLPをリニューアルしたのですが、表示速度が極端に低くなった(PageSpeed Insights で5/100点!)ため、急いでWebページ高速化に取り組まざるをえなくなった。最終的には数日程度で50点近くまで上げることができた。
  • とにかく急いでやったプロジェクトだったんですが、似たような状況に追い込まれた人のために、やったことを残しておきます。

やったこと

1. 「初歩からのPageSpeed Insights」 を読む

とりあえずまず以下の本を読みました。

重いサイトを軽くする、Webページ表示速度の高速化10の基本: 初歩からのPageSpeed Insights (にししふぁくとりー叢書)

  • Amazon Unlimitedに加入してれば無料で読める
  • 少ない分量でまとまっている。
  • 全部読まなくても、自分に関係がありそうな部分だけを拾い読む -> 可能な施策だけ着手 の流れが容易。

まずは、この本の内容と、自分のWebサイトのPageSpeed Insightsの結果を見比べて、効果がありそうなものから着手していきました。基本的な知識は全部この本で得られたので、この記事では、上記の本で足りなかったことを解説していきます。

2. 外部js, youtubeなどの超遅延ロード

超遅延ロードというのは私の造語ですが、 deferなどを用いた単なるjsの遅延ロードではなく、「Userが何らかのアクションをしたらロードする」というアクロバティックな遅延ロード手法です。この記事で紹介されてました。

うちのサイトの場合、tweetのjavascriptの埋め込みyoutubeの埋め込みが表示速度の悪化の大部分の原因を占めていたので、 これが最も効果があった施策でした。(あと、tweetとyoutubeはページのかなり下の方のコンテンツだったので、ロードを遅らせる合理的な理由もありました)

以下のコードで、Userの何らかのアクションに引っかけて、<script>タグや <iframe>などのDOMをinsertします。上記記事からコードの大部分をお借りしております。

lazy_load.js
(function(window,document){functioninsertResource(){// twitterの読み込みvartw_script=document.createElement('script');tw_script.type='text/javascript';tw_script.defer=true;tw_script.src='https://platform.twitter.com/widgets.js';document.getElementById('js-twitter-load').appendChild(tw_script);// 対象のページに<div id="js-twitter-load"></div> を埋め込んでおく// youtubeの読み込みvaryoutube=document.createElement('iframe');youtube.className="youtube__iframe";youtube.src="https://www.youtube.com/embed/xxxxxxxxx";youtube.frameborder=0youtube.allow="autoplay; encrypted-media"youtube.allallowfullscreenow=""document.getElementById('js-youtube').appendChild(youtube);// 対象のページに<div id="js-youtube"></div> を埋め込んでおく}// 遅延読込みvarlazyLoad=false;functiononLazyLoad(){if(lazyLoad===false){// 複数呼び出し回避 + イベント解除lazyLoad=true;window.removeEventListener('scroll',onLazyLoad);window.removeEventListener('mousemove',onLazyLoad);window.removeEventListener('mousedown',onLazyLoad);window.removeEventListener('touchstart',onLazyLoad);window.removeEventListener('keydown',onLazyLoad);insertResource();}}window.addEventListener('scroll',onLazyLoad);window.addEventListener('mousemove',onLazyLoad);window.addEventListener('mousedown',onLazyLoad);window.addEventListener('touchstart',onLazyLoad);window.addEventListener('keydown',onLazyLoad);window.addEventListener('load',function(){// ドキュメント途中までスクロールしている場合(更新時 or ページ内リンク)if(window.pageYOffset){onLazyLoad();}});})(window,document);

あとは lazy_load.js自体を通常の遅延読み込みで埋め込みます。

index.html
<script type="text/javascript"src="/js/lazy_load.js"defer="defer"/>

3. CSS と WebFont の遅延ロード

deferを使えば簡単にできるjavascriptの遅延ロードと違って、CSSの遅延ロードはちょっと面倒ですよね。
以下の記事で簡単な方法が紹介されていたので、活用しました。

CSSを非同期ロードする最も簡単な方法

media="print" onload="this.media='all'"を追加するだけ。便利。

以下は Uikitのcssを埋め込む時の例です。

index.html
<linkrel="stylesheet"href="https://cdn.jsdelivr.net/npm/uikit@3.5.9/dist/css/uikit.min.css"media="print"onload="this.media='all'"/>

WebFont(例:GoogleFontsの"Noto Sans JP")でも同様のことができます。
1. Google Fontsから 埋め込み用のタグを取得
2. media=”print” onload="this.media='all'"を追記する

index.html
<linkrel="preconnect"href="https://fonts.gstatic.com"><linkhref="https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;700&display=swap"rel="stylesheet"media=”print”onload="this.media='all'">

ファーストビューの描画に必要なCSSだけを同期的に読み込み、それ以外のCSSやWebFontは全部遅延読み込みにしてしまいます。

4. .webp形式の画像の導入

上記までの施策で、うちのサイトの点数はだいたい改善されたのですが、残ったのが画像の重さ問題。
PageSpeed Insightsがしつこく勧めてくるので、.webp形式の画像の導入を決めました。
.webp 形式は .jpg や .png より軽いのが利点ですが、対応していないブラウザも多いので、他の形式の画像と併用する必要があります。

<img>タグを使用している場合は、以下の書き方でOK。

index.html
<pictureclass="thumb"><sourcesrcset="/img/top/thumb.webp"type="image/webp"><imgclass="image"src="/img/top/thumb.jpg"loading="lazy"/></picture>

問題は CSSの background-image などで画像を指定している場合ですね。
modernizr.jsを使用することで、ブラウザの対応状況に合わせてCSSを切り替えることができます。詳しくは以下記事をどうぞ。

WebP(ウェッピー)を導入してみよう

5. Resource Hintsの使用

そこまでやる必要があるのかはよくわからなかったんですが、 Resource Hintsなるものを使うことで、必要になるであろうリソースを先にブラウザに伝えることができるようです。
今回の場合、ファーストビューのメインビジュアル画像をCSSのbackground-imageで指定してたので、HTML -> CSS -> 画像ファイルという3工程のリクエストチェーンになってしまうので、読み込み開始を早めるために使用しました。

index.html
<linkrel="preload"href="/img/top/mainvisual.webp"as="image">

これにより、ファーストビューのメインビジュアル画像のリクエストチェーンを HTML -> 画像ファイルの2工程に短縮できます。
体感でしかないけど、ファーストビューの表示がちょっとだけ早くなったような気はする。

結果

これだけやったところ、5/100点から50/100点にまでは上がったんですが、まだ Largest Contentful Paint(LCP) の点数が辛くてそれ以上にはならないようです。なんでなんや・・・。
もうちょっと勉強したらまた続きを書こうと思います。

参考


Viewing all articles
Browse latest Browse all 8660

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>