Firebase 的 Spark 免费档是静态托管里最大方的之一,但 Google 的说明含糊,让人搞不清自己的站到底够不够用。这篇把数字翻译成真实 PV、教你怎么测量自己的站,并给出 Blaze 不被意外扣费的预算配置。
问题背景
Spark 给你 10 GB 文件存储 + 每天 360 MB 流量,免费。流量是按天重置,不是按月。“我火了一下就被扣了 400 美金”那类故事,几乎都是 Cloud Functions 或 Firestore 的事,跟 Hosting 没关系。Hosting 在 Spark 下有硬天花板——当日流量用完,站点直接返回 quota 错误,到 UTC 0 点重置。
判断标准
- 日 PV 大约一万以下,资源大小一般。
- 站点总大小不超过 10 GB(内容站基本都满足)。
- 你不需要 rewrite 到 Cloud Run / Functions(那些必须 Blaze)。
- 某一天爆量返回 quota 错误你也能接受。
- 平均单页重量在 ~500 KB 以下(文本 + 已缓存图片 + 已缓存字体)。
快速结论
绝大多数独立内容站和 SaaS 落地页,Spark 可以一直用下去。需要 Cloud Functions、Cloud Run rewrite,或者预期流量长期超 360 MB/天,再升 Blaze。
开始前准备
- Firebase Console 打开项目,能看到当前计划。
- 装好
firebase-tools,可以从 CLI 拉用量。 - 知道 build 输出目录大小(
du -sh dist/)再开始测量。
实操步骤
- 测量平均单页重量。 Chrome DevTools → Network → 刷新,看底部总和。或者用
curl估算 HTML + 关键资源:
curl -sL -o /tmp/page.html https://yourdomain.com/articles/some-slug/
wc -c /tmp/page.html
# 45000 (45 KB HTML)
# 加上 immutable 的部分(一个访客只付一次):
curl -sIL https://yourdomain.com/_astro/index.abc123.css | grep -i content-length
curl -sIL https://yourdomain.com/_astro/main.def456.js | grep -i content-length
内容站带 hash 资源时,回头客单页重量常在 30-80 KB;首访在 200-500 KB。
- 算日流量。 粗公式:
daily_MB = (first_visits * first_visit_KB + repeat_visits * cached_visit_KB) / 1024
+ sitemap_等杂项
500 PV / 天的博客举例:
first_visits = 300 * 400 KB = 120000 KB ≈ 117 MB
repeat = 200 * 60 KB = 12000 KB ≈ 12 MB
合计 ≈ 129 MB/天 ← 360 MB 内宽松
- 一周后看真实数字。 Firebase Console → Hosting → Usage,或者 CLI:
firebase hosting:sites:list
# 看 site 列表,仪表盘 URL 里有每日带宽
# 或直接拉 Cloud Monitoring 指标:
gcloud monitoring time-series list \
--filter='metric.type="firebasehosting.googleapis.com/network/sent_bytes_count"' \
--interval-start-time=-P7D --format=json | jq '.[].points'
-
开预算告警。 Firebase Console → Project Settings → Usage and billing → Details & Settings → 设 $1 预算,50% / 90% / 100% 告警。Spark 也建议加,将来升级了不至于裸奔。
-
升 Blaze 的话设每日花费上限。 GCP Console → Budgets & alerts → Create budget。“Alert thresholds” 不会自动断流,但会发邮件。要真正断流,用 Google 文档里的 “Pub/Sub + Cloud Function 关闭计费” 配方:
# budget-action.yaml 示例
budget:
displayName: hosting-cap
amount:
specifiedAmount: { currencyCode: USD, units: 10 }
thresholdRules:
- thresholdPercent: 0.5
- thresholdPercent: 0.9
- thresholdPercent: 1.0
notificationsRule:
pubsubTopic: projects/your-project/topics/billing-alerts
disableDefaultIamRecipients: false
- 大批量发内容前审一次资源大小。 CI 里加:
TOTAL=$(du -sb dist/ | cut -f1)
LIMIT=$((10 * 1024 * 1024 * 1024)) # 10 GB
if [ "$TOTAL" -gt "$LIMIT" ]; then
echo "build 输出超过 Spark 10 GB 天花板"; exit 1
fi
- 图片打包前先压缩。 一张 2 MB 头图能在 180 次访问内吃光 Spark 当日额度:
# sharp 通过 Node 脚本或 astro-imagetools
npx sharp-cli --input "public/raw/**/*.{jpg,png}" \
--output "public/img/" \
--resize 1600 \
--format webp \
--quality 82
执行检查清单
du -sh dist/输出远低于 10 GB。- 首访和回头客的单页重量都测过。
- 日流量估算低于 360 MB 的 50%(留尖峰空间)。
- Spark 阶段也配好预算告警。
- 图片流水线产出压缩过的
.webp/.avif头图。
上线后验证
- 7 天后 Firebase Console → Hosting → Usage 与估算误差 ~25% 以内。
- 项目日志没有 “Quota exceeded” 事件。
- 模拟触发 50% 阈值时收到告警邮件。
容易踩的坑
- 把 Hosting 流量和 Firestore / Functions 流量混在一起算——它们是分开计费的。
- 忘了流量是按天重置,不是按月——爆一天不会消耗”整月”。
- 没压缩的大图把额度几个小时就吃完。
- 在 Spark 下加 rewrite 到 Cloud Functions——那些调用会失败,Functions 要求 Blaze。检测:被重写的路径返回 500。
- 直接 hot-link 大视频到 bundle 而不是用 YouTube/Vimeo。视频是最快炸 Spark 的方式。
- 忘了 preview channel 也算同一份配额。
FAQ
- 免费额度超了会怎样?: Spark 下站点会返回 quota 错误,到 UTC 0 点重置。不会自动扣钱。
- 免费档包含自定义域名和 SSL 吗?: 包含。自定义域名 + 免费 SSL 在 Spark 下都不要钱。
- 免费档能用 preview channel 吗?: 能,包括独立 URL。它们和正式部署共享存储 / 流量配额。
- 什么时候该升 Blaze?: 需要 Cloud Functions 或预期日 PV 超一万的时候。Blaze 按用量付费,Hosting 部分本身很便宜。
- Blaze 上 Hosting 单价多少?: 360 MB/天免费额度之外约 $0.026/GB。每月 10 GB 出流量大约 $0.25。