【CSS + JS】テキストの無限ループアニメーション
普通のレンタルサーバーでできる
Webページ高速化
目次
Webページの表示速度の重要性が増している
特に最近になって、サイトを作成する時には必ず気をつけていることが「ページが重くないか・表示速度が適正か」という部分です。
2、3年前までは体感で遅くなければそこまで気にすることはなかったのですが、ここ最近ではSEOでもページの表示スピードが重要なポイントになっていますし、ユーザビリティを高める意味でもWebページを作る上で表示速度の改善の優先度が高くなっています。やっぱり反応の良いサクサク見れるサイトがいいですよね。
何も対策していないと、最近では高解像度ディスプレイに対応するために解像度の高い画像を使っているとファーストビュー の画像の読み込みだけで数秒かかることもあります。
今回は画像に限りませんが、僕がサイトを作る時にやっている対策をメモ。
主にフロント側が中心の通常のレンタルサーバーでできる対策を書いていきます。
画像の最適化
まずは画像関連の対策です。
根本的に容量が少なければ少ないほどサイトが軽くなるので、1番容量を食う画像を圧縮することが表示速度改善の基本だと思います。もっと言えば画像を少なくする。文字などの画像はフォントで代用できないか考えたりSVGで直接インラインで埋め込んでしまうことも1つの手です。究極を言えばデザイン的に画像を0にできるなら0にしてもいいかもしれません。
画像の圧縮
画像の圧縮方法はいろいろとありますが、僕は1つに絞らず以下の3つのツールを状況に分けて使い分けています。
gulpを使う
まずはgulp。gulp-imageminを使ってタスクに書いているのでサイトのコーディングが終わったら必ず実行して圧縮します。jpg、png、gif、svgが圧縮できます。注意点としては、自分で圧縮率などをタスクに書くのですが、あまりキツイ設定で圧縮しすぎると画像が荒くなったりpngの色が変わってしまったりするので、適度な調整が必要です。そのため僕はこのタスクを実行して画像を圧縮する時は、上書きでなく一旦別ディレクトリに出力して中身を確認するようにしています。
オンラインツールを使う
「OPTIMIZILLA」というオンラインサービスを使って簡単にドラッグ&ドロップで画像を圧縮できます。圧縮後の状態を画面上で確認して画像ごとに適度な圧縮ができるのも便利です。ただしオンラインツールということもあり、1度に圧縮できるのは20枚までです。pngとjpgに対応しています。
デスクトップアプリを使う
「JPEGmini」というMacのデスクトップアプリを使っています。有料になりますが、買い切り型なので長い目で見れば使いやすいし得かなと思います。名前の通りjpgのみに対応なのでpngは圧縮できないのがネックですが、jpgの圧縮率もなかなかで、デスクトップアプリなので大量に放り込んでもサクサクと快適に圧縮してくれます。
僕の場合はこちらを最初に購入していたので使い続けていますが、他に「ImageOptim」というMac用の無料アプリがあるみたいなのでそちらを使うのも良いかと思います。ImageOptimはjpg・png・svg・gifに対応しており、使いやすそうです。
デスクトップアプリが1つあると、CMSなどで画像をアップロードする際にチャチャっと圧縮できるのが非常に便利です。
画像の遅延ロード
次に画像の遅延ロード。こちら容量削減ではないのですが、通常何も設定していないと最初の段階でページ内にある全ての画像を読み込んでから初めてページが表示されます。これを画面内に収まっていない画像は読み込まず、スクロールに合わせて画面内に入ってくるタイミングで後から画像を読み込む手法です。ページ全体の容量を削減できるわけではないですが、必要な時に必要な画像のみを読み込むのでこれを取り入れるだけで画像の多いサイトは初期表示がかなり高速化されます。
こちらはJSでその実装をするのですが、調べるといくつかライブラリが出て来るので好きなものを選ぶと良いかと思います。僕は「lazysizes」一択です。
WebPを使う
こちらはあまり馴染みがない人が多いと思いますが、WebP(ウェッピー)というGoogleが開発している超軽量の静止画の形式があります。すべてのブラウザで対応しているわけではないのですが、Chrome・Firefox・Edgeは対応してるので十分使う意味はあると思います。jpgやpngの画像をWebPに変換するとだいたい3割程度の削減が見込めますのでかなりの容量削減になります。
僕はGulpに画像をWebPに変換するタスクを書いて、画像圧縮→WebP生成をコーディング完了時に行っています。
ここで詳しく書くと他のことが書けなくなってしまいますので手法は割愛しますが、WebPの使い方としてはこちらのブログに書いてあることとほとんど同じです。
https://webkikaku.co.jp/blog/htmlcss/webp-how-to-use/
gulpでWebPを生成するタスクに関しては時間があればまた詳しく書こうと思います。
画像のインライン化
CSS内でアイコンなどの小さい画像を呼び出す場合、外部ファイルとして呼び出すよりもbase64に変換して埋め込んだ方がリクエストを減らせます。
これについて僕が実践した方法は以下の2つ。
gulp-base64を使う
Gulpのタスクで設定してCSS内の小さい画像をbase64に自動的に変換してくれます。画像の種類や容量の上限なども決められるのでgulpを使っている人には便利だと思います。
https://www.npmjs.com/package/gulp-base64
PostCSSを使う
PostCSSには「postcss-assets」という便利な機能が使えるようになるプラグインがあります。こちらの機能の中に画像をインライン化する方法がありますのでそれを使います。PostCSS自体が何のことか分からないという人もいるかもしれませんので、以下に参考ページを貼っておきます。
http://book2.scss.jp/code/c5/05.html
https://www.webprofessional.jp/7-postcss-plugins-to-ease-you-into-postcss/
レスポンシブイメージ
冒頭でも少し触れましたが、最近では高解像度ディスプレイに対応するために解像度の高い画像を使うことも増えました。解像度の高い画像はどれだけ圧縮してもそれなりに容量が大きくなってしまいます。この対策として、HTMLの新しい仕様「レスポンシブイメージ」という仕様を用いて、ディスプレイ解像度や画面サイズなどの条件ごとに最適な画像読み込ませることができます。
具体的には下記のページが詳しくまとまっています。
https://www.html5rocks.com/ja/tutorials/responsive/picture-element/
https://ics.media/entry/13324/
僕自身が実際にコーディングする時は、Photoshopで画像を書き出す時に必ず2倍の大きさの画像を書き出し、<picture>
要素でスマホ・PCそれぞれ解像度とサイズごとに最適な画像を表示させるように書いています。
この手法と遅延ロードをうまく掛け合わせて使うことでページはさらに軽くなります。遅延ロードのところで「lazysizes」一択だと書きましたが、lazysizesがこのレスポンシブイメージとの互換性があることがそう書いた1つの理由です。
以上が画像周りの対策になりますが、おそらくフロント側ではこれらの対策が速度改善に最も効果的です。全部やれば表示に1秒、2秒かかっていたサイトが余裕で1秒以内に表示できるようになるはずです。積極的に取り組みましょう。
CSSの最適化
ファイルの圧縮
ページの容量に関係する部分として次にCSSがあります。CSSは改行とかインデントを全部取ってしまっても動くので、gulpやwebpackでCSSを圧縮して容量を削減します。僕はSassを使っていますが、webpackでなくgulpでトランスパイルしていますので「gulp-csso」を使っています。PostCSSで使うのであれば「cssnano」がよく紹介されています。
レスポンシブデザインが普及してからメディアクエリで書くCSSの記述が増え、ファイルが肥大化してしまうことも多いので圧縮は必須です。オンラインツールなどもありますが、毎回コピペで貼り付けで圧縮するよりは時間もかからないタスクランナーで自動化しておく方が圧倒的に楽です。gulpやwebpackで設定しておきましょう。
インライン化
CSSを外部ファイル化して一括で読み込ませると、全部読み込むまで他の描画処理をブロックしてしまいます。そのためファーストビューに使うCSSだけをインライン化して<head>
要素内に<style>
タグで書いておき、他のCSSは後で読み込ませるといった手法があります。Googleの「PageSpeed Insights」でよく言われるやつです。
この対策をすると確かに初期表示は数値上では早くなります。ただTOPページと下層ページでデザインが違っていたりすると全部に対策しないといけないのか、とか大幅な変更があった時にファーストビューのCSSだけ抜き出すの面倒だな、とか考えると保守性とか拡張性はまるでないのであまりやる気になりません。笑 ちゃんと対策しないとCSSが適用されていない部分のちらつきが気になったり細かい対応が必要なので、この対策はサイトによって向き不向きがある気がします。(僕の知識が足りないだけかもしれません)
JavaScriptの最適化
ファイルの圧縮
webpackの「uglifyjs-webpack-plugin」を使って圧縮しています。webpackでバンドルしたファイルは容量が大きくなりがちなので、本番環境にデプロイする前に必ず圧縮します。これだけで5割近く容量を落とせる場合もあります。
こちらはCSSの圧縮と違って圧縮を実行すると割と時間がかかります。毎回5秒とかそれ以上の時間がかかることもあるので、開発時には圧縮せず、本番にデプロイする時だけ圧縮をかけたらいいと思います。
読み込みを最適化する
ここまでwebpackを使っている前提で書いてきているので今更ですが、リクエストを減らすためにJSのライブラリなどを全てまとめてバンドルします。キャッシュなどを考えるとCDNをうまく利用すればもっと早くなるとかいろいろな考え方があると思いますが、基本的にはリクエストの本数を減らすことが高速化に繋がると思うので僕はそうしています。
その上で外部ファイルとして読み込む際に他の描画処理をブロックしないように<body>
要素の閉じタグの直前で読み込ませる、<script>
タグにasync
属性、もしくは依存関係のあるJSを順番に読み込む場合はdefer
属性を付けます。async・deferについては以下の記事が詳しく調べてあるので参考になるかと思います。
https://qiita.com/phanect/items/82c85ea4b8f9c373d684
Resource Hintsを使う
HTMLの<link>
要素で使えるdns-prefetch
、preconnect
、prefetch
、 prerender
、preload
をうまく使って読み込みを最適化します。厳密に言うとpreload
と他の4つは別の仕様となっていますので、仕様や実装方法など詳しく調べてみたい方は参考ページをいくつか載せておきます。
https://qiita.com/ryo_hisano/items/e525616e5026b015aafe
https://triple-underscore.github.io/resource-hints-ja.html
https://blog.jxck.io/entries/2016-03-04/preload.html
https://webkikaku.co.jp/blog/htmlcss/preload/
具体的に僕が使っている手法としては、preload
を使ってCSSやJSをページを表示した段階で先読みさせます。これだけで100msほどの表示高速化になりました。
.htaccessの最適化
普通のレンタルサーバーであれば.htaccessが使えますので、その中でブラウザキャッシュやgzip圧縮配信などを設定します。
詳しくは以下のサイトを参考に。
https://cruw.co.jp/blog/2018/08/page_speed_with_htaccess/
https://www.cloud9works.net/seo/htaccess-setting-for-browser-cache/
https://www.cloud9works.net/seo/tutorial-gzip-with-htaccess/
注意点としては、CSSやJSのキャッシュが効いていると更新が反映されない場合がありますので、CSSファイルの後ろにパラメータを付与するなどしてキャッシュ回避する対策が必要になります。下記サイトが参考になります。
【CSS】WEBサイトの更新時、CSSのキャッシュを自動で読み直す方法
まとめ
レンタルサーバーでできるページ高速化についてをざっくりとご紹介しました。
ちなみにこのブログでも全ての対策をしていますが、お世辞にも早いとは言えません。笑 このサイトはWordPressなんですが、弊社で借りている格安レンタルサーバーのさらに端っこを借りて運営してますのであまりサーバーの応答速度がよろしくないようでして・・・笑
まぁ裏側のチューニングがもっと必要ですね。言い訳せずにがんばります。
現在、GCP × SSRでブログを爆速にする方法を試行錯誤中ですので、またその時がくれば記事にしたいと思います!
RELATED
NEW POSTS
【WordPress】GA4連携の人気記事ランキング機能を自作プラグイン化してみた
【netlify】ビルドイメージを更新 [ Ubuntu Xenial 16.04 → Ubuntu Focal 20.04 ]
【PHP】Google Business Profile APIを使ってクチコミを取得する
スクリーンショットのAPI「screendot」を使ってみた
【window.matchMedia】メディアクエリでhoverが使えるデバイスを判定
lax.jsの使い方【スクロール連動アニメーションの実装】