gazou-compressor.jp

プレースホルダ設計 2025:LQIP Blur + Dominant + Skeleton + Step Fade の組合せ

単一の LQIP だけでは “ぼやけ→突然鮮明” の視覚ジャンプが起きます。既存LQIPSkeleton + 支配色 + Step Fade に拡張し滑らかさを改善します。

構成
  • blurDataURL:雰囲気
  • 支配色背景:ちらつき防止
  • Skeleton:構造ヒント
  • Step Fade:視覚ジャンプ緩和

1. 課題

初期の 意味的手掛かり が不足するとユーザは“待たされている”と感じます。骨組みで大枠を、支配色でテーマを補完します。

2. 組合せ設計

Blur / Dominant / Skeleton / Step Fade を “フェーズ” と “役割” で分離し責務を明確化。Blur は “雰囲気(構図/色温度)” 、Skeleton は “レイアウト予測”、Dominant は “背景チラつき抑制”、Step Fade は “遷移の滑らかさ”。

要素目的表示期間失敗時フォールバック
Blur LQIP配色/構図提示0 → midDominant単色
Dominant BG残像/白フラッシュ抑制先行テーマ色トークン
Skeletonレイアウト予測0 → fullAspect Ratio Box
Step Fade視覚ジャンプ緩和mid → full単一フェード
// 1. 24px Blurred JPEG → base64
sharp img.jpg
  .resize(24)
  .jpeg({ quality: 25 })
  .toBuffer()
  .then(b=> 'data:image/jpeg;base64,'+b.toString('base64'));

3. Skeleton コンポーネント

Skeleton はサイズ確保 + 視線誘導 が主目的。読みやすさ優先でコントラストは WCAG "本文" 基準未満に抑え視覚ノイズ化を避けます。

// 2. Skeleton DOM (React)
export function Skeleton({ w, h, color }: { w:number; h:number; color:string }){
  return <div style={{ width:w, height:h }} className="relative overflow-hidden rounded bg-[color:var(--ph-bg)]">
    <div className="absolute inset-0 animate-pulse bg-gradient-to-r from-transparent via-white/15 to-transparent" />
  </div>;
}
// Aspect Ratio Box + Skeleton
function PhContainer({w,h,children}:{w:number;h:number;children:React.ReactNode}){
  const ar = (h / w * 100).toFixed(4);
  return <div className="relative" style={{width:w}}>
    <div style={{paddingTop:ar+'%'}} />
    <div className="absolute inset-0">{children}</div>
  </div>;
}

4. Step Fade ロジック

2段フェードは phase 0→1→2ぼかし半径とスケール を段階減衰し "瞬断" を除去。mid 画像は 1/4 解像度など軽量版。

// 3. Step Fade Hook
function useStepFade(){
  const [phase,setPhase] = useState(0); // 0 blur,1 mid,2 full
  function onMidLoaded(){ setPhase(p=> Math.max(p,1)); }
  function onFullLoaded(){ setPhase(2); }
  return { phase, onMidLoaded, onFullLoaded };
}
/* 4. CSS (Tailwind例) */
.blur-phase img { filter: blur(12px); transform: scale(1.04); }
.mid-phase img { filter: blur(4px); }
.full-phase img { filter: none; transition: filter .35s ease, transform .35s ease; }
// クラス付与例
<figure className={phase===0?'blur-phase':phase===1?'mid-phase':'full-phase'}>
  <img src={phase<2?midSrc:fullSrc} aria-hidden={phase<2} />
</figure>

5. CI / LCP差分検証

CI では LQIP 有無で LCP/INP/TTFB 影響 を A/B 収集し統計的有意差を閾値判定します。

# 5. CI: LQIP有無の LCP/INP 差分サンプリング
node scripts/lcp-sample.js --url /landing --runs 5 --with-placeholder true --out with.json
node scripts/lcp-sample.js --url /landing --runs 5 --with-placeholder false --out without.json
node scripts/lcp-compare.js with.json without.json --lcp-delta -150 --inp-delta 10
// scripts/lcp-compare.js (概念)
import stats from 'simple-statistics';
const a = load('with.json');
const b = load('without.json');
const p = stats.tTestTwoSample(a.lcp, b.lcp);
if (p < 0.05 && mean(a.lcp) < mean(b.lcp) - 120) process.exit(0); else process.exit(1);

6. 運用Tips

7. FAQ

8. まとめ

複合プレースホルダは 初期知覚の空白を最小化する分業パターン。計測と CI 化で “効果の持続性” を検証しながら改善を継続。

関連ツール

公開日: 2025-09-06編集: gazou-compressor.jp

gazou-compressor.jp 編集部

画像圧縮・変換・背景除去などの実践テクニックと、Webで“速く・軽く・崩さない”ためのノウハウを発信しています。

関連記事

トピック/更新日の近いコンテンツ