「もっさり​重い」の​正体は、​たいてい画像だった​ ──自社サイトを​10MB→0.3MBに​軽くした​実測ログ

ブログをWEBマガジン化した直後、「もっさり重い」と言われた。重いライブラリを疑う前に計測したら、犯人は地味な画像だった。生<img>の巨大PNG、全ページ常駐ロゴ684KB、canvasの影と総当たり、スクロールを削るblur。next/imageでカバー832KB→7KB、一覧~10MB→~0.3MB。「もっさり」の切り分けの型を実測Before/Afterで。

甲斐ショウジ甲斐ショウジ
CAG主宰/合同会社ATK CAIO(最高AI責任者)
技術9分で読めます
技術「もっさり重い」の正体は、たいてい画像だった ──自社サイトを10MB→0.3MBに軽くした実測ログ

技術ノート | AI駆動開発の現場から

このサイト(電脳技巧集団のコーポレートサイト)のブログを、先日WEBマガジン風に作り替えた。一覧性が上がって満足していた——その矢先、主宰の甲斐から一言。「とにかく、動きがもっさり重い」

速度の不調は、たいてい「重いライブラリのせいだ」と決めつけてしまう。だが今回は、まず計測してから犯人を絞った。結論を先に言うと、犯人は派手な技術ではなく地味な画像だった。ブログ一覧の表示が 約10MB → 約0.3MB、全ページ常駐のロゴが 684KB → 2KB。何をどう疑い、どう直したか——実測の数字つきで残しておく。[1]

ブラウザの開発者ツールのネットワークパネル。少数の巨大な画像リクエストが赤くハイライトされ、棒グラフを占拠してページの読み込みを遅くしている画面
ネットワークパネルを開けば一目瞭然——「もっさり」の正体は、画像が占拠する赤い帯

01​「もっさり​重い」と、​言われた​日

マガジン化で、ブログトップは見違えた。ヒーロー+カテゴリ別のセクションで、記事が一目で見渡せる。一覧性は狙いどおり。

ところが、スクロールがねっとりする。ページの表示にも、わずかな"待ち"を感じる。「もっさり重い」——感覚的だが、的を射た指摘だった。ここで多くの人がやりがちなのが、「アニメーションを減らそう」「WebGLが重いんじゃないか」と、当たりをつけて手を動かすこと。だが、当てずっぽうで直すと、たいてい見当違いの場所を削って時間を溶かす。まず、計測する。

02容疑者を​絞る​:重いのは​JSじゃなかった

最初に、いちばん疑われがちな"重量級ライブラリ"を確認した。package.json を見ると——Three.js も GSAP も Lenis も、入っていない。

これは大きい。3D描画(Three.js)も、重いアニメ(GSAP)も、スムーズスクロール(Lenis)も無い。とくに「スムーズスクロール」は、スクロールに意図的な"ため"を作るので、それ自体が「もっさり」の正体になりがちだが、今回は不在。つまりJSバンドルの重さや、スクロール遅延ライブラリは、犯人ではない。容疑者は3つに絞れた——①画像 ②描画アニメ(canvas) ③CSSのぼかし(blur)

「無いことを確認する」のは地味だが、調査では一番効く。可能性を一つずつ消すと、残った容疑者に資源を集中できる。逆に、ここを飛ばして「たぶんアニメ」と決め打つと、削っても直らず、また別の場所を当てずっぽうで触る——という消耗戦に入る。最初の5分の確認が、その後の数時間を救う。

容疑者リスト Three.js / GSAP / Lenis → 未使用=シロ ① 画像(巨大PNGを生<img>) ② canvas アニメ ③ CSS の blur 真の容疑者
計測で「JSバンドル/スムーズスクロール」を除外。残る容疑者は画像・canvas・blur

03真犯​人①:1MBの​画像を、​300pxで​表示していた

画像を数えて、血の気が引いた。public 配下の PNGが計44.5MB・52枚。記事カバーは1枚 800KB〜1.2MBのフルサイズ(1200×630)。しかも、これを <img> タグそのままで読み込んでいた(最適化なし)。

致命的なのは表示サイズとの落差だ。マガジントップはカバーを約14枚並べる。1枚300px幅で見せているのに、ブラウザは毎回1200pxのPNGをまるごとダウンロードして、デコードしている。合計すると1ページで10MB超。これでは、回線が速くても"重い"。スクロールのたびに巨大画像のデコードがCPUを噛む。これが「もっさり」の最大の正体だった。

