7 ポイント 投稿者 GN⁺ 2025-05-15 | 1件のコメント | WhatsAppで共有
  • Critical CSSは、ページの**「最初に表示される領域(above the fold)」をレンダリングするために必要な最小限のCSSだけを抽出したもので、これをHTMLにインライン化するとFCP(First Contentful Paint)**などの Core Web Vitals が改善されます
  • HTML の <head> にインライン化することで、ブラウザはスタイルシート全体の読み込みを待たずに素早くコンテンツをレンダリングできます
  • 体感読み込み速度の向上Lighthouse スコアの上昇SEO と UX の改善といった利点があります
  • 非必須の CSS は <body> の末尾で <link> により読み込むか、JavaScript で遅延読み込みすることで、さらにパフォーマンスを最適化できます
  • ユーザー自身で CSS リンクのパスやアセット参照を調整する必要がある点に注意が必要です

Critical CSS Generator

  • Critical CSS Generatorは、Web ページで本当に必要な最小限の CSS コードだけを抽出するツールで、用途に最適化された CSS 抽出が可能です
  • Critical CSS とは、ページで最初に表示される領域をスタイリングするために必要な最小限の CSS ルールのことです
  • この方法により、ブラウザはすべてのスタイルシートの読み込みを待たずに主要コンテンツをすぐ表示できるため、パフォーマンスや Core Web Vitals(FCP など)の改善に役立ちます

なぜ使うべきか?

  • 初期読み込みの体感速度がより速くなる
  • Lighthouse スコアの向上
  • SEO とユーザー体験の改善

🔧 適用方法

Step 1: Critical CSS のインライン化

  • <style> タグ内に Critical CSS を挿入し、HTML の <head> の最上部に配置します
  • ほかのスタイルシートやスクリプトより先に配置する必要があります
  • 内部 asset パスは必要に応じて修正が必要です
    <style>  
      /* Critical CSS for your page */  
      /* ... CSS content ... */  
    </style>  
    

Step 2: 非必須 CSS の遅延読み込み(基本方式)

  • 元の <link> タグは <head> から削除し、</body> の直前に配置します
  • こうすることで、初期レンダリングは Critical CSS のみで進み、非必須 CSS は後から読み込まれます
    <html>  
      ...  
      <body>  
        ...  
        <link rel="stylesheet" href="/css/vendors.min.css">  
        <link rel="stylesheet" href="/css/style.min.css">  
      </body>  
    </html>  
    

Step 3(任意): JavaScript による非同期スタイル読み込み

  • ページ読み込み完了後に JavaScript で非必須 CSS を動的に読み込みます
  • ネットワーク速度が遅い場合にパフォーマンス向上が期待できます
  • 既存の <head> 内にあるすべての非必須 CSS の <link> は削除する必要があります
    window.addEventListener("DOMContentLoaded", function () {  
      console.log("✅ Page loaded, now loading non-critical stylesheets...");  
      let stylesheets = [  
        // "/css/vendors.min.css",  
        // "/css/style.min.css",  
      ];  
      let loadedCount = 0;  
      function checkAllStylesLoaded() {  
        loadedCount++;  
        if (loadedCount === stylesheets.length) {  
          console.log("✅ All non-critical stylesheets loaded...");  
        }  
      }  
      stylesheets.forEach(function (href) {  
        var link = document.createElement("link");  
        link.rel = "stylesheet";  
        link.href = href;  
        link.onload = checkAllStylesLoaded;  
        link.onerror = () => console.warn(`Failed to load stylesheet: ${href}`);  
        document.head.appendChild(link);  
      });  
    });  
    

