EmDash は遅い (v0.9.0 時点)

Cloudflare が 2026 年 4 月に発表した EmDash という CMS を試した。Astro + Cloudflare Workers + D1 + R2 で動くフルスタック CMS で、「WordPress の精神的後継者」を謳っている。AI agent first 設計なのでエージェントとの相性も良く、自前のプラグイン作成も比較的スムーズ。
期待して触ってみたが、体感で明らかに遅い。

▲ EmDash のサイト構築時にインストールできるデモデータを適用したサイト。今回の計測対象。
どれぐらい遅いか
create-emdash で生成したデフォルトのデモプロジェクト (トップに記事リストが並ぶ典型的なブログ) を Cloudflare Workers にデプロイし、レスポンスタイムを計測した。プランは Cloudflare Workers Paid ($5/月)。
=== トップページ (記事リスト付き) ===
0.925s TTFB=0.916s
0.505s TTFB=0.501s
0.582s TTFB=0.580s
0.486s TTFB=0.484s
0.481s TTFB=0.380s
=== /about ページ (コンテンツは見出しと本文のみ、画像なし、データ取得最小) ===
0.420s TTFB=0.408s
0.464s TTFB=0.458s
0.960s TTFB=0.943s
0.511s TTFB=0.507s
0.410s TTFB=0.392s
トップページで 480ms〜925ms、文字だけの about ページですら 410ms〜960ms。 試行を増やすと cold start に当たって 2〜3 秒に達するケースもある。

