



WithCodeMedia-1-pc
WithCodeMedia-2-pc
WithCodeMedia-3-pc
WithCodeMedia-4-pc




WithCodeMedia-1-sp
WithCodeMedia-2-sp
WithCodeMedia-3-sp
WithCodeMedia-4-sp








npx astro add partytown から forward 設定までの完全な手順GoogleAnalytics.astro コンポーネントの実装コード全文import.meta.env.PROD で本番環境のみ計測する方法
生徒AstroサイトにGoogle Analytics 4を入れたら、PageSpeed InsightsのスコアがガクッとB下がってしまいました。パフォーマンスを下げずにGA4を導入する方法ってありますか?



よーく聞くんだぞ。それは「Partytown」を使えばほぼ解決できるんじゃ!PartytownはGoogleアナリティクスのような重い外部スクリプトをWebワーカーという別スレッドで動かすことで、メインスレッドへの影響を最小限に抑えてくれるライブラリじゃ。今日はAstro + GA4 + Partytownの導入手順をコード付きで徹底解説するぞい!
Astroで作ったサイトにGoogle Analytics 4(GA4)を普通に設置すると、外部スクリプトの読み込みがメインスレッドをブロックし、Core Web Vitalsのスコアが下がってしまいます。「計測したいけどパフォーマンスも落としたくない」というジレンマはAstroユーザーが共通して直面する課題です。
実際、GA4のトラッキングスクリプトは外部CDNから読み込む100KB超のJavaScriptで、低速回線やモバイルでは表示速度に無視できない影響を与えます。Partytownを使ってWebワーカーに逃がすことで、同じスクリプトをメインスレッドを汚染せずに実行できます。
本記事では、AstroサイトにGoogle Analytics 4をPartytownで導入する4ステップと、本番環境のみ読み込む環境変数の設定、動作確認の方法をすべてコード付きで解説します。
Partytownを使う前に、「なぜ外部スクリプトがパフォーマンスを下げるのか」と「Partytownがどう解決するのか」を理解しておくと、設定内容が腑に落ちやすくなります。


【通常のGA4スクリプトがPageSpeedを下げる理由】
ブラウザの構造:
メインスレッド(1本)
├─ HTMLの解析・DOMの構築
├─ CSSの計算・レイアウト
├─ JavaScriptの実行 ← ここで外部スクリプトも実行される
└─ 描画(Paint / Composite)
問題:
→ GA4のスクリプト(外部CDNから100KB超)がメインスレッドで実行される
→ 実行中、ページの描画・ユーザー操作への応答がブロックされる
→ FID(First Input Delay)・TBT(Total Blocking Time)が悪化する
→ Core Web Vitals スコアが下がる
【Partytownを使うと何が変わるか】
ブラウザの構造(Partytown導入後):
メインスレッド Webワーカー(別スレッド)
├─ HTMLの解析・DOM構築 │
├─ CSSの計算・レイアウト │ ← GA4スクリプトがここで動く
├─ JSの実行(軽くなる!) │ メインスレッドに影響ゼロ
└─ 描画(高速!) │
効果:
✅ メインスレッドのブロック時間が大幅に減少
✅ FID / TBT の改善 → Core Web Vitals が向上
✅ PageSpeed Insights のスコアが上がる
✅ GA4のトラッキングは通常通り動作する(計測精度に影響なし)
注意点:
❌ window オブジェクトへの直接アクセスは制限される
→ forward オプションで dataLayer.push を転送する設定が必要
| パッケージ | 動作確認バージョン |
|---|---|
| Astro | 5.0.5 以降 |
| @astrojs/partytown | 2.1.3 以降 |
| Node.js | 18.x 以降推奨 |
まずはGA4の管理画面からトラッキングIDを取得します。すでに取得済みの場合はこの手順を読み飛ばしてください。


G-XXXXXXXXXX 形式)【取得するトラッキングID】
G-XXXXXXXXXX ← この形式の文字列(X の部分は英数字)
・「G-」から始まる文字列がトラッキングID
・後のコンポーネント作成で使用するのでメモしておく
・絶対に公開リポジトリに直書きしない
→ 環境変数(.env)に保存するのが安全
Astroには公式インテグレーションとして @astrojs/partytown が用意されており、コマンド1つで設定まで自動で行えます。


