2024.12.10
Webサイトのパフォーマンス向上ガイド②
前回の記事はこちら。
現代のWebサイトでは、訪問者に優れたユーザー体験を提供するために、スピードと効率がとても大切です。読み込みが遅いサイトは、ユーザーにストレスを与え、離脱率を高めるだけでなく、検索エンジンのランキングにも悪影響を及ぼします。
この記事では、Webサイトのパフォーマンスを向上させるためのCSSとJavaScriptの最適化、HTTPリクエストの削減、キャッシュの利用、レイジーロードの導入について詳しく説明します。
CSSとJavaScriptの最適化
CSSとJavaScriptの最適化は、Webサイトのパフォーマンスを向上させるために欠かせない要素です。ファイルサイズを小さくして、読み込み時間を短くするために、以下の具体的な手法を利用できます。
ミニファイ
ミニファイとは、CSSやJavaScriptファイルから不要なスペースやコメントを削除して、ファイルサイズを小さくする手法です。これにより、ブラウザがファイルを素早く解析できるようになり、ページのレンダリング速度が向上します。
- UglifyJS: JavaScriptファイルをミニファイするためのツールで、コードを小さくしながらも機能を損なわないようにします。
- CSSNano: CSSファイルをミニファイするためのツールで、ファイルサイズを小さくするためにさまざまな最適化を行います。
- オンラインツール: 多くのオンラインツールが無料で利用でき、簡単にファイルをミニファイできます。例えば、Minify CodeやOnline CSS Minifierなどがあります。
ミニファイを行うことで、ユーザーがWebページを訪れる際の初期ロード時間を大幅に短縮できます。
非同期読み込み
- async属性: スクリプトが読み込まれたときにすぐに実行されます。他のスクリプトがまだ読み込まれている間でも、ページのレンダリングがブロックされません。
<script src="example.js" async></script>
- defer属性: 全てのHTMLが解析された後にスクリプトが実行されるため、ページのレンダリングが遅くなりません。特に、ページの末尾に配置されるスクリプトに有効です。
<script src="example.js" defer></script>
HTTPリクエストの削減
HTTPリクエストの削減は、Webページの読み込み速度を大幅に向上させるための重要な手法です。リクエストが多いとサーバーの負荷が増え、ページの表示に時間がかかるため、できるだけリクエスト数を減らすことが推奨されます。以下の具体的な方法でHTTPリクエストを削減できます。
スプライト画像の利用
スプライト画像は、複数の小さな画像を1つの大きな画像にまとめて、CSSで表示位置を調整する手法です。これにより、画像ごとに個別のHTTPリクエストが発生するのを防ぐことができます。
- スプライトの作成: 複数のアイコンや小さな画像を1つのスプライトシートにまとめます。Photoshopやオンラインツールを使えば簡単に作成できます。
- CSSでの配置: CSSのbackground-positionプロパティを使って、スプライト画像の中から特定の部分を表示します。例えば、以下のように記述します。
.icon {
background-image: url('sprite.png');
background-position: -10px -10px;
width: 32px;
height: 32px;
}
インライン化
インライン化は、小さなCSSやJavaScriptをHTML内に直接埋め込む手法です。これにより、外部ファイルとして読み込むための追加のHTTPリクエストを減らすことができます。ただし、インライン化を適切に使わないとHTMLが大きくなりすぎるため、バランスが重要です。
- インラインCSS: スタイルをHTMLの<style>タグ内に直接記述します。
<style>
.header { background-color: #333; color: #fff; }
</style>
- インラインJavaScript: JavaScriptをHTMLの<script>タグ内に直接記述します。
<script>
document.addEventListener('DOMContentLoaded', function() {
console.log('Page loaded');
});
</script>
リソースの結合
複数のCSSやJavaScriptファイルを1つにまとめて、リクエスト数を減らします。これにより、ブラウザがファイルを取得するためのHTTPリクエスト数が減り、ページの読み込み速度が向上します。
- CSS結合: 複数のCSSファイルを1つにまとめ、リンクタグで一度に読み込むようにします。
- JavaScript結合: 複数のJavaScriptファイルを1つにまとめ、scriptタグで一度に読み込むようにします。
HTTP/2の活用
HTTP/2は、複数のファイルを同時に読み込むことができるプロトコルです。HTTP/1.1では、各リソースのダウンロードが順番に行われるため、リクエスト数が多いとページの読み込みが遅くなります。HTTP/2を使うと、同時に複数のリクエストを処理できるので、ページのパフォーマンスが向上します。
- サーバー設定: HTTP/2を有効にするためには、サーバーがHTTP/2に対応している必要があります。多くの現代的なWebサーバー(Apache, Nginxなど)はHTTP/2をサポートしています。
キャッシュの利用
キャッシュの利用は、Webサイトのパフォーマンスを大幅に向上させる手法の一つです。ブラウザキャッシュをうまく活用することで、ユーザーが再訪した際のロード時間を短縮し、サーバーへの負荷を軽減することができます。ここでは、キャッシュの仕組みと具体的な実装方法について詳しく説明します。
キャッシュの仕組み
キャッシュとは、一度取得したリソース(画像、CSSファイル、JavaScriptファイルなど)をブラウザやプロキシサーバーに一時的に保存しておく仕組みです。これにより、再度同じリソースを要求する際に、サーバーからダウンロードせずにキャッシュから直接読み込むことができます。
主なキャッシュの種類
- ブラウザキャッシュ: ユーザーのブラウザに保存されるキャッシュ。サイトを再訪した際に再利用されます。
- プロキシキャッシュ: ネットワークのプロキシサーバーに保存されるキャッシュ。複数のユーザーが同じリソースを利用する際に効果的です。
- CDNキャッシュ: コンテンツデリバリーネットワーク(CDN)が提供するキャッシュ。グローバルに分散されたサーバーからリソースを提供します。
キャッシュ制御ヘッダー
キャッシュを効果的に利用するためには、HTTPヘッダーを適切に設定することが重要です。以下に、主なキャッシュ制御ヘッダーについて説明します。
Cache-Control: キャッシュの制御を行う最も重要なヘッダーです。
- max-age: キャッシュの有効期限を秒単位で指定します。
Cache-Control: max-age=3600
- no-cache: サーバーにリソースの最新バージョンを確認するよう指示します。
Cache-Control: no-cache
- no-store: キャッシュを一切行わないよう指示します。
Cache-Control: no-store
- ETag: リソースのバージョン管理に使用されるヘッダーです。リソースが変更された場合に新しいETagが生成されます。
ETag: "686897696a7c876b7e"
- Expires: リソースの有効期限を日付で指定します。現在ではCache-Controlヘッダーのmax-ageと併用されることが一般的です。
Expires: Wed, 21 Oct 2021 07:28:00 GMT
ブラウザキャッシュの設定例
具体的な設定例を示します。これらの設定は、Webサーバーの設定ファイル(例: Apacheの.htaccessやNginxの設定ファイル)に追加します。
Apacheの場合
<IfModule mod_expires.c>
ExpiresActive On
# image/jpgおよびimage/pngファイルタイプに対して、
# アクセスから1ヶ月間キャッシュを有効にする
ExpiresByType image/jpg "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
# text/cssおよびapplication/javascriptファイルタイプに対して、
# アクセスから1週間キャッシュを有効にする
ExpiresByType text/css "access plus 1 week"
ExpiresByType application/javascript "access plus 1 week"
</IfModule>
Nginxの場合
# 指定したファイルタイプ(JPEG、PNG、GIF、アイコン、CSS、JavaScript)を1ヶ月間キャッシュする
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 1M;
add_header Cache-Control "public, no-transform";
}
キャッシュバスティング
キャッシュバスティングとは、リソースが更新されたときに古いキャッシュが使われるのを防ぐ手法です。主な方法として、リソースのURLにバージョン情報を含めることが挙げられます。
- クエリパラメータ:
<link rel="stylesheet" href="style.css?v=1.2.3">
- ファイル名の変更:
<link rel="stylesheet" href="style.v123.css">
これにより、リソースが更新されるたびに新しいバージョンとして認識され、最新のリソースがキャッシュに保存されます。
レイジーロードの導入
レイジーロード(Lazy Loading)は、Webサイトの初期ロード時間を短縮し、ユーザーに対するパフォーマンスを向上させる技術です。特に、画像や動画などのメディアファイルを段階的に読み込むことで、ページ全体の表示速度を改善します。ここでは、レイジーロードの仕組みと具体的な実装方法について詳しく説明します。
レイジーロードの仕組み
レイジーロードは、ユーザーがスクロールして画面内に表示されるときに初めてリソースを読み込む手法です。これにより、初期ページロード時にすべての画像や動画を一度に読み込む必要がなくなり、ページの初期表示速度が劇的に向上します。
主な利点
- 初期ロード時間の短縮: ページが最初に表示されるときに必要なリソースだけを読み込むので、初期ロード時間が短くなります。
- 帯域幅の節約: 必要なときにだけリソースを読み込むので、無駄なデータ転送を防げます。
- パフォーマンスの向上: レンダリングの負荷が軽減され、ユーザー体験が向上します。
レイジーロードの実装方法
レイジーロードを実装するための方法はいくつかあります。ここでは、HTML5のloading属性を使用した方法とJavaScriptを使用した方法について説明します。
HTML5のloading属性を使ったレイジーロード
レイジーロードの実装方法として、HTML5のloading
属性を使用する方法が非常にシンプルで効果的です。この方法は、追加のJavaScriptを必要とせず、ブラウザが自動的に画像やiframeを遅延読み込みするように指示します。
以下は、loading属性を使った例です。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Lazy Load Example</title>
</head>
<body>
<img src="example.jpg" alt="Example Image" loading="lazy">
<iframe src="example.html" loading="lazy"></iframe>
</body>
</html>
loading=”lazy”属性を画像タグやiframeタグに追加するだけで、ブラウザは自動的にその画像やiframeを遅延読み込みします。
JavaScriptを使ったレイジーロード
より高度な制御が必要な場合や、ブラウザの互換性を考慮する場合には、JavaScriptを使用したレイジーロードの実装も検討できます。以下は、Intersection Observer APIを利用した例です。
以下は、Intersection Observerを使ったレイジーロードの例です。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Lazy Load Example</title>
<style>
.lazy {
opacity: 0;
transition: opacity 0.3s;
}
.lazy-loaded {
opacity: 1;
}
</style>
</head>
<body>
<img class="lazy" data-src="example.jpg" alt="Example Image">
<script>
document.addEventListener('DOMContentLoaded', function() {
let lazyImages = [].slice.call(document.querySelectorAll('.lazy'));
if ('IntersectionObserver' in window) {
let lazyImageObserver = new IntersectionObserver(function(entries, observer) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
let lazyImage = entry.target;
lazyImage.src = lazyImage.dataset.src;
lazyImage.classList.add('lazy-loaded');
lazyImageObserver.unobserve(lazyImage);
}
});
});
lazyImages.forEach(function(lazyImage) {
lazyImageObserver.observe(lazyImage);
});
}
});
</script>
</body>
</html>
このスクリプトでは、IntersectionObserverを使って、画像がビューポート内に入ったときにdata-src
属性から実際のsrc
に画像のソースを設定し、画像を表示します。
レイジーロードのツールとライブラリ
複雑なレイジーロードの実装を簡単にするために、さまざまなツールやライブラリが存在します。以下はいくつかの例です。
- lazysizes: 高機能なレイジーロードライブラリで、画像やiframeだけでなく、他のリソースも遅延読み込みできます。
- lozad.js: 軽量でシンプルなレイジーロードライブラリで、Intersection Observer APIを使っています。
- vanilla-lazyload: 初心者にも使いやすく、設定が簡単なレイジーロードライブラリです。
まとめ
Webサイトのパフォーマンス向上には、さまざまな手法を組み合わせることが重要です。画像の最適化や次世代フォーマット(WebPやAVIF)の活用により、ファイルサイズを削減し、読み込み速度を向上させることができます。また、CSSとJavaScriptの最適化、HTTPリクエストの削減、キャッシュの利用、レイジーロードの導入といった手法を駆使することで、さらに高速で効率的なWebサイトを構築できます。
これらの手法を実践することで、ユーザー満足度の向上、SEOの改善、サーバー負荷の軽減、モバイルユーザーへの対応、そして持続可能なWeb開発が実現します。総合的なパフォーマンス向上を目指し、ユーザーにとって快適で魅力的なWebサイトを提供し、ビジネスの成功に貢献しましょう。
いいねありがとうございます!
この記事を書いた人
鈴木 秀一朗
フロントエンジニア
《 仕事で大切にしていること 》
迅速丁寧な対応を心がけています。
元々営業・販売職をしていたので、迅速丁寧な対応がお客様の満足度を上げ、また私自身の仕事をする上での満足度を上げることにも繋がると考えています。