ブラウザ側もこの遅さを正しく検出していて、Firefox の開発者ツールでドキュメントリクエストの脇に亀マークの警告が表示される。「Slow server response time (880 ms). The recommended limit is 500 ms.」(推奨上限は 500ms) — つまりブラウザ側の客観基準でも明確に遅いと判定されている。
比較
参考までに、自分が運用している他のサイトの実測。
| サイト | 構成 | 計測 (TTFB) |
|---|---|---|
| www.cyberneura.com | Astro (SSG) + AWS Amplify Hosting / RDB なし | 30ms (cold 160ms) |
| www.ytyng.com | SvelteKit (SSR) + Django Ninja API / PostgreSQL | 70ms |
| chat-attendant.cyberneura.net | SvelteKit (SSG) + Cloudflare Pages / RDB なし | 65ms |
| emoji.ytyng.com | SvelteKit (SSG) + Vercel / RDB なし | 32ms |
| emdash-test-01 (今回) | EmDash 0.9.0 + Cloudflare Workers + D1 + R2 | 480〜960ms |
EmDash とユースケースとして比較できるのは、ブログサイトである www.ytyng.com (このサイト)。比較して EmDash は 7 倍程度遅い。
SSG (静的) サイトと比較すると 20〜30 倍遅い。
「おま環では?」
そう疑って他の人のレポートを探した。結論: おま環ではない。EmDash on Cloudflare Workers + D1 の構造的な性質。
詳細な第三者ベンチマーク
shift64 — "I Bought the Domain Before I Ran the Test. EmDash Still Lost to WordPress."
| EmDash | WordPress | 比 | |
|---|---|---|---|
| Server processing | 543 ms | 84 ms | WordPress が 6.4 倍速い |
| Total TTFB | 596 ms | 136 ms |
著者 (この方は EmDash に好意的で期待していた) の結論を引用:
An SEO professional reviewing crawl-stats charts blind classified the EmDash performance as needing to be "scrapped and rebuilt" (~1,300 ms zone), while the WordPress site landed in "normal, expected" territory.
After aggressive optimization, the gap narrowed only to 4.1× slower, still insufficient for recommendation.
The fundamental issue stems from architecture — D1 database round-trips at the edge create an unavoidable latency floor that optimization cannot overcome without platform-level changes to Cloudflare's infrastructure.
私の実測 (596ms vs 596ms) ともほぼ一致するので、再現性のある数値とみなしていい。
公式以外の検証
- Maciek Palmowski: EmDash a fresh take on CMS — 「EmDash は WordPress ユーザーが本当に困っている performance / hosting cost / plugin bloat をそもそも解決対象にしていない」という指摘。EmDash の主眼は AI agent first と plugin security
- Hacker News thread (47602832) — 性能への直接的な言及は少ないが、全体トーンとして「アーキテクチャは面白いが、過去聞いたことのある話」という反応
食い違いの注意
逆に「EmDash は爆速」と書いている記事もあるが、よく読むと数値の取り方が違う。
- Lushbinary: "P50 latency 1〜3ms" — これは Worker の単純な TCP/HTTP hop 計測で、EmDash アプリ本体のレンダリング時間を含んでいない
- dev.to: "sub-50ms TTFB" — エッジロケーションへの距離だけの話で、実測ではなくマーケティング寄り
これらに惑わされず、実測ベースの shift64.com の数値を信用するほうがよい。
原因
EmDash が出力する Server-Timing ヘッダで内訳が見える。今回計測したリクエストでは:
setup;dur=61 probe
rt;dur=89 runtime init 合計
rt.db;dur=23 D1 マイグレーションチェック
rt.plugins;dur=10 _plugin_state 読み込み
rt.site;dur=12 site info options
rt.market;dur=15 marketplace plugins
rt.hooks;dur=29 exclusive hook resolution
render;dur=346 ← page render (D1 から記事/メディア/メニュー fetch)
mw;dur=496 ← total middleware (上記合計)
ここで重要なのは runtime init の rt.* が毎リクエスト走っている という点。マイグレーションチェック / plugin state 読み込み / site info / hook resolution は全て D1 への独立した SELECT で、EmDash はこれを並列化していない箇所が多く累積する。
加えて、render の 346ms は Astro の page render + EmDash の content fetch + Portable Text レンダリング。ここでも記事一覧・メニュー・関連メディア等を D1 から複数クエリで引いてくる。
Cloudflare の D1 はコードからは SQLite だが、実体は エッジネットワーク越しの SQLite サーバー。1 クエリあたり 5〜15ms のラウンドトリップが発生し、これが累積して 500ms 級になる。
shift64 の検証曰く:
The fundamental issue stems from architecture — D1 database round-trips at the edge create an unavoidable latency floor that optimization cannot overcome without platform-level changes to Cloudflare's infrastructure.
プラットフォーム側 (Cloudflare の D1) にメスを入れない限り、アプリ層の最適化では超えられない。
改善できそうなこと
完全には解決しないが、緩和策はいくつかある。
Cache-Control: public, max-age=Nをパブリックページに付ける → Cloudflare CDN cache hit になればミリ秒級。ただし認証が絡む admin / preview / 動的 API では使えない- D1 Sessions API (read replica) —
astro.config.mjsにsession: "auto"を入れれば有効。ただし read replica が地理的に近くにないと効果が薄い - Astro の
Astro.cache.set(cacheHint)を pages で呼ぶ — EmDash テンプレートのCLAUDE.mdにも書いてあるルール - Node.js + ローカル SQLite (containers) にデプロイ —
~85ms TTFBと劇的に改善するが、Workers の旨味は失う
$5 プランで解決するか?
しない。Workers Paid ($5/月) で変わるのは CPU time 上限 (Free 10ms → Paid 30/50ms) と請求モデルだけで、リクエスト毎の D1 ラウンドトリップ回数とエッジ越しのレイテンシには無関係。
CPU 重い処理 (画像変換等) が発生するならば差は出るが、EmDash のメインフローは I/O 主体なので、$5 にアップグレードしても体感の TTFB はほぼ変わらない。
EmDash 公式 GitHub の動き
emdash-cms/emdash の Issues を性能関連のキーワードで検索しても、performance 専用の open issue は見当たらない。コアチームは速度を主要な目標にしていない (公式キャッチコピーは Plugin Security と AI agent-first)。
つまりフレームワーク側の根本的な改善が積極的に進められている兆しは現時点では見えない。
まとめ
| 期待 | 現実 |
|---|---|
| Cloudflare 公式の最新 CMS だから速い | 構造的に WordPress より 6 倍遅い |
| Workers の cold start <5ms だから瞬時 | Worker 起動は速いが D1 への複数 RPC が累積 |
| Cache-Control で解決 | 静的部分のみ。admin / preview / 動的 API で詰む |
| Workers Paid ($5) に上げれば速い | 無関係。CPU 上限緩和だけ |
現段階では、本番環境採用するにはリスク要素が多いと感じる。
ハンズオンや遊び目的、AI エージェント連携の実験として触る分には全く問題ない。AI agent から CMS をプログラマブルに操作できるのは EmDash の確かな強みなので、その用途なら速度は二の次でいい。
ただし、トラフィックが期待される本番サイトに採用するのは一旦保留が妥当。今後アプリ側の機能を積み増していくと、ライフサイクルフックや plugin の loading が増えて、さらに遅くなる方向にしか行かない (フレームワークの根本改善が入らない限り)。
EmDash チーム or Cloudflare 側で D1 アーキテクチャの改修 (アプリ Worker 内に SQLite を埋め込む形態など) が入るのを待つのが現実的だと思う。
開発相談をお待ちしています。