# Astroプロジェクトのルートで実行する
npx astro add partytown
コマンドを実行すると以下の確認が表示されます。すべて y で進めてください。
✔ Continue? … yes
✔ @astrojs/partytown を package.json に追加しますか? … yes
✔ astro.config.mjs を更新しますか? … yes
自動追加されたコードに、forward: ["dataLayer.push"] の設定を必ず追記してください。この設定がないとGA4のイベントがWebワーカーからメインスレッドへ正しく転送されず、計測が機能しません。
// astro.config.mjs
import { defineConfig } from "astro/config";
import partytown from "@astrojs/partytown";
export default defineConfig({
integrations: [
partytown({
config: {
// dataLayer.push をWebワーカーからメインスレッドへ転送する
// ← この設定がないとGA4のイベントが計測されない
forward: ["dataLayer.push"],
},
}),
],
});
【forward オプションが必要な理由】
問題の背景:
→ WebワーカーはブラウザのAPIの一部(window・documentなど)にアクセスできない
→ GA4は内部で window.dataLayer.push() を呼び出してイベントを記録する
→ スクリプトをWebワーカーに移すと、window が参照できずイベントが消える
解決策:
→ forward に "dataLayer.push" を指定すると
Partytownがダミーの dataLayer.push をメインスレッドに作成する
WebワーカーのGA4が dataLayer.push を呼ぶ
→ メインスレッドのダミーが受け取って本物の dataLayer.push に渡す
▶ forward の設定はPartytown導入で最もよくミスするポイントなので要注意
GA4のトラッキングコードを1か所にまとめたAstroコンポーネントを作成します。コンポーネント化することで、Layout.astroから1行で呼び出せるようになります。


src/
├── components/
│ └── GoogleAnalytics.astro ← このファイルを新規作成
├── layouts/
│ └── Layout.astro
└── pages/
└── index.astro
<!-- src/components/GoogleAnalytics.astro -->
<!--
重要:script タグに type="text/partytown" を指定する
→ これがないとWebワーカーではなくメインスレッドで実行されてしまう
-->
<!-- ① GA4の外部スクリプトを非同期で読み込む -->
<script
type="text/partytown"
async
src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"
></script>
<!-- ② GA4の初期設定スクリプト -->
<script type="text/partytown">
window.dataLayer = window.dataLayer || [];
function gtag() { dataLayer.push(arguments); }
gtag("js", new Date());
gtag("config", "G-XXXXXXXXXX");
</script>
G-XXXXXXXXXX の部分を手順1で取得したトラッキングIDに置き換えてください。
トラッキングIDをソースコードに直書きすると、GitHubなどに誤って公開してしまうリスクがあります。環境変数で管理するのがベストプラクティスです。
# .env(プロジェクトルートに作成)
PUBLIC_GA_TRACKING_ID=G-XXXXXXXXXX
# .env はリポジトリに含めない!
# .gitignore に .env を追記しておく
<!-- src/components/GoogleAnalytics.astro(環境変数版) -->
---
// Astroでは PUBLIC_ プレフィックスのついた環境変数がクライアントに公開される
const trackingId = import.meta.env.PUBLIC_GA_TRACKING_ID;
---
<script
type="text/partytown"
async
src={`https://www.googletagmanager.com/gtag/js?id=${trackingId}`}
></script>
<script type="text/partytown" define:vars={{ trackingId }}>
window.dataLayer = window.dataLayer || [];
function gtag() { dataLayer.push(arguments); }
gtag("js", new Date());
gtag("config", trackingId);
</script>
【Astroの環境変数の使い分け】
PUBLIC_ プレフィックスあり(例:PUBLIC_GA_TRACKING_ID)
→ クライアントサイド(ブラウザ)でも参照できる
→ ビルド後のJSに含まれる
→ GA4のトラッキングIDなど「公開されても問題ない値」に使う
PUBLIC_ プレフィックスなし(例:SECRET_API_KEY)
→ サーバーサイド(.astroファイルのfrontmatter)のみ参照可能
→ ブラウザのJSには絶対に含まれない
→ APIキー・データベースの接続情報など「秘密にすべき値」に使う
作成した GoogleAnalytics.astro を Layout.astro の <head> 内にインポートして配置します。