そして、この手の重さは気づきにくい。開発中は画像がブラウザにキャッシュされているし、手元の回線は速い。「自分の環境では普通に動く」から、問題が見えない。実際に効いてくるのは、初めて訪れた人・モバイル回線・非力な端末——つまり、いちばん大事にしたい相手の環境だ。巨大PNGの生<img>は、エラーも警告も出さずに、静かに体感を削る。派手に壊れないぶん、見過ごされ続ける。

開発者ツールで同じ画像の2つのリクエスト行を比較。上は832KBの巨大な赤いバー、下は7KBの小さな緑のバー——同じ見た目で100倍軽い
同じ画像が、832KB→7KB。表示枠に合わせて配信するだけで2桁変わる

04next/imageで、​桁が​変わる​(832KB→7KB)

直し方は、王道だった。カバーを Next.jsの next/image に通すだけ。これだけで、画像は表示サイズに自動リサイズされ、avif/webpで配信される。設定は next.configformats:[avif,webp] を足し、各画像に「表示幅(sizes)」と、ファーストビューにはpriorityを渡す。

効果は、桁で変わった。同じカバー画像での実測を表に整理する。

形式・配信幅サイズ削減率
生PNG(原寸)832 KB—(基準)
next/image webp・幅3847 KB約99%減(カード表示幅)
webp・幅64018 KB約98%減
webp・幅82828 KB約97%減

※ 削減率は実測サイズ(生PNG 832KB基準)からの計算値。

生PNG(原寸) 832 KB next/image webp · 幅384 7 KB webp · 幅640 18 KB webp · 幅828 28 KB カード表示幅(384)で約99%減
同一カバー:生PNG 832KB → next/image webp 7KB(カード幅384px)。桁が2つ変わる

仕組みも気が利いている。next/imageは、端末の解像度に合わせた複数サイズの候補(srcset)を自動で用意し、画面に入る直前まで読み込みを遅らせる(遅延読み込み)。だからファーストビューの外にあるカードは、スクロールして初めて、しかも端末にぴったりのサイズだけ取得される。唯一の注意点は sizes(その画像が実際に表示される幅)を正しく書くこと——ここを大きく書きすぎると、過大なサイズを取りに行って効果が薄れる。リード(大きい)・カード(中)・サムネ(小)で、それぞれ実寸に合わせて指定した。

結果、マガジントップ全体では画像の転送量が 約10MB → 約0.3MB。一覧の全カバーが最適化エンドポイント経由になり、生PNGの直リンクはゼロになった。見た目は1ピクセルも変わらないまま、体感だけが軽くなる。コードの差分は小さいのに、効果は桁で出る——いちばん費用対効果の高い一手だった。

05全ページに​効く​一手:常駐ロゴ684KB→2KB

もう一つ、地味だが効いた発見がある。サイトの全ページに常駐するチャットの起動ボタン。そこに表示しているロゴマークが、684KBのPNGを、20〜24pxで表示するために生<img>で読んでいた

常駐パーツの怖さは、どのページを開いても必ず読まれること。トップでも、ブログでも、会社概要でも、毎回684KB。これを next/image 化したら、avifで2.3KB(表示48px相当)に落ちた。サイト全体に波及する無駄は、最優先で潰す——これは画像最適化の鉄則だ。1枚のアセットでも、全ページ常駐なら影響は全ページ分になる。逆に言えば、ヘッダーのロゴ・ファビコン・共通アイコンのような「どこにでも出るもの」は、最初から最適化しておく価値が一番高い。記事ごとのカバーより、まず"常駐枠"を疑うのが近道だ。

トップ ブログ 会社概要 …全ページ 常駐ロゴ684 KB ×毎回 next/image = 2 KB全ページに波及して軽量化
全ページ常駐アセットは、1枚直すだけで効果が全ページ分になる

06真犯​人②:canvasの​「影」と​「総当たり」

容疑者の2つ目、トップの粒子ネットワーク(背景で点が線で繋がるアニメ)。ここに、canvasの二大コストが潜んでいた。

  • 粒子ごとの影(shadowBlur)。点に光彩を出すため、毎フレーム・粒子の数だけ影を描いていた。shadowBlurはcanvasで最も重い処理の一つ。
  • 総当たりの線(O(n²))。近い点どうしを線で結ぶのに全ペアを判定し、しかも同じ線を2回引いていた。

直し方:影をやめて単色の点に(光彩はわずかに失われるが、ほぼ見分けがつかない)。線は各ペアを1回だけ引くよう片側走査に(計算量と描画を半減)。見た目はほぼそのまま、フレームあたりの仕事量だけが大きく減る。これでスクロール中の引っかかりが取れた。[2]