1件のコメント

 
GN⁺ 2025-05-15
Hacker Newsのコメント
  • レスポンシブ対応までできるなら素晴らしいと思う。レスポンシブなクリティカルスタイルの重複排除が難しくて、結局いつも手でスタイルシートを修正し続けてきた。クリティカルCSSはサイズが重要なので、CSS変数のようなものも down-compile するオプションがあるとよさそう。それから、非クリティカルCSSの <link> タグを </body> の直前に置けという助言はおすすめしない。CSSは素早く取得すべきで、この方法だとCSSの発見が遅れてダウンロードも遅くなる。代わりに preload と noscript を組み合わせる方法を勧める。<link rel="preload" href="styles.css" as="style" onload="this.rel='stylesheet'"> <noscript><link rel="stylesheet" href="styles.css"></noscript>

    • この preload にJSコードを書く方法は、CSPで unsafe-inline を許可していないとブロックされるのでは、という疑問がある

    • CSSをJSハックで読み込む方式は使いたくない。スタイルシート適用時にページ全体の layout/style 再計算が起きる可能性がある。ブラウザはページ下部にあっても stylesheet を素早く取得する

    • prefetch 属性と HTTP ヘッダーヒント、そして CDN の組み合わせだけでも似たような効果は得られる。わざわざクリティカルCSSを継続的に rebuild する必要はない。CF のような CDN をちゃんと使えばかなり速い

    • その通りだと思う。こうしたオプションも入れる予定だ。'before body' の代わりに 'DOMCONTENTLOADED' オプションを試したが、古いスマホや遅いネットワークでもUXと Lighthouse の両面で十分に良好に動作した

    • レスポンシブ対応の意見には強く同意する

  • 私の考えでは、これは早すぎる最適化という感じだ。CSSが非常に複雑だったり、読み込むリソースが多い場合には価値があるだろうが、ほとんどの状況ではCSS、HTML、JSをきれいに書くほうが効率的で、この方式は不要だったり、むしろ害になることもある

    • とても有用だ。フリーランスとして WordPress のWebサイトをよく請け負うが、複数の開発者や代理店を経るうちにCSS/JSが完全に混沌としていることが多い。こういうツールをぜひ使ってみたい

    • CSSが複雑だったりリソースが多いほど、むしろ最適化の純効果は小さくなる。ここで狙っているのは RTT latency の最適化で、クリティカルCSSが大きいほど最適化コストが上がるので純利益は減る

    • 12年前ならこういうツールにお金を払っていただろう。何年も積み上がった膨大なCSSがあり、どのルールがクリティカルなのか把握しにくかった

    • 多くのサイトでは確かに早すぎる最適化かもしれない。だがニュース/メディアのようにクリック数に敏感なサイトでは、「即時の」ページロードが非常に重要だ。1秒を超えるだけで離脱率や広告収益が落ちる。HuffPost でも10年前にこの最適化を試していた

    • フロントエンド開発の現状を見ると本当にやりすぎだと感じる。Lighthouse のようなツールが、意味のない数字のための最適化に執着させ、その結果ビルドの複雑さだけが増え、実際のユーザーは体感もしないのに開発だけが不便になっている。その一方で、本当に基本的なUI/状態管理のミスだらけのサイトもよく見かける。もどかしい

    • きれいな CSS、HTML、JS が正解なのはそうだが、ときには散らかったプロジェクトを引き継ぐこともあれば、テンプレートを使うこともあるし、自分で開発していても設計がこんがらがることはある

    • 私にとってCSSの読み込み方式は、開発の最初の段階で必ず検討する項目だ。うちのWebは page speed test の点数が低くてクライアントが離れることが多かった。性能がSEOに反映されるので非常に重要だ。Google Lighthouse で100点を取るためにページ最適化を自分で一から設計し直した。CSS/JS の読み込み順序と方式まで、すべて最初から計画しないと後から手直しする作業が増える。私たちは fold の上と下でCSSも分け、適切な場所にインラインで含めたし、fold 下のJSはスクロールされるまでまったく評価しない。Lighthouse が提案することはすべて反映した。以前のシステムは全ページにサイト全体のCSS(3〜4MB)を載せ、JSはさらにひどかった。初期の最適化設計がなされていなかったせいだ。まだそのシステムを使っているので名前は出せないが、内部ではずっと問題になっている。性能が目標なら、早すぎる最適化という概念はないと思う。最初から全部考慮すべきだ。その結果、モバイルを含むすべてのクライアントで100点の性能が出ており、競合と比べても優位だ。このツールを自分のサイトで試したが、これ以上最適化する余地がないほどすでに全部反映されていて効果はなかった

  • Astro フレームワークで作った自分のページでは、HTML 27.52KB(圧縮時 6.1KB)、JS は 10KB 未満、クリティカルCSSは57KB(圧縮時 7KB)だ。同種のサイトは 100KB〜1MB まである。きれいに作ればインライン CSS/JS なしでも resource hints だけで十分速い。nginx+HTTP/2+edge cache の組み合わせなら、クリティカルCSSやインラインJSなしでも 100/100 の性能は可能だ。ページごとに 7KB 追加するのは非効率ではないかと思う。実装面では SPA/edge caching のほうがはるかに環境に優しく高速だ。Elementor のように極端に重いHTMLを送る必要はない。モバイルのバッテリーは限られているのだから、不要なデータまで送る理由はない

    • いいトリックではあるが、CDN と HTTP/2 がすでに一般的な状況では、こうした最適化は結局帯域幅を無駄にするだけだ。ベンチマークの数字が少し良くなるだけで、実際には 10〜20ms ほど速くなる程度だ

    • すべてのページにクリティカルCSSを含めるのが正解とは限らない。初回訪問(キャッシュがない状態)やセッションの開始ページ程度にだけ selective に使うのも、不要な data bloat を避ける方法だ

  • クライアントの依頼でクリティカルCSS抽出ツールを探したが、望む機能がなかったので Puppeteer と自作ソリューションを共有することになった。ページロード後どれだけ待つかを指定できる。有料サービスも使ったが気に入らず返金してもらった。フィードバック歓迎で、今は無料で公開している

    • penthouse パッケージのような既存ツールに問題があったのか気になる

    • CSSのないサイトを入力するとエラーになる

    • コードは公開されているのか。Vite/Astro プラグインとしても使いたい

    • penthouse のUI版なのか聞きたい。設定値がかなり似ている

  • この方法はむしろ逆効果だ。非常に一貫した FOUC(スタイル未適用状態のちらつき)が発生する。レイアウトが途中で変わると、すでに何かをクリックしているユーザーは大きな不便を被る。単なる見た目の問題ではなく、実際のユーザビリティの問題だ

    • 私もこの方式を適用後に一部スタイルを修正したが、最終的には CLS(累積レイアウトシフト)0 に最適化できた。予算が少なくライブラリの多いテンプレートを使う場合には非常に有用だった

    • CSS network request を block せずに FOUC を防ぐことが、そもそもの目的では?

  • この方式は、初回ページビューでCSSキャッシュがまったくないという前提ではより意味がある。実際には新規/再訪問者の比率、CSSキャッシュ設定、CDN、103 early hints、クリティカルCSS/initial congestion window など、さまざまな要素の trade-off がある

    • そう、初回流入専用で、強く推奨する方法というより trade-off だ。最善なのはすべてのコードとスタイルを自分で書き、ライブラリ利用を減らすことだ
  • パフォーマンス測定時、localhost では CSS の影響がほとんどないレベルだった。CSSを完全に取り除いても改善は 7ms 未満で、それすら測定誤差の範囲だった

    • クライアント-サーバー latency の最適化は localhost のような低 latency 環境では当然ほとんど無意味だ。これが必須の最適化だとは思わないが、localhost でのテストは良いベンチマークではない
  • 自分のサイトでこのツールを使ったところ、本来不要なデバッグ用要素までCSSに抽出された。たとえばサイトのグリッドオーバーレイ用の body::after などもそのまま CSS に含まれていた(忘れていたが今回気づいた)

  • 私は、CSSがなくても意味が十分伝わるHTMLの書き方を好む。こうすれば文書構造が複雑になるのを事前に防げる

    • ただし、これはすべてのサイトに当てはまるわけではない。たとえば左→右、上→下に読むのが前提ではないUIも多い
  • アイデア自体は新鮮だったので個人サイトに適用してみたが、penthouse ライブラリでCSS欠落エラーが発生した {"error":true,"name":"Error","message":"css should not be empty" ...}

    • このケースも確認してみる予定。ありがとう