JA EN

画像プレースホルダー技術の比較 - LQIP, BlurHash, SQIP の実装ガイド

· 約 9 分で読めます

画像プレースホルダーとは - なぜ空白よりも優れているのか

画像プレースホルダーとは、本来の画像が読み込まれるまでの間に表示する代替コンテンツです。遅延読み込み (lazy loading) を実装したページでは、ビューポート外の画像は読み込みが遅延されるため、スクロール時に一瞬空白が表示されることがあります。この空白をプレースホルダーで埋めることで、ユーザー体験を大幅に改善できます。

プレースホルダーがない場合の問題点:

プレースホルダーの種類は大きく分けて以下の 4 つがあります。

どの手法を選ぶかは、データサイズ、視覚的品質、実装の複雑さ、パフォーマンスへの影響のバランスで決まります。以降のセクションで各手法を詳しく比較します。

LQIP の実装 - 極小画像によるプレビュー表示

LQIP (Low Quality Image Placeholder) は、元画像を極端に縮小した低品質版をインラインで HTML に埋め込む手法です。Facebook が 2015 年頃から採用したことで広く知られるようになりました。ブラウザが縮小画像を拡大表示する際に自然なぼかし効果が得られるため、追加の CSS フィルタなしでもプレースホルダーとして機能します。

実装手順:

データサイズの目安: 幅 20px の JPEG (品質 20) で約 300-600 バイト。Base64 エンコードすると約 400-800 文字になります。HTML に直接埋め込んでも、ページサイズへの影響は画像 1 枚あたり 1KB 未満に収まります。

CSS によるぼかし強化: ブラウザのバイリニア補間だけでは、ブロックノイズが目立つ場合があります。filter: blur(20px) を適用し、画像読み込み完了時にトランジションで解除すると、より滑らかな表示が得られます。

.lqip { filter: blur(20px); transform: scale(1.1); transition: filter 0.3s, transform 0.3s; }
.lqip.loaded { filter: blur(0); transform: scale(1); }

LQIP の利点は実装のシンプルさと、特別なライブラリが不要な点です。Sharp や ImageMagick で簡単に生成でき、既存のビルドパイプラインに組み込みやすいのが特徴です。

BlurHash の仕組み - 文字列で画像を表現する革新的アプローチ

BlurHash は Wolt (フィンランドのフードデリバリー企業) が開発したアルゴリズムで、画像を 20-30 文字程度の短い文字列にエンコードします。この文字列からクライアントサイドでぼかし画像を生成するため、LQIP のように画像データを転送する必要がありません。

エンコードの原理: BlurHash は画像を離散コサイン変換 (DCT) で周波数成分に分解し、低周波成分のみを保持します。コンポーネント数 (X 方向 x Y 方向) を指定でき、デフォルトは 4x3 です。各コンポーネントの係数を Base83 でエンコードして文字列化します。

デコードの流れ:

データサイズ: 4x3 コンポーネントの場合、わずか 20 文字 (約 20 バイト) で画像の大まかな色分布を表現できます。LQIP の 300-600 バイトと比較して 10-30 倍コンパクトです。JSON API のレスポンスに含めても帯域への影響はほぼゼロです。

実装例 (JavaScript デコード):

import { decode } from 'blurhash';
const pixels = decode('LEHV6nWB2yk8pyo0adR*.7kCMdnj', 32, 32);
// pixels は Uint8ClampedArray (32*32*4 = 4096 要素)
// Canvas の ImageData に設定して描画

BlurHash は Instagram、Mastodon、Unsplash など多くのサービスで採用されています。API レスポンスに BlurHash 文字列を含め、画像 URL の読み込み完了前にプレースホルダーを表示する用途に最適です。

SQIP の特徴 - SVG プリミティブによる芸術的なプレースホルダー

SQIP (SVG-based Quality Image Placeholder) は、画像を SVG のプリミティブ図形 (三角形、楕円、矩形など) の組み合わせで近似する手法です。Tobias Baldauf が 2017 年に公開したツールで、内部的には Primitive (Michael Fogleman 作) のアルゴリズムを使用しています。

生成プロセス:

データサイズ: 8 個のプリミティブで約 800-1200 バイト。LQIP と同程度ですが、SVG はベクター形式のためどの解像度でもシャープに表示されます。Retina ディスプレイでもぼやけません。

視覚的品質: SQIP の最大の特徴は、プレースホルダーとしての美しさです。幾何学的な図形の組み合わせが芸術的な印象を与え、単なるぼかし画像よりもデザイン性が高いプレースホルダーになります。ポートフォリオサイトやギャラリーサイトなど、ビジュアルの品質が重要なサイトに適しています。

SQIP の課題: 生成に時間がかかることが最大の弱点です。1 枚あたり 1-5 秒程度の処理時間が必要で、大量の画像を扱うサイトではビルド時間が大幅に増加します。また、Node.js の sqip パッケージはメンテナンスが停滞気味で、最新の Node.js バージョンとの互換性に問題が生じることがあります。