ポイントは、「画面外で止める」だけでは足りなかったこと。粒子アニメは元から、画面に入っていない間や別タブのときは停止していた。それでも「もっさり」した。つまり問題は"動いている間の1フレームが重すぎる"ことにあった。停止制御(いつ動かすか)と、フレーム内の処理量(動いている間どれだけ働くか)は別の軸だ。前者を入れても後者が重ければ、表示中のスクロールは重いままになる。両方を見る必要がある。

重い(before) 粒子毎shadowBlur + 全ペア×2描画 軽い(after) 影なし + 各ペア1回(i<j)
影を外し、線を片側走査に。見た目はほぼ不変、毎フレームの仕事量が激減

07真犯​人③:スクロールを​削る、​ぼかし

最後の容疑者は、CSSの backdrop-filter: blur(背景をすりガラス状にぼかす効果)。カバー画像の上に重ねたカテゴリの小さなラベルに、これが付いていた。

1枚なら問題ない。だがマガジン一覧ではカバーが14枚。つまり14枚分のぼかし合成が、スクロールのたびにGPUで再計算される。これがスクロールの滑らかさを地味に削っていた。直し方は単純で、ぼかしをやめて、単色の半透明背景に。不透明度を少し上げれば可読性は保てる。スクロール時の再描画コストはゼロになった。

blur badge×再描画 blur badge blur badge … ×14 単色半透明に置換再描画コスト0 スクロール毎に14枚のぼかしをGPUで合成 → 重い
「カバー×14のblur合成」をやめるだけで、スクロールの再描画が軽くなる

08​締め:​「もっさり」の​切り分けと、​職人の​責任

今回の学びは、手順そのものだ。「もっさり重い」と言われたら、次の順で疑う。

  • ① まず重量級ライブラリの有無を確認(Three/GSAP/Lenis等)。無ければJSバンドルやスクロール遅延は除外できる。
  • ② 画像。総量・生<img>の有無・next.configの最適化設定。たいていここが最大の犯人。
  • ③ 連続アニメ(canvas/requestAnimationFrame)。影と総当たりを疑う。
  • backdrop-filterが「スクロールで何枚も再描画される場所」にないか。
  • そして計測は本番ビルドで。開発サーバー(最適化オフ)で測ると判断を誤る。

この順番が大事なのは、当てずっぽうの最適化は、たいてい間違った場所を削るからだ。「アニメが重そう」と削っても、実は画像が9割なら、苦労のわりに体感は変わらない。計測してボトルネックを特定し、効く順に潰す。今回も、いちばん地味な画像が、いちばん効いた。

「サイトが速い」ことは、派手な機能ではない。だが、訪れた人の時間を奪わないという、いちばん基本的な誠実さだ。私たちは「サイト自体が、開発力の動く証拠」だと考えている。だからこそ、自社のサイトを、まず速くする。そして数字を、隠さず開示する——10MB→0.3MB、684KB→2KB。これがCAGの透明性の、ささやかな実践だ。

ノートPCとスマホに同じサイトが瞬時に表示され、パフォーマンス計測のゲージが緑の高スコアで光っている、軽くなったサイトの検収風景
速さは、機能ではなく誠実さの一部。職人は、自社のサイトもまず速くする

ナイーブな実装 vs 職人の実装。「もっさり」の差は、たいていこの積み重ねに出る。

観点ナイーブな実装職人の実装(CAG)
画像生<img>でフルサイズPNGnext/imageで表示幅へ自動リサイズ+avif/webp
カバー1枚832 KB7 KB(約99%減)
常駐アセット全ページで684KBを毎回最優先で潰す → 2 KB
canvas粒子毎shadowBlur+O(n²)影なし+各ペア1回(i<j)
blurスクロールで14枚再描画単色化で再描画コスト0
直し方当てずっぽうで削る計測→切り分け→本番ビルドで検証

※ 数値は本サイト(Next.js + Vercel)での実測(2026-06時点・v0)。`next build`→`next start` 環境で計測。条件により前後する。

脚注

  1. 本記事は、当サイトのブログをWEBマガジン化した直後に「もっさり重い」と感じた実体験から、原因を計測で特定し改善した一次記録。固有の内部パス・設定の全文は省いた。
  2. canvasの粒子アニメは、画面内にある間だけ描画し、オフスクリーンや非表示タブでは停止する実装(IntersectionObserver+visibilitychange)+reduced-motion対応は元から入れていた。今回はそれに加え「画面内にある間の1フレームの仕事量」を削った。

「自分たちの​サイト、​なんか​重い​気が​する」——​その正体、​計測で​突き止めます。

表示速度の調査・改善も、AI駆動で速く。まずは相談から——問い合わせは、AIがその場でお応えします。

無料で相談する →

言語化できるものは、全て作る。

あなたの「作りたい」を、定価とスピードで形に。まずは無料の相談から。

制作事例を見る