<!-- src/layouts/Layout.astro -->
---
import GoogleAnalytics from '../components/GoogleAnalytics.astro';
---
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="generator" content={Astro.generator} />
<title>{title}</title>
<!-- GoogleAnalytics コンポーネントを head 内に配置 -->
<GoogleAnalytics />
</head>
<body>
<slot />
</body>
</html>
この時点でGA4は全ページに適用されます。ただしこのままでは開発環境でも計測されてしまうため、次のステップで本番環境のみに絞ります。
開発環境でもGA4が動いていると自分のアクセスが計測データに混入し、数値が正確でなくなります。import.meta.env.PROD で本番環境のみGA4を読み込むように設定しましょう。


<!-- src/layouts/Layout.astro(本番環境のみGA4を読み込む版) -->
---
import GoogleAnalytics from '../components/GoogleAnalytics.astro';
// import.meta.env.PROD
// → 本番ビルド(npm run build)のとき true
// → 開発サーバー(npm run dev)のとき false
const isProd = import.meta.env.PROD;
---
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="generator" content={Astro.generator} />
<title>{title}</title>
<!-- isProd が true のときだけ GoogleAnalytics を表示する -->
{isProd && <GoogleAnalytics />}
</head>
<body>
<slot />
</body>
</html>
【Astroの環境変数まとめ】
import.meta.env.PROD
→ npm run build で生成した本番ビルドのとき true
→ npm run dev(開発サーバー)のとき false
import.meta.env.DEV
→ 開発サーバーのとき true(PRODの逆)
import.meta.env.MODE
→ "production" または "development" の文字列
import.meta.env.BASE_URL
→ astro.config.mjs の base オプションの値
活用例:
{import.meta.env.PROD && <GoogleAnalytics />}
→ 本番のみGA4を読み込む(開発中は計測しない)
{import.meta.env.DEV && <DebugPanel />}
→ 開発中だけデバッグパネルを表示する
設定が完了したら、GA4とPartytownが正しく動いているか確認しましょう。本番ビルドを使う必要があるため、npm run build 後に確認します。


# 本番ビルドを実行
npm run build
# プレビューサーバーを起動(本番ビルドの動作確認用)
npm run preview
# → http://localhost:4321 でアクセスできる
# → isProd が true になるのでGA4が読み込まれる
1. ブラウザで http://localhost:4321 を開く
2. F12で開発者ツールを開く
3. 「Network」タブを選択
4. フィルターに「gtag」と入力
5. ページをリロード
確認ポイント:
✅ "googletagmanager.com/gtag/js?id=G-XXXXXXXXXX" のリクエストが
「Initiator: partytown」と表示されていればWebワーカー経由で動いている
❌ Initiatorが通常のスクリプトになっている場合
→ type="text/partytown" が script タグについているか確認する
1. Google Analytics の管理画面にアクセス
2. 左メニュー「レポート」→「リアルタイム」を開く
3. プレビューサーバー(localhost:4321)のページを開く
4. 「現在のユーザー数」が1以上表示されれば計測成功
注意:
→ localhost での計測はGAにフィルタリングされる場合がある
→ 本番環境にデプロイした後で確認するのが確実
【Partytown導入前後のPageSpeed Insightsの変化(目安)】
計測指標 導入前 導入後(目安)
─────────────────────────────────────────────
TBT(Total Blocking Time)
100〜300ms → 20〜80ms
FID(First Input Delay)
100ms超 → 50ms以下
パフォーマンススコア 70〜80 → 85〜95
※ サイトの構成や他スクリプトの量によって効果は異なる
※ 効果を最大化するには、他の外部スクリプト(広告・チャット等)も
同様にPartytownに移すことを検討する
設定後に想定通りに動かないケースと、その解決方法をまとめます。


