PNG再最適化の機会を高速検出する:PNG Re-Optimize 戦略
PNG Re-Optimize ツールは PNG の色数/チャンク/圧縮レベルを推定し “残り何% 余地があるか” を大まかに算出します。限られた作業時間を最大削減効果へ投下する優先順位付けに活用。
TL;DR
- 余地% × 配信 PV × キャッシュ寿命 = 削減期待バイト
- 上位 20% のみ手動再最適化対象
- 再最適化後はメタデータ記録で“再作業”を防止
- 閾値を満たさないものは触らない勇気
1. スコア式
score = (size * estimated_saving_ratio) * monthly_requests * remaining_months
rank = desc(score)
期待節約バイト = サイズ × 推定削減率 × (月間リクエスト × 残存月)。一時用途画像は残存月を 0.25 などに縮小。
2. 推定ロジック
- カラーパレット利用可 → 索引化候補
- 未stripチャンク(gAMA/EXIF等) → 低コスト削減余地
- 圧縮層レベル低 (zlib level <7) 推定 → 強圧縮余地
3. CI レポート例
score ≥ 1e9 のみ PR コメント/失敗で通知し 低期待値ノイズ を遮断。
file,size,est_ratio,est_bytes,score
hero1.png,312KB,0.28,87360,2.1e10
ui-kit.png,95KB,0.12,11640,8.4e9
// scripts/png-reopt-score.ts (抜粋)
import fs from 'node:fs';
for (const f of process.argv.slice(2)) {
const size = fs.statSync(f).size;
const ratio = estimateSavingRatio(analyzeSignals(f)); // analyzeSignals 実装別途
const monthly = lookupMonthlyRequests(f);
const months = remainingCacheMonths(f);
const estBytes = Math.round(size * ratio);
const score = estBytes * monthly * months;
if (score >= 1e9) console.log(f+','+size+','+ratio.toFixed(2)+','+estBytes+','+score);
}
4. 可視化
前回比 △score を算出し改善 (緑) / 悪化 (赤) で強調。
interface Entry { file:string; score:number; prev?:number }
export function decorate(es:Entry[]){
return es.map(e=>({ ...e, delta: e.prev? e.score - e.prev : 0 }));
}
5. やらないことリスト
- 削減期待が閾値未満 (例: 5MB/月) の資産は後回し
- 毎月更新される一時画像は再最適化効果が薄い
6. 関連ツール
7. まとめ
“全部最適化” は非効率。期待値ソートで 削減インパクト最大 の層を先に刈り取る。
公開日: 2025-09-06編集: gazou-compressor.jp
FAQ
FAQ(よくある質問)
1画像形式の基本方針は?(写真/スクショ/透過)
写真は AVIF / WebP(画質80–85%目安)、UIやスクショはPNG / WebP Lossless、単色ロゴはSVGが基本です。 実装の詳細は srcset/sizes設計ガイド と スクショ最適化 を参照してください。
2圧縮しても画質を落とさないコツは?
実表示幅に合わせたリサイズ → 過大ダウンロードを防ぎ、
srcset/sizes
を 実描画幅に一致させます。画質は写真で 80–85% を起点に、ノイズやエッジを目視確認。 仕上げは /compare で Before/After を見比べるのがおすすめです。