【ITニュース解説】My Mermaid renderer taught me that headless Chrome is a 300MB tax on every deploy
2026年11月04日に「Dev.to」が公開したITニュース「My Mermaid renderer taught me that headless Chrome is a 300MB tax on every deploy」について初心者にもわかりやすく解説しています。
ITニュース概要
Mermaid図の画像化にHeadless Chromeを使ったら、デプロイ容量が300MB増え、起動が遅くなりメモリも圧迫した。このため専用サービスに切り替え、デプロイコストを削減。汎用ツール導入前に、それが本当に必要か、費用対効果を測る重要性を学んだ。
ITニュース解説
この記事では、ソフトウェア開発の現場でよく使われる図形描画ツールであるMermaid記法で書かれたテキストから、画像ファイルを効率的に生成する方法に関する興味深い経験が語られている。Mermaidは、フローチャートやシーケンス図といった複雑な図形を、簡単なテキスト入力だけで作成できる便利なツールだ。手作業で箱や線を引く手間を省けるため、多くのエンジニアに利用されている。しかし、このようなテキストベースの図形を、実際のシステムやドキュメントで画像として利用するには、何らかの変換処理が必要になる。
記事の筆者は、自動化された処理の流れである「エージェントパイプライン」の中で、Mermaidで記述された図を画像として埋め込む必要に迫られた。この課題に対する最初の解決策として、多くのチュートリアルや一般的な情報源が推奨している「Puppeteer」と「Headless Chrome」の組み合わせを採用した。
「Chrome」とは、皆さんも普段から使っているGoogle Chromeウェブブラウザのことだ。そして「Headless Chrome」とは、このChromeブラウザを、画面表示のためのGUI(グラフィカルユーザーインターフェース)なしで、プログラムから操作できるモードを指す。つまり、ユーザーが直接画面を見ることはないが、裏側でウェブページを開いたり、JavaScriptを実行したり、スクリーンショットを撮ったりといったブラウザの機能を使えるようになる。
「Puppeteer」は、Googleが開発したNode.jsライブラリで、このHeadless ChromeをJavaScriptコードから簡単に制御するためのツールだ。例えば、特定のURLにアクセスしてページのスクリーンショットを撮ったり、PDFに変換したり、Webサイトの自動テストを行ったりと、ブラウザの描画能力や実行環境が必要な様々な用途で汎用的に利用される。Mermaidで記述されたテキストを画像化する場合も、Headless Chrome上でMermaidの描画ライブラリを実行し、その結果表示された図のスクリーンショットを撮る、という方法が直感的に、そして「標準的」なアプローチとして考えられる。筆者もこのセオリーに従い、PuppeteerとHeadless Chromeを使ってMermaid図を画像化するシステムを構築した。
しかし、この「標準的」な解決策には、予期せぬ大きな代償が伴うことが明らかになった。システムを運用環境に「デプロイ」(配置・展開すること)する際にかかる費用、つまり「デプロイ税」と筆者は表現している。具体的には、コンテナ(アプリケーションとその実行に必要なすべてのものを隔離してパッケージ化したもの、Dockerなどが代表的)を再構築するたびに、約300MBものデータがダウンロードされることになった。この300MBというのは、Headless Chromeブラウザ本体とその動作に必要な様々な「依存関係」(他のプログラムやライブラリ)のサイズだ。テキストからたった一枚の画像を生成するためだけに、巨大なブラウザ全体を毎回ダウンロード・インストールすることになる。これは、毎回のデプロイ作業に余計な時間とネットワーク帯域を消費させる大きな負担となった。
さらに、システムが停止状態から初めて起動する際の応答時間、「コールドスタート」も深刻な問題となった。Headless Chromeを起動し、必要なライブラリを読み込み、レンダリング環境を整えるまでに、ミリ秒単位だった起動時間が数秒単位へと大幅に延びてしまったのだ。システムがユーザーのリクエストに素早く応答できないと、ユーザー体験が悪化したり、他の自動処理のボトルネックになったりする可能性がある。
最も運用に支障をきたしたのが、メモリ使用量の問題だった。Headless Chromeは、たとえ画面表示がなくても、ブラウザとして動作するためにかなりの量のメモリ(コンピュータの一時記憶領域)を消費する。その結果、筆者のシステムで最も小さい「ワーカー層」(処理を担当する最小単位のサーバーやプロセス)では、Mermaid図の描画処理中にメモリが不足し、「OOM-killed」(Out Of Memory killed、メモリ不足によりOSから強制終了されること)という事態が頻繁に発生した。これは、割り当てられたメモリ容量を超えて使用しようとしたために、システムがそのプロセスを強制終了させてしまった状態を指す。これにより、処理が途中で中断され、システムの信頼性が著しく低下した。
これらの問題は、単に技術的な不具合にとどまらず、コストとして明確に現れた。余計なリソース消費は、クラウドサービス利用料の増加に直結する。テキストをPNG画像に変換するだけの単純な処理のために、高価なブラウザとその維持にかかるコストを払い続けるのは、合理的な選択とは言えない状況だった。
この状況を改善するため、筆者は根本的な解決策に踏み切った。それは、PuppeteerとHeadless Chromeを用いた汎用的なアプローチを捨て、より「単一目的」に特化したサービスに置き換えることだった。具体的には、Mermaidの構文(テキスト)を受け取ると、そのテキストから生成された図の画像データをBase64形式のPNGまたはSVGとして返す、専用のエンドポイント(APIのようなもの)を構築した。
この新しいサービスは、フローチャート、シーケンス図、クラス図、ガントチャートなど、Mermaidで描ける様々な種類の図に対応している。最も重要な違いは、このサービスを利用するために、ローカルの実行環境にブラウザやその描画スタック(描画に必要なソフトウェア群)をインストールする必要が一切なくなった点だ。必要なのはMermaidのテキストと、その結果を受け取るシンプルなHTTPリクエストだけである。
この変更によって、劇的な改善が見られた。システムの「コールドスタート」時間は、以前のミリ秒単位へと戻り、システム全体の応答性が向上した。余計なブラウザを起動するオーバーヘッド(追加の処理コスト)がなくなったため、メモリ使用量も大幅に削減され、OOM-killedのような問題も解消されたと考えられる。
この経験から得られた重要な教訓は、何か問題に直面したときに、すぐに「汎用的なツール」に飛びつく前に、そのツールの利用が実際にどれだけのコストを伴うのかをきちんと「測定」することの重要性だ。汎用ツールは多くの機能を提供し、様々な問題に対応できるため、一見すると便利で効率的な選択肢に見えるかもしれない。しかし、今回のケースのように、特定の狭い用途に限定して使う場合、その汎用性がかえって重荷となり、不必要なリソース消費やパフォーマンスの低下を招くことがある。
「ただヘッドレスブラウザを使えばいい」というアドバイスは、多くの場面で有効な標準的な解決策として受け入れられている。しかし、今回の記事が示しているのは、それが最も「高価なオプション」として隠れてしまう場合があるという現実だ。本当に必要な機能だけを提供し、無駄を徹底的に省いた「専用のソリューション」が、結果としてより効率的でコストパフォーマンスに優れた選択肢となることがあるのだ。システムを設計・構築する際には、常にその選択肢がもたらす実際の「コスト」(リソース、時間、運用負荷など)を多角的に評価する視点が求められる。