Webサイトを運営している皆さん、こんにちは。
FRONTL1NEを運営しているFL1NE(フライン)と申します。
まず皆さんに聞きたいのですが
「Webサイトの高速化正しくやれてますか?」
ページの表示速度が遅いなぁ〜と思って、GoogleのLighthouseやPageSpeed Insightsなどのベンチマークを利用してWebページのベンチマークをとると、このように低いスコアが表示されてがっかりしたことありませんか?
いろんなページのベンチマークをとっていると、意外に有名な企業のサイトなどでさえも高速化・最適化などには手が周りきらず、そのまま放置されていることに気づくこともあります。
そこで、今回の記事ではWebサイトを運営する人なら抑えておきたい、割と簡単にできるWebサイトの高速化・最適化手法を10点紹介します。
ではどうぞ!
コーディング関連
画像の遅延読み込み(Lazy Load) [Native Lazy Load]
(PageSpeedの「オフスクリーン画像の遅延読み込み」対策)
画面に表示されていない画像を画面に入ったタイミングで取得し表示する「画像遅延読み込み (Lazy Load[レイジーロード])」というものがあります。
Lazy Loadでは、ダウンロードする画像をそもそも少なくすることで転送量の削減と表示速度の改善に繋がります。
以前まではJavascriptなどで自前実装をする必要がありましたが、2019年8月にGoogleが「Native Lazy Load[ネイティブ レイジーロード]」という、Webブラウザ自体にLazy Load機能を持たせるという仕様を提唱し、2020年2月にHTMLのWeb標準機能となりました。
Native Lazy Loadの実装は簡単で、画像表示に使う<img>
タグ内にloading="lazy"
という属性を持たせるだけで実装ができます。
また、<img>
タグに限らず、<iframe>
や、<picture>
等の要素に対してもloading="lazy"
で遅延読み込みさせることができます。
詳細は公式ドキュメント (Native image lazy-loading for the web | web.dev)を読んでみてください。
各ブラウザの対応状況はCan I Useで確認できます。
WordPressの場合はGoogleが公式プラグインを提供しているのでそちらを使うのが便利です。
画像サイズの調整、最適化
やはりWebサイトで一番効いてくるであろう内容が画像のサイズ調整及び最適化です。
画像はPhotoshopのエクスポート機能を利用している様子で、そのままpngで保存すると5.93MBとなる画像がjpgで最適化をすると100分の1程度である58.74KBになります。
画像の最適化は以下のような内容が中心となります。 (最低限赤文字のはやった方がいい)
- 画像ファイルのフォーマット等を見直す (jpgやpngの出力設定を見直す。
(PageSpeedの「効率的な画像フォーマット」対策)
- 画像の表示解像度と画像ファイルの解像度を同一にする。
(PageSpeedの「適切なサイズの画像」対策) - RetinaなどのHiDPIに対応させる (
<img>
タグのsrcset
を利用する)
(PageSpeedの「適切なサイズの画像」対策) - 次世代フォーマット(WebP, JPEG XR, JPEG 2000)などで画像を配信する (動かないブラウザもあるので要注意)
(PageSpeedの「次世代フォーマットでの画像の配信」対策)
WordPressの場合はEWWW Image Optimizerというプラグインがオススメです。
<script>を<head>内に書かず<body>の閉じタグ直前に書く もしくは async/deferで読み込む
(PageSpeedの「レンダリングを妨げるリソースの除外」対策)
Javascriptなどを読み込む<script>
タグを<head>
内に書くと、該当するJavascriptの読み込みや実行が完了するまでレンダリングをブロックすることになるため、速度の低下に繋がります。
基本は</body>
の直前にまとめるか、asyncやdeferなどで非同期に読み込むようにしましょう。
(HTMLで必要となるスクリプトは仕方がないので<head>
内で読み込む)
以下の記事が参考となります。
結局scriptをどこで読み込むのかが正解なのか – Qiita
<script> タグに async / defer を付けた場合のタイミング – Qiita
フォントやCSSなどをプリロードする (レンダーブロッキングしないようにする)
(PageSpeedの「キー リクエストのプリロード」対策)
cssやフォントファイルなど<head>
内で読み込まれるリクエストを<link rel="preload">
を利用して、早い段階で読み込むようにします。
画像のソースコードのように<link rel="preload">
は実際に利用する時のコードとは別に事前に定義されている必要があります。
(画像では<link rel="stylesheet" href="style.css">
の前に<link rel="preload" href="style.css" as="style">
でスタイルシートを先読みしている)
ちなみにcssのスタイル読み込みで2回<link>
を使用するよりも、<link rel="preload" href="style.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
というように読み込み完了後にそのタグの内容を書き換えるみたいな若干トリッキーな実装をすることで1回にまとめることができます。
また、css内で利用しているフォントファイルも同様にフォントを利用するcssが読み込まれるよりも前に<link rel="preload">
で読み込みます。
FRONTL1NEでは<link rel="preload" as="font" type="font/woff" href="/wp-content/themes/luxeritas/webfonts/fa-brands-400.woff2" crossorigin>
と言ったような内容をWordPressテーマの<head>
タグ内に記載することでフォントの先読みをしています。
参考文献 : rel=”preload” によるコンテンツの先読み | MDN
Webフォントのロード中もテキストを表示させる。
(PageSpeedの「ウェブフォント読み込み中のテキストの表示」対策)
css内のフォント読み込みの際に@font-face
を利用している場合が多いと思いますが、その中で font-display: swap
というものを追加するだけです。
font-display: swap
を利用することでWebフォントの読み込みが終わった時点でフォントを変更すると言った挙動になり、Webフォントロード前にはシステムフォントが利用されることとなります。 (これにより早い段階でユーザーにテキスト情報を提供できます)
参考文献 : Ensure text remains visible during webfont load | web.dev
YouTubeの遅いiframe埋め込みを高速化する
YouTubeではWebサイトに動画を埋め込む手法として<iframe>
を利用した埋め込みが一般的です。
ただ… この<iframe>
埋め込み、控え目に言ってクッソ遅いです。
マジでこの埋め込みするだけで1秒(1000ms)くらい遅くなります。
これを回避する方法として、サムネイル画像をクリックされた際にJavascriptでiframeを生成するという手法が流行っています。
GitHubにあるpaulirish/lite-youtube-embedなどのライブラリを使うと簡単に実装できます。
(Googleが提供するものは全て正義というわけではない)
HTML/JavaScript/CSSなどのMinify
たかが数バイト~数キロバイトとか思うかもしれませんが、コードを圧縮するMinify(ミニファイ)をすることで転送量を間違いなく減らせます。 (=高速化)
HTML/Javascript/CSSを圧縮するなら以下のMinifierを使うと良いです。 (自動で圧縮をするシェルスクリプトを書くとなお良いです)
- HTML : HTMLMinifier (kangax/html-minifier | Github)
$ html-minifier --collapse-whitespace --remove-comments --remove-optional-tags --remove-redundant-attributes --remove-script-type-attributes --remove-tag-whitespace --use-short-doctype [ファイル] -o [出力ファイル]
- JavaScript : UglifyJS 3 (mishoo/UglifyJS)
$ uglifyjs --compress --mangle -o [出力ファイル] -- [ファイル]
- CSS : cleancss (jakubpawlowicz/clean-css)
$ cleancss -O2 [ファイル] -o [出力ファイル]
Cloudflareを使っている場合はCloudflareにMinify機能がついてるのでそれを使うといいです。
インフラ関連
静的アセットのキャッシュポリシー設定
(PageSpeedの「静的なアセットと効率的なキャッシュ ポリシーの配信」対策)
画像やフォント, JavaScriptファイルやスタイルシートなどの静的アセットをWebブラウザにキャッシュさせることで毎回ダウンロードする必要がなくなり高速化へ繋がります。
利用しているHTTPサーバーの種類によって設定が異なり、比較的厄介な類に含まれますがキャッシュの効果は再度サイトを訪れた人に絶大なメリットを与えるのでぜひ設定しましょう。
参考 : How to Fix the Leverage Browser Caching Warning in WordPress | Kinsta
Apacheの場合
以下のような内容を.htaccess
に追加すればOKです。
期間は必要に応じて調整しましょう。
<IfModule mod_expires.c> ExpiresActive On ExpiresByType image/jpg "access 1 year" ExpiresByType image/jpeg "access 1 year" ExpiresByType image/gif "access 1 year" ExpiresByType image/png "access 1 year" ExpiresByType image/svg "access 1 year" ExpiresByType text/css "access 1 month" ExpiresByType application/pdf "access 1 month" ExpiresByType application/javascript "access 1 month" ExpiresByType application/x-javascript "access 1 month" ExpiresByType application/x-shockwave-flash "access 1 month" ExpiresByType image/x-icon "access 1 year" ExpiresDefault "access 2 days" </IfModule>
nginxの場合
以下のような内容をコンフィグファイル内のserver
ブロック内に追記すればOKです。
必要に応じて期間やキャッシュするファイルの種類を調整した方がいいです。
location ~* \.(css|gif|ico|jpeg|jpg|js|png|webp|woff|woff2|fon|fot|ttf|svg|mp4|webm|otf)$ { expires 365d; }
LiteSpeedの場合
LiteSpeedの場合、WebAdmin Consoleから設定します。
設定したいバーチャルホストのコンテキストタブから、コンテキストを以下のような内容で新規追加します。
- タイプ : Static
- URI :
exp:^.*(css|gif|ico|jpeg|jpg|js|png|webp|woff|woff2|fon|fot|ttf|svg|mp4|webm|otf)$
- 場所 :
$DOC_ROOT/$0
- アクセス可能 : はい
- Header Operations :
unset Cache-control
set Cache-control public, max-age=15552000
set Access-Control-Allow-Origin: *
URIの中身を変更することでキャッシュするファイルの種類が変更でき、Header Operationsのmax-age=15552000
を変更することでキャッシュの期間を変更できます。
設定が完了したらLiteSpeedを必ず再起動しましょう。
テキスト圧縮の有効化
(PageSpeedの「テキスト圧縮の有効化」対策)
通信量を削減するためにテキストベースのリソース(HTMLやJavaScript, CSSなど)はgzipで圧縮して送信した方が良いです。
設定する場合、以下を参考にしてください。
- Apache : 【初心者向け】Apacheでgzip | Qiita
- nginx : Nginxでコンテンツに対してgzip圧縮をかける | Qiita
- LiteSpeed :サーバー設定のチューニング内にあるGZIP/Brotli Compressionの設定を画像のようにします。
TTFB(サーバー応答時間)の短縮
これはFRONTL1NE自体が以前まで抱えていたミスなのですが、日本人向けのコンテンツなら日本のサーバーを立てたほうが良いです。
海外にサーバーを立てていると、どうしても日本から海外までの通信に一定の時間がかかってしまいます。(光は俺たちにとって遅すぎる)
またサーバーの位置の他にもサーバーで行われる処理が重いなど、サーバー応答時間を遅くする原因はたくさんあります。
これだ! という解決策を示すことはできないのですが、地道にボトルネックとなる部分を特定していくのがベストです。
ちなみにWordPressユーザーならHTTPサーバーをOpenLiteSpeedに載せ替えるのがオススメです。
おまけ (WordPressについて)
まずWordPressに限ったことではないですが、なんでもかんでもプラグインで解決しようとするのは最悪なので絶対やめたほうがいいです。
(WordPressが遅いとか言っちゃう人は大体この辺の最適化が下手なだけだと思う。もちろん静的サイトのほうがWPより早いけど…)
Google Analyticsのコードを挿入するのわざわざプラグイン使ったりとかするのは本当に謎
あとは、nginxやApache使ってるなら、OpenLiteSpeedに乗り換えるのもオススメ。
おわりに
このページで解説した内容はWebの最適化・高速化のあくまで一部にすぎません。
高速化で重要なことは、できるだけ早くテキストなどの重要な情報をユーザーに届けることです。
これを必ず覚えておきましょう。
あと、PHPやSSR(Server Side Rendering)などのサーバー側で何かする動的なサイトは単純なHTMLなどを配信する静的サイトに速度では基本勝てないです。
静的サイトで済むコンテンツは基本WordPressとか使わずに作成した方が良いことが多いのでお忘れなく…
最後まで読んでいただきありがとうございました。
Twitterフォロー、Discordへの参加などお待ちしてます。
【特典付き! 】Webサイト高速化のための 静的サイトジェネレーター活用入門 (Compass Booksシリーズ)
コメント