代替として、primitive コマンドラインツールを直接使用し、出力 SVG に手動でぼかしフィルタを追加する方法もあります。Go で実装されているため高速に動作します。

手法の比較と選定基準 - プロジェクトに最適な手法を選ぶ

4 つのプレースホルダー手法を主要な評価軸で比較します。プロジェクトの要件に応じて最適な手法を選択してください。

データサイズ比較:

視覚的品質 (情報量の多さ): SQIP > LQIP > BlurHash > ドミナントカラー。SQIP は画像の構造を最もよく保持し、LQIP は色の分布を自然に表現します。BlurHash は大まかな色のグラデーションを再現しますが、エッジ情報は失われます。

生成速度: ドミナントカラー (1ms 未満) > BlurHash (10-50ms) > LQIP (50-200ms) > SQIP (1-5 秒)。大量の画像を処理するビルドパイプラインでは、SQIP の生成時間がボトルネックになる可能性があります。

推奨する使い分け:

複数の手法を組み合わせることも有効です。例えば、ファーストビューの画像には LQIP を使い、スクロール下の画像にはドミナントカラーだけを設定する、といった段階的なアプローチが実用的です。

Next.js と Astro での実装例 - モダンフレームワークとの統合

モダンな Web フレームワークでは、画像プレースホルダーの生成と表示を効率的に統合する仕組みが提供されています。Next.js と Astro での具体的な実装方法を紹介します。

Next.js の Image コンポーネント: Next.js の <Image> コンポーネントは placeholder prop で LQIP と BlurHash をネイティブサポートしています。

<Image src="/photo.jpg" placeholder="blur" blurDataURL="data:image/jpeg;base64,..." />

静的インポートの場合、ビルド時に自動的に blurDataURL が生成されます。動的画像の場合は、plaiceholder ライブラリを使ってサーバーサイドで生成できます。

import { getPlaiceholder } from 'plaiceholder';
const { base64 } = await getPlaiceholder('/photo.jpg');

Astro での実装: Astro の <Image> コンポーネントは直接的なプレースホルダーサポートを持ちませんが、ビルド時に Sharp で LQIP を生成し、コンポーネントに渡す方式が一般的です。

import sharp from 'sharp';
const buffer = await sharp('src/images/photo.jpg').resize(20).jpeg({ quality: 20 }).toBuffer();
const lqip = `data:image/jpeg;base64,${buffer.toString('base64')}`;

BlurHash の React 実装: react-blurhash パッケージを使えば、BlurHash 文字列から Canvas ベースのプレースホルダーを簡単に表示できます。Intersection Observer と組み合わせて、ビューポートに入ったタイミングで本来の画像を読み込む実装が効果的です。

パフォーマンスの注意点: インライン Base64 画像は HTML のサイズを増加させるため、SSR ページでは初期 HTML の転送量に注意が必要です。画像が 50 枚以上あるページでは、ファーストビュー外の画像にはドミナントカラーのみを設定し、LQIP はファーストビュー付近の 5-10 枚に限定することを推奨します。

関連記事

画像の遅延読み込み実装ガイド - loading=lazy と IntersectionObserver の使い分け

Web ページの初期表示速度を改善する画像遅延読み込みの実装方法を、ネイティブ API と JavaScript の両アプローチで解説します。

画像読み込み戦略の設計 - preload, fetchpriority, decoding を使いこなす

Web ページの画像読み込みを最適化する 3 つの属性を徹底解説。LCP 改善に直結する preload、fetchpriority、decoding の正しい使い方と組み合わせ方を紹介。

Data URI で画像を埋め込む技術と注意点 - Base64 エンコードの仕組みと最適な使いどころ

Data URI スキームで画像を HTML/CSS に直接埋め込む技術を解説。Base64 エンコードの仕組み、パフォーマンスへの影響、適切なユースケースと避けるべきケースを整理します。

画像ギャラリーのパフォーマンス最適化 - 大量画像を高速表示するテクニック

数百枚以上の画像を含むギャラリーページのパフォーマンスを最適化する手法を解説。仮想スクロール、プログレッシブ読み込み、メモリ管理、レイアウト計算の効率化を実践的に紹介します。

Web サイトの画像パフォーマンス監査 - Core Web Vitals 改善の実践ガイド

Web サイトの画像がパフォーマンスに与える影響を監査する方法を解説。LCP 改善、CLS 防止、転送量削減の具体的な手法を紹介します。

SVG の基礎と活用法 - ベクター画像の仕組みからアニメーションまで

SVG (Scalable Vector Graphics) の基本構造から実践的な活用法まで解説。パス、図形、テキスト、フィルタ、アニメーションの実装方法と最適化テクニックを紹介します。

関連用語