[{"data":1,"prerenderedAt":1792},["ShallowReactive",2],{"blog-ja-gpdf-vs-wkhtmltopdf-vs-chromium":3},{"id":4,"title":5,"author":6,"body":10,"date":1778,"description":1779,"draft":1780,"extension":1781,"howTo":1782,"image":1782,"meta":1783,"navigation":330,"path":1784,"seo":1785,"stem":1786,"tags":1787,"updated":1782,"__hash__":1791},"blogJa/ja/blog/026.gpdf-vs-wkhtmltopdf-vs-chromium.md","gpdf vs wkhtmltopdf vs Chromium — Go の PDF 生成 2026",{"name":7,"url":8,"avatar":9},"Taiki Noda","https://nadai.dev/ja/about","https://nadai.dev/og-default.png",{"type":11,"value":12,"toc":1764},"minimark",[13,18,31,34,37,41,163,172,175,178,181,184,188,191,194,214,217,223,229,232,236,239,245,251,269,290,293,296,300,303,961,979,986,989,992,1074,1086,1089,1092,1095,1098,1101,1104,1207,1218,1221,1224,1227,1237,1240,1244,1247,1252,1333,1344,1349,1399,1413,1418,1636,1643,1646,1650,1655,1658,1663,1666,1671,1674,1679,1690,1695,1700,1704,1707,1722,1735,1738,1760],[14,15,17],"h2",{"id":16},"tldr","TL;DR",[19,20,21,22,26,27,30],"p",{},"wkhtmltopdf は 2023 年 1 月にアーカイブされた。ヘッドレス Chromium (Puppeteer / Playwright / chromedp / go-rod) は動くが、約 170 MB のブラウザバイナリを抱え、同時リクエストごとに 50〜120 MB の RSS を持ち、コールドスタートで 300〜800 ms かかる。",[23,24,25],"strong",{},"gpdf"," は ",[23,28,29],{},"13 µs/ページ","で PDF を生成する。依存ゼロ、ヘッドレスブラウザなし。代償は「任意の HTML+CSS をレンダリングしない」こと、それだけ。",[19,32,33],{},"この記事の判断基準: 「デザイナーが Tailwind ページを投げてきて、pixel-perfect に出してほしい」なら Chromium が正解。「請求書、明細、レポート、証明書、ラベル」なら、ネイティブ系は別カテゴリのコスト構造になる。",[19,35,36],{},"立場の開示: 私たちは gpdf を作っている側。ベンチマークコードは公開しているし、トレードオフのセクションでは何を諦めたかを明記する。ユースケース表も「gpdf がすべて勝つ」とは書いていない。",[14,38,40],{"id":39},"_3-つのアーキテクチャを並べる","3 つのアーキテクチャを並べる",[42,43,44,72],"table",{},[45,46,47],"thead",{},[48,49,50,54,57,60,63,66,69],"tr",{},[51,52,53],"th",{},"アプローチ",[51,55,56],{},"代表的ツール",[51,58,59],{},"レンダリングエンジン",[51,61,62],{},"バイナリサイズ",[51,64,65],{},"RSS / リクエスト",[51,67,68],{},"コールドスタート",[51,70,71],{},"ライセンス",[73,74,75,101,132],"tbody",{},[48,76,77,83,86,89,92,95,98],{},[78,79,80],"td",{},[23,81,82],{},"wkhtmltopdf",[78,84,85],{},"wkhtmltopdf CLI",[78,87,88],{},"QtWebKit fork (〜2014)",[78,90,91],{},"〜40 MB",[78,93,94],{},"〜30〜80 MB",[78,96,97],{},"〜150 ms",[78,99,100],{},"LGPLv3",[48,102,103,108,111,114,119,124,129],{},[78,104,105],{},[23,106,107],{},"Chromium 系",[78,109,110],{},"Puppeteer / Playwright / chromedp / go-rod",[78,112,113],{},"Blink + V8 (本物の Chromium)",[78,115,116],{},[23,117,118],{},"〜170 MB",[78,120,121],{},[23,122,123],{},"〜50〜120 MB",[78,125,126],{},[23,127,128],{},"〜300〜800 ms",[78,130,131],{},"BSD + 再配布制約",[48,133,134,139,142,145,150,155,160],{},[78,135,136],{},[23,137,138],{},"ネイティブ (gpdf)",[78,140,141],{},"gpdf / signintech/gopdf / gofpdf†",[78,143,144],{},"純 Go の PDF Writer",[78,146,147],{},[23,148,149],{},"依存 0",[78,151,152],{},[23,153,154],{},"〜2〜10 MB",[78,156,157],{},[23,158,159],{},"0 ms",[78,161,162],{},"MIT",[19,164,165,166,171],{},"† gofpdf と go-pdf/fpdf はどちらもアーカイブ済み。Go 系ライブラリの全体像は",[167,168,170],"a",{"href":169},"/ja/blog/go-pdf-library-showdown-2026","2026 年版 Go PDF ライブラリ徹底比較","を参照。",[19,173,174],{},"説明の前にこの表から読み取れることが 3 つある。",[19,176,177],{},"1 つ目。wkhtmltopdf の「バイナリサイズが小さい」は誤解を招く。バイト数が少ないのは、WebKit fork が 10 年以上前から上流追従を止めているから。CVE バックログは小さくない。",[19,179,180],{},"2 つ目。Chromium は PDF ライブラリではない。たまたま印刷もできるブラウザだ。その列のコストはすべてブラウザのコスト。",[19,182,183],{},"3 つ目。「0 ms vs 300 ms のコールドスタート」は、1 時間に 1 回 PDF を作る長期常駐サーバーにはどうでもいい話。一方で、サーバーレス (Lambda / Cloud Run / Workers) や「1,000 件の PDF を最速で」というバッチでは死活問題になる。",[14,185,187],{"id":186},"_2026-年の-wkhtmltopdf","2026 年の wkhtmltopdf",[19,189,190],{},"このセクションは読む必要ないかもしれない。既に wkhtmltopdf から離脱しているなら、次のセクションに飛んでください。",[19,192,193],{},"そうでない読者へ。wkhtmltopdf の開発は 2022 年に事実上停止し、リポジトリは 2023 年 1 月にアーカイブされた。メンテナの離脱メモは「代替として Chromium を使え」と明記している。理由はインフラ的なものだった。wkhtmltopdf のレンダラーは QtWebKit という WebKit のフォークで、上流の WebKit から 2014 年あたりで分岐したまま。Qt 本体も 2016 年に QtWebKit を非推奨化し、QtWebEngine (Chromium ラッパー) に移行している。wkhtmltopdf が今も使っているフォークは、12 年前のブラウザエンジンだ。",[19,195,196,197,201,202,205,206,209,210,213],{},"具体的に何が動かないか。モダンな CSS — flex 完全仕様、grid、大量の CSS カスタムプロパティ、",[198,199,200],"code",{},"aspect-ratio","、",[198,203,204],{},":has()","、container queries、flex の ",[198,207,208],{},"gap","、モダンな color 関数 — は誤って描画されるか、まったく描画されない。",[198,211,212],{},"@font-face"," の web フォントは大体動くが、可変軸付き web フォントは動かない。SVG サポートは部分的。WOFF2 サポートは遅れて実装され、バグが多い。",[19,215,216],{},"したがって 2026 年に「wkhtmltopdf を使う」には 2 つの意味があり、どちらも厳しい。",[19,218,219,222],{},[23,220,221],{},"未パッチの WebKit を含む upstream バージョンに乗っている。"," セキュリティチームはいずれ必ずこれを指摘する。「プロジェクトがアーカイブされた」は緩和策ではない。最終リリースは 2020 年。それ以降の CVE 対応は upstream ではなく、Linux ディストロが個別にバックポートしている。",[19,224,225,228],{},[23,226,227],{},"自社フォークを保守している。"," Qt と WebKit のソースを読み、パッチをバックポートし、配布する全プラットフォームでリビルドする担当者が必要。実際に見たケースがある。コストは「他のことをしたい」エンジニア 1 名のフルタイムだった。",[19,230,231],{},"移行先は Chromium (高い忠実度、高いコスト) かネイティブな PDF ジェネレータ (低コスト、HTML/CSS なし) のどちらか。それがこの記事の残りの話題。",[14,233,235],{"id":234},"chromium-系-pdf-生成の実コスト","Chromium 系 PDF 生成の実コスト",[19,237,238],{},"ヘッドレス Chromium は「本当にブラウザが必要なとき」には正しい道具。コストは 4 か所に現れる。",[19,240,241,244],{},[23,242,243],{},"バイナリ。"," Chromium 本体で 〜170 MB。Playwright は既知良好ビルドをバンドル、Puppeteer はインストール時にダウンロード (3 ブラウザ全部入れると 〜280 MB)。コンテナイメージでは最大レイヤーが 1 桁大きくなる。Lambda zip の 250 MB 上限ではこれだけで使い切る。",[19,246,247,250],{},[23,248,249],{},"プロセスあたりメモリ。"," 起動直後の Chromium プロセスで RSS 〜50 MB。実 CSS、web フォント、画像が数枚あるページを読み込むと 80〜120 MB まで上がる。中身次第で変動するが、下限は変わらない。",[19,252,253,256,257,260,261,264,265,268],{},[23,254,255],{},"コールドスタート。"," Chromium を起動して ",[198,258,259],{},"about:blank"," に飛ばすだけで 〜300 ms (温かいマシンで)。",[198,262,263],{},"await page.goto(url)"," + 実ページロード + フォント取得 + ",[198,266,267],{},"await page.pdf()"," を含めると、初回リクエストでは 500 ms〜2 秒が現実的。プールで温めておけば改善するが、サーバーレスでは効かない。スケールアップごとにコールドスタートを払う。",[19,270,271,274,275,278,279,278,282,285,286,289],{},[23,272,273],{},"運用上の表面積。"," ブラウザは「自分で決めたつもりのない決定」の大陸だ。CSP をどうするか、",[198,276,277],{},"networkidle"," で待つか ",[198,280,281],{},"load",[198,283,284],{},"domcontentloaded"," で待つか、JS を無効化するか、Docker で ",[198,287,288],{},"--disable-dev-shm-usage"," をどう設定するか、プロセスがリークしたらどうするか。どれも難しくはない。けど全部、本当はやりたくないデバッグ。",[19,291,292],{},"正直なカウンター: 忠実度が必要なときは必要だ。デザイナーが Figma エクスポートと Tailwind ページを投げてきて、カスタムフォント、グラデーション、SVG アイコンが「そのまま」出てほしい — これは Chromium の仕事。宣言的なドキュメント API で頑張ると、1 週間溶かしてデザイナーから初回レビューで却下される。",[19,294,295],{},"つまり問いは「Chromium を使うか否か」ではない。「自分がレンダリングしているのは本当に web ページか?」だ。",[14,297,299],{"id":298},"gpdf-ブラウザなしのネイティブレンダリング","gpdf: ブラウザなしのネイティブレンダリング",[19,301,302],{},"gpdf は 3 つ目のカテゴリ — 純 Go の PDF Writer。HTML なし、CSS なし、ヘッドレスブラウザなし。Go (または JSON、または Go テンプレート) でドキュメントを記述すると、PDF バイト列が直接出てくる。",[304,305,310],"pre",{"className":306,"code":307,"language":308,"meta":309,"style":309},"language-go shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","package main\n\nimport (\n    \"os\"\n\n    \"github.com/gpdf-dev/gpdf\"\n    \"github.com/gpdf-dev/gpdf/document\"\n    \"github.com/gpdf-dev/gpdf/template\"\n)\n\nfunc main() {\n    doc := gpdf.NewDocument(\n        gpdf.WithPaperSize(document.A4),\n        gpdf.WithMargin(document.Mm(20)),\n    )\n\n    doc.AddPage(func(p *template.PageBuilder) {\n        p.Row(document.Mm(12), func(r *template.RowBuilder) {\n            r.Col(12, func(c *template.ColBuilder) {\n                c.Text(\"請求書\", template.FontSize(24), template.Bold())\n            })\n        })\n        p.Row(document.Mm(8), func(r *template.RowBuilder) {\n            r.Col(6, func(c *template.ColBuilder) {\n                c.Text(\"株式会社 Acme\", template.FontSize(11))\n            })\n            r.Col(6, func(c *template.ColBuilder) {\n                c.Text(\"INV-2026-0517\", template.FontSize(11), template.AlignRight())\n            })\n        })\n        // 以降、明細行と合計\n    })\n\n    out, _ := os.Create(\"invoice.pdf\")\n    defer out.Close()\n    doc.Write(out)\n}\n","go","",[198,311,312,325,332,342,354,359,369,379,389,395,400,416,438,463,491,497,502,535,581,617,666,672,678,718,750,784,789,820,861,866,871,878,884,889,921,938,955],{"__ignoreMap":309},[313,314,317,321],"span",{"class":315,"line":316},"line",1,[313,318,320],{"class":319},"sMK4o","package",[313,322,324],{"class":323},"sBMFI"," main\n",[313,326,328],{"class":315,"line":327},2,[313,329,331],{"emptyLinePlaceholder":330},true,"\n",[313,333,335,339],{"class":315,"line":334},3,[313,336,338],{"class":337},"s7zQu","import",[313,340,341],{"class":319}," (\n",[313,343,345,348,351],{"class":315,"line":344},4,[313,346,347],{"class":319},"    \"",[313,349,350],{"class":323},"os",[313,352,353],{"class":319},"\"\n",[313,355,357],{"class":315,"line":356},5,[313,358,331],{"emptyLinePlaceholder":330},[313,360,362,364,367],{"class":315,"line":361},6,[313,363,347],{"class":319},[313,365,366],{"class":323},"github.com/gpdf-dev/gpdf",[313,368,353],{"class":319},[313,370,372,374,377],{"class":315,"line":371},7,[313,373,347],{"class":319},[313,375,376],{"class":323},"github.com/gpdf-dev/gpdf/document",[313,378,353],{"class":319},[313,380,382,384,387],{"class":315,"line":381},8,[313,383,347],{"class":319},[313,385,386],{"class":323},"github.com/gpdf-dev/gpdf/template",[313,388,353],{"class":319},[313,390,392],{"class":315,"line":391},9,[313,393,394],{"class":319},")\n",[313,396,398],{"class":315,"line":397},10,[313,399,331],{"emptyLinePlaceholder":330},[313,401,403,406,410,413],{"class":315,"line":402},11,[313,404,405],{"class":319},"func",[313,407,409],{"class":408},"s2Zo4"," main",[313,411,412],{"class":319},"()",[313,414,415],{"class":319}," {\n",[313,417,419,423,426,429,432,435],{"class":315,"line":418},12,[313,420,422],{"class":421},"sTEyZ","    doc ",[313,424,425],{"class":319},":=",[313,427,428],{"class":421}," gpdf",[313,430,431],{"class":319},".",[313,433,434],{"class":408},"NewDocument",[313,436,437],{"class":319},"(\n",[313,439,441,444,446,449,452,455,457,460],{"class":315,"line":440},13,[313,442,443],{"class":421},"        gpdf",[313,445,431],{"class":319},[313,447,448],{"class":408},"WithPaperSize",[313,450,451],{"class":319},"(",[313,453,454],{"class":421},"document",[313,456,431],{"class":319},[313,458,459],{"class":421},"A4",[313,461,462],{"class":319},"),\n",[313,464,466,468,470,473,475,477,479,482,484,488],{"class":315,"line":465},14,[313,467,443],{"class":421},[313,469,431],{"class":319},[313,471,472],{"class":408},"WithMargin",[313,474,451],{"class":319},[313,476,454],{"class":421},[313,478,431],{"class":319},[313,480,481],{"class":408},"Mm",[313,483,451],{"class":319},[313,485,487],{"class":486},"sbssI","20",[313,489,490],{"class":319},")),\n",[313,492,494],{"class":315,"line":493},15,[313,495,496],{"class":319},"    )\n",[313,498,500],{"class":315,"line":499},16,[313,501,331],{"emptyLinePlaceholder":330},[313,503,505,508,510,513,516,519,522,525,527,530,533],{"class":315,"line":504},17,[313,506,507],{"class":421},"    doc",[313,509,431],{"class":319},[313,511,512],{"class":408},"AddPage",[313,514,515],{"class":319},"(func(",[313,517,19],{"class":518},"sHdIc",[313,520,521],{"class":319}," *",[313,523,524],{"class":323},"template",[313,526,431],{"class":319},[313,528,529],{"class":323},"PageBuilder",[313,531,532],{"class":319},")",[313,534,415],{"class":319},[313,536,538,541,543,546,548,550,552,554,556,559,562,565,568,570,572,574,577,579],{"class":315,"line":537},18,[313,539,540],{"class":421},"        p",[313,542,431],{"class":319},[313,544,545],{"class":408},"Row",[313,547,451],{"class":319},[313,549,454],{"class":421},[313,551,431],{"class":319},[313,553,481],{"class":408},[313,555,451],{"class":319},[313,557,558],{"class":486},"12",[313,560,561],{"class":319},"),",[313,563,564],{"class":319}," func(",[313,566,567],{"class":518},"r",[313,569,521],{"class":319},[313,571,524],{"class":323},[313,573,431],{"class":319},[313,575,576],{"class":323},"RowBuilder",[313,578,532],{"class":319},[313,580,415],{"class":319},[313,582,584,587,589,592,594,596,599,601,604,606,608,610,613,615],{"class":315,"line":583},19,[313,585,586],{"class":421},"            r",[313,588,431],{"class":319},[313,590,591],{"class":408},"Col",[313,593,451],{"class":319},[313,595,558],{"class":486},[313,597,598],{"class":319},",",[313,600,564],{"class":319},[313,602,603],{"class":518},"c",[313,605,521],{"class":319},[313,607,524],{"class":323},[313,609,431],{"class":319},[313,611,612],{"class":323},"ColBuilder",[313,614,532],{"class":319},[313,616,415],{"class":319},[313,618,620,623,625,628,630,633,637,639,641,644,646,649,651,654,656,658,660,663],{"class":315,"line":619},20,[313,621,622],{"class":421},"                c",[313,624,431],{"class":319},[313,626,627],{"class":408},"Text",[313,629,451],{"class":319},[313,631,632],{"class":319},"\"",[313,634,636],{"class":635},"sfazB","請求書",[313,638,632],{"class":319},[313,640,598],{"class":319},[313,642,643],{"class":421}," template",[313,645,431],{"class":319},[313,647,648],{"class":408},"FontSize",[313,650,451],{"class":319},[313,652,653],{"class":486},"24",[313,655,561],{"class":319},[313,657,643],{"class":421},[313,659,431],{"class":319},[313,661,662],{"class":408},"Bold",[313,664,665],{"class":319},"())\n",[313,667,669],{"class":315,"line":668},21,[313,670,671],{"class":319},"            })\n",[313,673,675],{"class":315,"line":674},22,[313,676,677],{"class":319},"        })\n",[313,679,681,683,685,687,689,691,693,695,697,700,702,704,706,708,710,712,714,716],{"class":315,"line":680},23,[313,682,540],{"class":421},[313,684,431],{"class":319},[313,686,545],{"class":408},[313,688,451],{"class":319},[313,690,454],{"class":421},[313,692,431],{"class":319},[313,694,481],{"class":408},[313,696,451],{"class":319},[313,698,699],{"class":486},"8",[313,701,561],{"class":319},[313,703,564],{"class":319},[313,705,567],{"class":518},[313,707,521],{"class":319},[313,709,524],{"class":323},[313,711,431],{"class":319},[313,713,576],{"class":323},[313,715,532],{"class":319},[313,717,415],{"class":319},[313,719,721,723,725,727,729,732,734,736,738,740,742,744,746,748],{"class":315,"line":720},24,[313,722,586],{"class":421},[313,724,431],{"class":319},[313,726,591],{"class":408},[313,728,451],{"class":319},[313,730,731],{"class":486},"6",[313,733,598],{"class":319},[313,735,564],{"class":319},[313,737,603],{"class":518},[313,739,521],{"class":319},[313,741,524],{"class":323},[313,743,431],{"class":319},[313,745,612],{"class":323},[313,747,532],{"class":319},[313,749,415],{"class":319},[313,751,753,755,757,759,761,763,766,768,770,772,774,776,778,781],{"class":315,"line":752},25,[313,754,622],{"class":421},[313,756,431],{"class":319},[313,758,627],{"class":408},[313,760,451],{"class":319},[313,762,632],{"class":319},[313,764,765],{"class":635},"株式会社 Acme",[313,767,632],{"class":319},[313,769,598],{"class":319},[313,771,643],{"class":421},[313,773,431],{"class":319},[313,775,648],{"class":408},[313,777,451],{"class":319},[313,779,780],{"class":486},"11",[313,782,783],{"class":319},"))\n",[313,785,787],{"class":315,"line":786},26,[313,788,671],{"class":319},[313,790,792,794,796,798,800,802,804,806,808,810,812,814,816,818],{"class":315,"line":791},27,[313,793,586],{"class":421},[313,795,431],{"class":319},[313,797,591],{"class":408},[313,799,451],{"class":319},[313,801,731],{"class":486},[313,803,598],{"class":319},[313,805,564],{"class":319},[313,807,603],{"class":518},[313,809,521],{"class":319},[313,811,524],{"class":323},[313,813,431],{"class":319},[313,815,612],{"class":323},[313,817,532],{"class":319},[313,819,415],{"class":319},[313,821,823,825,827,829,831,833,836,838,840,842,844,846,848,850,852,854,856,859],{"class":315,"line":822},28,[313,824,622],{"class":421},[313,826,431],{"class":319},[313,828,627],{"class":408},[313,830,451],{"class":319},[313,832,632],{"class":319},[313,834,835],{"class":635},"INV-2026-0517",[313,837,632],{"class":319},[313,839,598],{"class":319},[313,841,643],{"class":421},[313,843,431],{"class":319},[313,845,648],{"class":408},[313,847,451],{"class":319},[313,849,780],{"class":486},[313,851,561],{"class":319},[313,853,643],{"class":421},[313,855,431],{"class":319},[313,857,858],{"class":408},"AlignRight",[313,860,665],{"class":319},[313,862,864],{"class":315,"line":863},29,[313,865,671],{"class":319},[313,867,869],{"class":315,"line":868},30,[313,870,677],{"class":319},[313,872,874],{"class":315,"line":873},31,[313,875,877],{"class":876},"sHwdD","        // 以降、明細行と合計\n",[313,879,881],{"class":315,"line":880},32,[313,882,883],{"class":319},"    })\n",[313,885,887],{"class":315,"line":886},33,[313,888,331],{"emptyLinePlaceholder":330},[313,890,892,895,897,900,902,905,907,910,912,914,917,919],{"class":315,"line":891},34,[313,893,894],{"class":421},"    out",[313,896,598],{"class":319},[313,898,899],{"class":421}," _ ",[313,901,425],{"class":319},[313,903,904],{"class":421}," os",[313,906,431],{"class":319},[313,908,909],{"class":408},"Create",[313,911,451],{"class":319},[313,913,632],{"class":319},[313,915,916],{"class":635},"invoice.pdf",[313,918,632],{"class":319},[313,920,394],{"class":319},[313,922,924,927,930,932,935],{"class":315,"line":923},35,[313,925,926],{"class":337},"    defer",[313,928,929],{"class":421}," out",[313,931,431],{"class":319},[313,933,934],{"class":408},"Close",[313,936,937],{"class":319},"()\n",[313,939,941,943,945,948,950,953],{"class":315,"line":940},36,[313,942,507],{"class":421},[313,944,431],{"class":319},[313,946,947],{"class":408},"Write",[313,949,451],{"class":319},[313,951,952],{"class":421},"out",[313,954,394],{"class":319},[313,956,958],{"class":315,"line":957},37,[313,959,960],{"class":319},"}\n",[19,962,963,964,967,968,967,971,973,974,978],{},"スタック全部。コンテナに Chromium バイナリなし。",[198,965,966],{},"npm install puppeteer"," なし。",[198,969,970],{},"page.goto",[198,972,947],{}," 呼び出しが PDF をライターに直接書き込む。1 ページの請求書なら",[167,975,977],{"href":976},"/ja/blog/why-gpdf-is-faster","CPU 時間 〜13 µs","。",[19,980,981,982,985],{},"そのために諦めたもの。レンダラーは ",[198,983,984],{},"display: flex"," が何を意味するか知らない。知っているのは行、列 (12 カラムグリッド)、テキストラン、画像、テーブル、バーコード。スケールして生成される文書 — 請求書、明細、レシート、レポート、証明書、ラベル、納品書 — のほとんどはこの語彙で足りる。残り (マーケティング PDF、デザイナー主導のブローシャ、もともと Web ページだったもの) では足りない。",[14,987,988],{"id":988},"パフォーマンス比較",[19,990,991],{},"3 カテゴリを比較するのは方法論的に厄介。それぞれ少しずつ違う問題を解いているから。承知の上でやる。公平な比較は「同じ最終成果物、3 つの実装」: ヘッダ + 4×10 の明細表 + 合計の 1 ページ請求書。",[42,993,994,1012],{},[45,995,996],{},[48,997,998,1001,1003,1006],{},[51,999,1000],{},"ワークロード",[51,1002,25],{},[51,1004,1005],{},"wkhtmltopdf (CLI)",[51,1007,1008,1009,532],{},"Chromium (Playwright ",[198,1010,1011],{},"page.pdf()",[73,1013,1014,1030,1046,1060],{},[48,1015,1016,1019,1024,1027],{},[78,1017,1018],{},"1 ページ請求書",[78,1020,1021],{},[23,1022,1023],{},"13 µs",[78,1025,1026],{},"〜140 ms",[78,1028,1029],{},"〜280 ms (warm) / 〜1.2 s (cold)",[48,1031,1032,1035,1040,1043],{},[78,1033,1034],{},"100 ページのページ送りレポート",[78,1036,1037],{},[23,1038,1039],{},"683 µs",[78,1041,1042],{},"〜3.4 s",[78,1044,1045],{},"〜6.1 s (warm)",[48,1047,1048,1051,1054,1057],{},[78,1049,1050],{},"1 リクエスト中のピーク RSS",[78,1052,1053],{},"〜5 MB",[78,1055,1056],{},"〜70 MB",[78,1058,1059],{},"〜120 MB",[48,1061,1062,1065,1068,1071],{},[78,1063,1064],{},"コンテナイメージ増加分",[78,1066,1067],{},"0",[78,1069,1070],{},"+40 MB",[78,1072,1073],{},"+170 MB",[19,1075,1076,1077,1085],{},"Apple M1, Go 1.25 (gpdf 側)、wkhtmltopdf 0.12.6 バイナリ、Playwright 1.42 + 同梱 Chromium。gpdf のベンチマークコードは ",[167,1078,1082],{"href":1079,"rel":1080},"https://github.com/gpdf-dev/gpdf/tree/main/_benchmark",[1081],"nofollow",[198,1083,1084],{},"_benchmark/"," — clone して各自のハードウェアで再現可能。",[19,1087,1088],{},"注目すべき数字が 2 つある。",[19,1090,1091],{},"1 ページ請求書の差は約 22,000 倍。大半はレンダリング自体ではなく、リクエストごとにブラウザプロセスを起動・終了させるコスト。Playwright のプールを温めておけば 〜4 倍に縮むが、それでも 4 桁の差。",[19,1093,1094],{},"100 ページレポートの差は約 9,000 倍。ここではレンダリングコストが支配的になり、「ブラウザを起動するコスト」は償却される。償却後も Chromium は要素ごとのレイアウトコストを払う。ネイティブな PDF Writer はそこをスキップする。",[19,1096,1097],{},"本番環境で効いてくるのはピーク RSS の数字だ。Chromium プロセス 1 つが 6 秒間 120 MB を握る = 4 GB のコンテナで同時 30 レポートくらいが上限。同じコンテナで gpdf を走らせると数千同時。",[14,1099,1100],{"id":1100},"どのアプローチがどこで勝つか",[19,1102,1103],{},"「gpdf が全部勝つ」表ではない。そのつもりもない。実際のアーキテクチャ判断はこういう形になる。",[42,1105,1106,1119],{},[45,1107,1108],{},[48,1109,1110,1113,1116],{},[51,1111,1112],{},"ユースケース",[51,1114,1115],{},"正しい道具",[51,1117,1118],{},"理由",[73,1120,1121,1132,1142,1153,1163,1174,1185,1196],{},[48,1122,1123,1126,1129],{},[78,1124,1125],{},"Figma + Tailwind のマーケティング PDF",[78,1127,1128],{},"Chromium (Playwright)",[78,1130,1131],{},"コストよりデザイナー意図への忠実度。",[48,1133,1134,1137,1139],{},[78,1135,1136],{},"月末に 50,000 通の明細書",[78,1138,25],{},[78,1140,1141],{},"1 通あたりのコスト × 量 = 実費。CSS は不要。",[48,1143,1144,1147,1150],{},[78,1145,1146],{},"単発「デザイナーがブローシャをくれた」",[78,1148,1149],{},"Chromium (or InDesign)",[78,1151,1152],{},"量は少なく CSS は多い。1 度きりなら正しい道具を使う。",[48,1154,1155,1158,1160],{},[78,1156,1157],{},"SaaS 課金システムの請求書",[78,1159,25],{},[78,1161,1162],{},"量が売上に比例。コールドスタートが効く。レイアウトが構造化されている。",[48,1164,1165,1168,1171],{},[78,1166,1167],{},"税務書類 / 規制対応申請 (PDF/A)",[78,1169,1170],{},"gpdf (or unidoc)",[78,1172,1173],{},"PDF/A 適合、署名、監査証跡。ブラウザは扱わない。",[48,1175,1176,1179,1182],{},[78,1177,1178],{},"BI ダッシュボードのスクショ入りレポート",[78,1180,1181],{},"Chromium",[78,1183,1184],{},"チャートが主役。PDF はエクスポート手段。",[48,1186,1187,1190,1193],{},[78,1188,1189],{},"Markdown を印刷 / ドキュメント PDF",[78,1191,1192],{},"gpdf or Chromium",[78,1194,1195],{},"どちらでも可。コスト vs 忠実度の取引。",[48,1197,1198,1201,1204],{},[78,1199,1200],{},"レガシー wkhtmltopdf からの移行",[78,1202,1203],{},"HTML が単純なら gpdf / 実 CSS なら Chromium",[78,1205,1206],{},"テンプレートを先に監査。",[19,1208,1209,1210,1213,1214,1217],{},"パターン: ",[23,1211,1212],{},"量 × リクエストあたりコスト"," vs ",[23,1215,1216],{},"デザイン忠実度","。前者が支配的ならネイティブが勝つ。後者が支配的なら Chromium が勝つ。wkhtmltopdf はこの 2026 年のマトリックスのどこにも座る場所がない。",[14,1219,1220],{"id":1220},"ごまかさないトレードオフ",[19,1222,1223],{},"ずっと匂わせてきたが、節を立てて書く。",[19,1225,1226],{},"gpdf は HTML も CSS もレンダリングしない。既存システムが「HTML メールテンプレートをそのまま PDF にも印刷している」なら、gpdf 移行はそのテンプレートをビルダー API に書き換えること。テンプレ 1 個なら午後一仕事。デザイナーが保守する 30 個のマーケティングテンプレートのライブラリなら、それはプロジェクト。",[19,1228,1229,1231,1232,1236],{},[198,1230,212],{}," の web フォントも扱わない。TTF/OTF ファイルをドキュメント構築時に渡す。CJK フォントは first-class — ",[167,1233,1235],{"href":1234},"/ja/blog/japanese-pdf-in-go","CGO なしで CJK をレンダリングする話","を別記事で書いた — が、フォントファイルを配送するのは開発者の責任。",[19,1238,1239],{},"譲らないもの: 速度、メモリ、デプロイ容易性、依存フットプリント。トレードオフは機能表面積で払っている。本番コストでは払っていない。高ボリュームな構造化ドキュメントを作っているチームの多くは、必要ないブラウザに金を払い続けている、というのが私たちの見立て。そういうチームにはネイティブの道が正解。すべてのチームに gpdf が正解とは思っていない。",[14,1241,1243],{"id":1242},"コード-同じ請求書を-3-通り","コード: 同じ請求書を 3 通り",[19,1245,1246],{},"API の手触りの違いを実感したければ、3 実装を並べる。",[19,1248,1249],{},[23,1250,1251],{},"Chromium (Playwright, Node):",[304,1253,1257],{"className":1254,"code":1255,"language":1256,"meta":309,"style":309},"language-js shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","const { chromium } = require('playwright');\nconst fs = require('fs');\n\n(async () => {\n  const browser = await chromium.launch();\n  const page = await browser.newPage();\n  const html = fs.readFileSync('invoice.html', 'utf8');\n  await page.setContent(html, { waitUntil: 'networkidle' });\n  await page.pdf({\n    path: 'invoice.pdf',\n    format: 'A4',\n    margin: { top: '20mm', bottom: '20mm', left: '20mm', right: '20mm' },\n  });\n  await browser.close();\n})();\n","js",[198,1258,1259,1264,1269,1273,1278,1283,1288,1293,1298,1303,1308,1313,1318,1323,1328],{"__ignoreMap":309},[313,1260,1261],{"class":315,"line":316},[313,1262,1263],{},"const { chromium } = require('playwright');\n",[313,1265,1266],{"class":315,"line":327},[313,1267,1268],{},"const fs = require('fs');\n",[313,1270,1271],{"class":315,"line":334},[313,1272,331],{"emptyLinePlaceholder":330},[313,1274,1275],{"class":315,"line":344},[313,1276,1277],{},"(async () => {\n",[313,1279,1280],{"class":315,"line":356},[313,1281,1282],{},"  const browser = await chromium.launch();\n",[313,1284,1285],{"class":315,"line":361},[313,1286,1287],{},"  const page = await browser.newPage();\n",[313,1289,1290],{"class":315,"line":371},[313,1291,1292],{},"  const html = fs.readFileSync('invoice.html', 'utf8');\n",[313,1294,1295],{"class":315,"line":381},[313,1296,1297],{},"  await page.setContent(html, { waitUntil: 'networkidle' });\n",[313,1299,1300],{"class":315,"line":391},[313,1301,1302],{},"  await page.pdf({\n",[313,1304,1305],{"class":315,"line":397},[313,1306,1307],{},"    path: 'invoice.pdf',\n",[313,1309,1310],{"class":315,"line":402},[313,1311,1312],{},"    format: 'A4',\n",[313,1314,1315],{"class":315,"line":418},[313,1316,1317],{},"    margin: { top: '20mm', bottom: '20mm', left: '20mm', right: '20mm' },\n",[313,1319,1320],{"class":315,"line":440},[313,1321,1322],{},"  });\n",[313,1324,1325],{"class":315,"line":465},[313,1326,1327],{},"  await browser.close();\n",[313,1329,1330],{"class":315,"line":493},[313,1331,1332],{},"})();\n",[19,1334,1335,1336,1339,1340,1343],{},"加えて自分で保守する ",[198,1337,1338],{},"invoice.html","、同梱 Chromium バイナリ (〜170 MB)、フォントの渡し方 (web フォント? base64 埋め込み? ",[198,1341,1342],{},"--font-render-hinting","?)。Tailwind テンプレでは綺麗に動く。保守対象は HTML 側。",[19,1345,1346],{},[23,1347,1348],{},"wkhtmltopdf (shell):",[304,1350,1354],{"className":1351,"code":1352,"language":1353,"meta":309,"style":309},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","wkhtmltopdf --enable-local-file-access \\\n  --margin-top 20mm --margin-bottom 20mm --margin-left 20mm --margin-right 20mm \\\n  invoice.html invoice.pdf\n","bash",[198,1355,1356,1366,1391],{"__ignoreMap":309},[313,1357,1358,1360,1363],{"class":315,"line":316},[313,1359,82],{"class":323},[313,1361,1362],{"class":635}," --enable-local-file-access",[313,1364,1365],{"class":421}," \\\n",[313,1367,1368,1371,1374,1377,1379,1382,1384,1387,1389],{"class":315,"line":327},[313,1369,1370],{"class":635},"  --margin-top",[313,1372,1373],{"class":635}," 20mm",[313,1375,1376],{"class":635}," --margin-bottom",[313,1378,1373],{"class":635},[313,1380,1381],{"class":635}," --margin-left",[313,1383,1373],{"class":635},[313,1385,1386],{"class":635}," --margin-right",[313,1388,1373],{"class":635},[313,1390,1365],{"class":421},[313,1392,1393,1396],{"class":315,"line":334},[313,1394,1395],{"class":635},"  invoice.html",[313,1397,1398],{"class":635}," invoice.pdf\n",[19,1400,1401,1402,1405,1406,1409,1410,1412],{},"加えて wkhtmltopdf バイナリ、QtWebKit-2014 が理解できる CSS だけを使った HTML テンプレ (実用上: ",[198,1403,1404],{},"grid"," 不可、",[198,1407,1408],{},"flex"," は要注意、",[198,1411,204],{}," 不可、カスタムプロパティは部分動作)。さらに監査がバイナリを引っかけたときのセキュリティ会話。",[19,1414,1415],{},[23,1416,1417],{},"gpdf (Go):",[304,1419,1421],{"className":306,"code":1420,"language":308,"meta":309,"style":309},"doc := gpdf.NewDocument(\n    gpdf.WithPaperSize(document.A4),\n    gpdf.WithMargin(document.Mm(20)),\n)\ndoc.AddPage(func(p *template.PageBuilder) {\n    invoiceHeader(p, \"INV-2026-0517\", \"株式会社 Acme\")\n    invoiceTable(p, lineItems)\n    invoiceTotals(p, subtotal, tax, total)\n})\nout, _ := os.Create(\"invoice.pdf\")\ndefer out.Close()\ndoc.Write(out)\n",[198,1422,1423,1438,1457,1479,1483,1508,1536,1552,1578,1583,1609,1622],{"__ignoreMap":309},[313,1424,1425,1428,1430,1432,1434,1436],{"class":315,"line":316},[313,1426,1427],{"class":421},"doc ",[313,1429,425],{"class":319},[313,1431,428],{"class":421},[313,1433,431],{"class":319},[313,1435,434],{"class":408},[313,1437,437],{"class":319},[313,1439,1440,1443,1445,1447,1449,1451,1453,1455],{"class":315,"line":327},[313,1441,1442],{"class":421},"    gpdf",[313,1444,431],{"class":319},[313,1446,448],{"class":408},[313,1448,451],{"class":319},[313,1450,454],{"class":421},[313,1452,431],{"class":319},[313,1454,459],{"class":421},[313,1456,462],{"class":319},[313,1458,1459,1461,1463,1465,1467,1469,1471,1473,1475,1477],{"class":315,"line":334},[313,1460,1442],{"class":421},[313,1462,431],{"class":319},[313,1464,472],{"class":408},[313,1466,451],{"class":319},[313,1468,454],{"class":421},[313,1470,431],{"class":319},[313,1472,481],{"class":408},[313,1474,451],{"class":319},[313,1476,487],{"class":486},[313,1478,490],{"class":319},[313,1480,1481],{"class":315,"line":344},[313,1482,394],{"class":319},[313,1484,1485,1488,1490,1492,1494,1496,1498,1500,1502,1504,1506],{"class":315,"line":356},[313,1486,1487],{"class":421},"doc",[313,1489,431],{"class":319},[313,1491,512],{"class":408},[313,1493,515],{"class":319},[313,1495,19],{"class":518},[313,1497,521],{"class":319},[313,1499,524],{"class":323},[313,1501,431],{"class":319},[313,1503,529],{"class":323},[313,1505,532],{"class":319},[313,1507,415],{"class":319},[313,1509,1510,1513,1515,1517,1519,1522,1524,1526,1528,1530,1532,1534],{"class":315,"line":361},[313,1511,1512],{"class":408},"    invoiceHeader",[313,1514,451],{"class":319},[313,1516,19],{"class":421},[313,1518,598],{"class":319},[313,1520,1521],{"class":319}," \"",[313,1523,835],{"class":635},[313,1525,632],{"class":319},[313,1527,598],{"class":319},[313,1529,1521],{"class":319},[313,1531,765],{"class":635},[313,1533,632],{"class":319},[313,1535,394],{"class":319},[313,1537,1538,1541,1543,1545,1547,1550],{"class":315,"line":371},[313,1539,1540],{"class":408},"    invoiceTable",[313,1542,451],{"class":319},[313,1544,19],{"class":421},[313,1546,598],{"class":319},[313,1548,1549],{"class":421}," lineItems",[313,1551,394],{"class":319},[313,1553,1554,1557,1559,1561,1563,1566,1568,1571,1573,1576],{"class":315,"line":381},[313,1555,1556],{"class":408},"    invoiceTotals",[313,1558,451],{"class":319},[313,1560,19],{"class":421},[313,1562,598],{"class":319},[313,1564,1565],{"class":421}," subtotal",[313,1567,598],{"class":319},[313,1569,1570],{"class":421}," tax",[313,1572,598],{"class":319},[313,1574,1575],{"class":421}," total",[313,1577,394],{"class":319},[313,1579,1580],{"class":315,"line":391},[313,1581,1582],{"class":319},"})\n",[313,1584,1585,1587,1589,1591,1593,1595,1597,1599,1601,1603,1605,1607],{"class":315,"line":397},[313,1586,952],{"class":421},[313,1588,598],{"class":319},[313,1590,899],{"class":421},[313,1592,425],{"class":319},[313,1594,904],{"class":421},[313,1596,431],{"class":319},[313,1598,909],{"class":408},[313,1600,451],{"class":319},[313,1602,632],{"class":319},[313,1604,916],{"class":635},[313,1606,632],{"class":319},[313,1608,394],{"class":319},[313,1610,1611,1614,1616,1618,1620],{"class":315,"line":402},[313,1612,1613],{"class":337},"defer",[313,1615,929],{"class":421},[313,1617,431],{"class":319},[313,1619,934],{"class":408},[313,1621,937],{"class":319},[313,1623,1624,1626,1628,1630,1632,1634],{"class":315,"line":418},[313,1625,1487],{"class":421},[313,1627,431],{"class":319},[313,1629,947],{"class":408},[313,1631,451],{"class":319},[313,1633,952],{"class":421},[313,1635,394],{"class":319},[19,1637,1638,1639,1642],{},"加えてビルダー API に対して自分で書いた 3 つの Go 関数。テンプレートファイルなし、バイナリ依存なし、別レンダー手順なし。単一の Go バイナリとして ",[198,1640,1641],{},"FROM scratch"," コンテナにデプロイできる。",[19,1644,1645],{},"読み方は「どれが一番短いか」ではない。「どの表面積を保守したいか」だ。Chromium の表面積は HTML + CSS + ブラウザ。wkhtmltopdf の表面積は HTML + CSS + 10 年前のブラウザ。gpdf の表面積は Go。",[14,1647,1649],{"id":1648},"faq","FAQ",[19,1651,1652],{},[23,1653,1654],{},"2026 年に wkhtmltopdf は本当に使えないのか?",[19,1656,1657],{},"「使えない」は強すぎる。「推奨しない」が正確。動くし、単純なテンプレなら正しい PDF を吐く。新規プロジェクトで採用しない理由: プロジェクトはアーカイブ済み、WebKit fork は 2014 年のコードベース、セキュリティ監査で必ず引っかかる、公式の代替案内が「Chromium を使え」。本番に既に入っているなら移行する時間はある。ただし新規の依存先として今から増やす時間はない。",[19,1659,1660],{},[23,1661,1662],{},"Chromium のコストを受け入れればいいのでは?",[19,1664,1665],{},"多くのワークロードではそれで OK。上の判断マトリックスでも、マーケティング PDF とデザイナー主導の文書は Chromium 列に置いてある。この記事を書いた理由は、Chromium が「請求書、明細、レポート」 — ブラウザの忠実度が要らないワークロード — にも使われていて、そのコストが AWS の請求書に現れていることが多いから。",[19,1667,1668],{},[23,1669,1670],{},"Chromium を使わない HTML→PDF (html2pdf や jsPDF) は?",[19,1672,1673],{},"ブラウザ側 JS で HTML を canvas に描いてから PDF にするライブラリ群。忠実度は Chromium より大幅に低い (モダン CSS の多くが動かない)。性能もネイティブより悪い (2 回描画する: HTML → canvas → PDF)。クライアント側 PDF 生成という固有のニッチはあるが、この比較表には載らない。",[19,1675,1676],{},[23,1677,1678],{},"gpdf は PDF/A や電子署名に対応している?",[19,1680,1681,1682,1685,1686,1689],{},"対応している。PDF/A-1b / PDF/A-2b 適合は ",[198,1683,1684],{},"gpdf.WithPDFA(...)","、PKCS#7 署名 (RFC 3161 タイムスタンプ含む) は ",[198,1687,1688],{},"gpdf.SignDocument(...)","。両方とも MIT コアライブラリに同梱 — 別売りや商用ライセンスは不要。",[19,1691,1692],{},[23,1693,1694],{},"他の Go の PDF ライブラリ (ブラウザ系ではなく) と比べて?",[19,1696,1697,1698,978],{},"それは別の問い。短く: gofpdf と go-pdf/fpdf はアーカイブ済み、signintech/gopdf は保守されているが低レベル (レイアウトグリッドなし)、Maroto v2 は保守されているがアーカイブ済み gofpdf の上、unidoc は商用。完全な比較は",[167,1699,170],{"href":169},[14,1701,1703],{"id":1702},"gpdf-を使ってみる","gpdf を使ってみる",[19,1705,1706],{},"gpdf は Go の PDF 生成ライブラリ。MIT、ゼロ依存、CJK 対応。",[304,1708,1710],{"className":1351,"code":1709,"language":1353,"meta":309,"style":309},"go get github.com/gpdf-dev/gpdf\n",[198,1711,1712],{"__ignoreMap":309},[313,1713,1714,1716,1719],{"class":315,"line":316},[313,1715,308],{"class":323},[313,1717,1718],{"class":635}," get",[313,1720,1721],{"class":635}," github.com/gpdf-dev/gpdf\n",[19,1723,1724,1729,1730],{},[167,1725,1728],{"href":1726,"rel":1727},"https://github.com/gpdf-dev/gpdf",[1081],"⭐ GitHub で Star する"," · ",[167,1731,1734],{"href":1732,"rel":1733},"https://gpdf.dev/ja/docs/quickstart",[1081],"ドキュメントを読む",[14,1736,1737],{"id":1737},"関連記事",[1739,1740,1741,1748,1753],"ul",{},[1742,1743,1744,1747],"li",{},[167,1745,1746],{"href":976},"なぜ gpdf は他の Go PDF ライブラリの 10〜30 倍速いのか"," — この記事の数字の裏側にあるアーキテクチャ",[1742,1749,1750,1752],{},[167,1751,170],{"href":169}," — Go ネイティブライブラリ同士の比較",[1742,1754,1755,1759],{},[167,1756,1758],{"href":1757},"/ja/blog/gofpdf-migration","gofpdf から gpdf への移行ガイド"," — アーカイブ済みライブラリから抜けるなら",[1761,1762,1763],"style",{},"html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":309,"searchDepth":327,"depth":327,"links":1765},[1766,1767,1768,1769,1770,1771,1772,1773,1774,1775,1776,1777],{"id":16,"depth":327,"text":17},{"id":39,"depth":327,"text":40},{"id":186,"depth":327,"text":187},{"id":234,"depth":327,"text":235},{"id":298,"depth":327,"text":299},{"id":988,"depth":327,"text":988},{"id":1100,"depth":327,"text":1100},{"id":1220,"depth":327,"text":1220},{"id":1242,"depth":327,"text":1243},{"id":1648,"depth":327,"text":1649},{"id":1702,"depth":327,"text":1703},{"id":1737,"depth":327,"text":1737},"2026-05-18","wkhtmltopdf はアーカイブ済み。Chromium は 1 リクエスト 170 MB。gpdf は 13 µs/ページ、ブラウザ不要。2026 年の正直な比較。",false,"md",null,{},"/ja/blog/gpdf-vs-wkhtmltopdf-vs-chromium",{"title":5,"description":1779},"ja/blog/026.gpdf-vs-wkhtmltopdf-vs-chromium",[1788,1789,1790],"comparison","benchmark","migration","T_FOWFRbHJZOF-JoyBR4njjRB_fxUXq3WynPJ3J4658",1779199019506]