【原因と対処法】
原因A:astro.config.mjs に forward: ["dataLayer.push"] を書き忘れている
対処:astro.config.mjs を確認して forward オプションを追記する
原因B:script タグに type="text/partytown" を付け忘れている
対処:GoogleAnalytics.astro の両方の script タグに
type="text/partytown" が付いているか確認する
原因C:開発サーバー(npm run dev)で確認している
対処:npm run build && npm run preview でビルド後に確認する
(isProd を使っている場合、dev では読み込まれない)
原因D:トラッキングIDが間違っている
対処:G- から始まるIDが正しく設定されているか確認する
// よく見られるエラーメッセージ
// "Partytown could not find 'dataLayer'"
// → forward オプションが設定されていない
// astro.config.mjs を確認・修正する
partytown({
config: {
forward: ["dataLayer.push"], // ← これが必要
},
})
<!-- GTMをPartytownで動かす場合(GA4ではなくGTM経由の場合) -->
<script
type="text/partytown"
async
src="https://www.googletagmanager.com/gtm.js?id=GTM-XXXXXXXX"
></script>
<script type="text/partytown">
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({ "gtm.start": new Date().getTime(), event: "gtm.js" });
</script>
// astro.config.mjs の forward も更新が必要
partytown({
config: {
forward: ["dataLayer.push"],
// GTM独自のイベントも必要に応じて追加
},
})
A. 基本的には計測精度に影響ありません。Partytownはスクリプトを実行する場所(Webワーカー)を変えるだけで、GA4の計測ロジック自体は変わらないからです。ただし、forward オプションの設定ミスがあるとイベントが欠落する場合があるため、動作確認は必ず行ってください。
A. はい。Google Tag Manager・Meta Pixel・Hotjar・インターコムなどの多くの外部スクリプトをPartytownで動かすことができます。type="text/partytown" を追加するだけで動くものと、forward オプションへの追記が必要なものがあります。各スクリプトの公式ドキュメントやPartytownのドキュメントを確認しながら設定してください。
A. 使えます。Next.js・Nuxt・SvelteKit・Remixなど主要なフレームワーク向けのインテグレーションが用意されています。また、フレームワークなしのVanilla JSプロジェクトでも、@builder.io/partytown を直接インストールして使えます。基本的な考え方(type="text/partytown"・forward設定)はどの環境でも共通です。
A. @astrojs/partytown の基本的な設定方法はAstro 4.x と 5.x で大きく変わりません。ただし、Astroのバージョンアップ時は @astrojs/partytown のバージョンも合わせてアップデートし、公式のマイグレーションガイドを確認することを推奨します。
A. 動作します。Partytownはビルド時に静的ファイルとして生成され(public/~partytown/ 以下)、サーバーに依存しない仕組みで動きます。Vercel・Netlify・Cloudflare Pagesいずれも追加設定なしで使えます。デプロイ後は必ずGA4のリアルタイムレポートで計測できているか確認してください。



Partytownって設定が多くて難しそうに見えましたが、やってみたら意外と簡単でした!他にもパフォーマンスを上げる方法はありますか?



よいことに気がついたのう!Astroはもともと「必要なJavaScriptだけ送る」という設計思想があるから、パフォーマンスには有利じゃ。さらに上を目指すなら、画像の最適化(Astro Image)・フォントのサブセット化・CSS/JSのバンドルサイズ削減も有効じゃぞ。WithCodeでHTML/CSS/JSの基礎を学んだ上でAstroに取り組むと、こうした最適化の理由が自然に理解できるようになるんじゃ!



なるほど!基礎があってこそ最適化の意味がわかるんですね。PageSpeedのスコアが上がった瞬間はすごく嬉しかったです!引き続き勉強します!
本記事では、AstroサイトにGoogle Analytics 4をPartytownで導入する方法として、インストールから本番環境の設定・動作確認・トラブルシューティングまで解説しました。
npx astro add partytown の1コマンドで完了。ただし forward: ["dataLayer.push"] の追記を忘れずに。type="text/partytown" を指定するのが最重要。これがないとWebワーカーで動かない。PUBLIC_GA_TRACKING_ID として .env に保存し、ソースコードに直書きしない。import.meta.env.PROD で本番ビルド時のみGA4を読み込み、開発中の計測データ混入を防ぐ。npm run build && npm run preview でビルド後に確認し、ネットワークタブで「Initiator: partytown」と表示されれば成功。AstroにGA4をPartytownで導入することで、パフォーマンスを落とさず正確な計測データを取得できるようになり、SEOとUXの両面でサイトの品質を高めることができます。
WithCodeで学んだHTML/CSS/JavaScriptの基礎を土台に、Astroでのサイト制作を始めてみましょう。パフォーマンスへの理解が深まるほど、Webサイトの質を高める手段が広がっていきます。
副業・フリーランスが主流になっている今こそ、自らのスキルで稼げる人材を目指してみませんか?
未経験でも心配することはありません。初級コースを受講される方の大多数はプログラミング未経験です。まずは無料カウンセリングで、悩みや不安をお聞かせください!
公式サイト より
今すぐ
無料カウンセリング
を予約!