parse5 vs cheerio vs domino vs jsdom
Node.js におけるサーバーサイド HTML パーシングと DOM 操作ライブラリの比較
parse5cheeriodominojsdom類似パッケージ:

Node.js におけるサーバーサイド HTML パーシングと DOM 操作ライブラリの比較

cheeriodominojsdomparse5 は、Node.js 環境で HTML を処理するための代表的なライブラリです。これらはサーバーサイドでのスクレイピング、テスト、HTML 変換などの用途に使われますが、内部の実装アプローチと提供される機能には大きな違いがあります。jsdom はブラウザの DOM 仕様をほぼ完全に実装しており、ブラウザ依存のコードをテストする際に最適です。cheerio は jQuery に似た API を提供し、HTML の抽出や操作を軽量かつ高速に行えます。domino は DOM 実装に特化しており、ウィンドウオブジェクトを持たない軽量な環境を提供します。parse5 は HTML パーサーそのものであり、他のライブラリの基盤としても使われる低レベルなツールです。

npmのダウンロードトレンド

3 年

GitHub Starsランキング

統計詳細

パッケージ
ダウンロード数
Stars
サイズ
Issues
公開日時
ライセンス
parse546,161,3983,884337 kB358ヶ月前MIT
cheerio8,564,93830,2271.01 MB392ヶ月前MIT
domino0788-376年前BSD-2-Clause
jsdom021,5266.93 MB4154日前MIT

Node.js における HTML 処理ライブラリ:cheerio、domino、jsdom、parse5 の比較

Node.js で HTML を扱う場合、ブラウザと同じように DOM を操作できるか、それとも軽量なパーシングだけで十分かによって選ぶべきツールが変わります。cheeriodominojsdomparse5 はそれぞれ異なる設計思想を持っており、用途によって明確な使い分けが必要です。ここでは、実開発で直面する具体的なシナリオに基づいて、これら 4 つのライブラリを技術的に比較します。

🏗️ 基本アーキテクチャ:DOM 実装 vs パーサー

jsdom は、W3C の DOM 仕様を可能な限り忠実に実装しようとする「フル機能」のライブラリです。

  • ブラウザの windowdocument オブジェクトをエミュレートします。
  • JavaScript の実行機能も含まれており、ページ内のスクリプトを動かすことも可能です。
// jsdom: 完全な DOM 環境
const { JSDOM } = require("jsdom");
const dom = new JSDOM(`<!DOCTYPE html><p>Hello</p>`);
console.log(dom.window.document.querySelector("p").textContent); // "Hello"

cheerio は、DOM 仕様の実装ではなく、サーバーサイドでの HTML 操作に特化したライブラリです。

  • jQuery と非常に似た API を提供します。
  • 内部で parse5 をパーサーとして使用していますが、完全な DOM ツリーは構築しません。
// cheerio: jQuery ライクな API
const cheerio = require("cheerio");
const $ = cheerio.load(`<p>Hello</p>`);
console.log($("p").text()); // "Hello"

domino は、DOM レベル 4 仕様に基づいた軽量な DOM 実装です。

  • window オブジェクトを持たず、document のみを提供します。
  • ブラウザの描画やレイアウト機能は含まれません。
// domino: 軽量な DOM 実装
const domino = require("domino");
const doc = domino.createDocument(`<p>Hello</p>`);
console.log(doc.querySelector("p").textContent); // "Hello"

parse5 は、HTML パーサーおよびシリアライザーそのものです。

  • DOM 操作 API は提供しません。
  • AST(抽象構文木)を生成し、それを元に自分で処理を書くか、他のライブラリに渡します。
// parse5: 純粋なパーサー
const parse5 = require("parse5");
const ast = parse5.parse(`<p>Hello</p>`);
console.log(ast.childNodes[0].tagName); // "p"

⚡ パフォーマンスとリソース消費

処理速度とメモリ使用量は、大規模な HTML を扱う際に重要な要素です。

cheerio は、不要なブラウザ機能を捨てることで最も高速に動作する傾向があります。

  • 単純な要素の抽出や属性の変更であれば、他の追随を許しません。
// cheerio: 高速な操作
const $ = cheerio.load(largeHtmlString);
const titles = $("h1").map((i, el) => $(el).text()).get();

jsdom は機能性が最も高い分、初期化コストとメモリ使用量が大きいです。

  • 複雑な DOM 操作やイベントシミュレーションが必要な場合に真価を発揮します。
// jsdom: 高機能だが重め
const { JSDOM } = require("jsdom");
const dom = new JSDOM(largeHtmlString);
const titles = Array.from(dom.window.document.querySelectorAll("h1")).map(el => el.textContent);

dominojsdom よりも軽量ですが、cheerio ほど最適化されていません。

  • DOM 仕様への準拠が必要な場合の中間選択肢となります。
// domino: 中程度の重さ
const doc = domino.createDocument(largeHtmlString);
const titles = Array.from(doc.querySelectorAll("h1")).map(el => el.textContent);

parse5 はパーシングのみを行うため、単体では比較対象が異なりますが、基盤として非常に高速です。

  • 自分でトラバーサルロジックを書く手間がかかります。
// parse5: 最速のパーシングだが手動作業が必要
const ast = parse5.parse(largeHtmlString);
// ここから自分で AST を走査して h1 タグを探す必要がある

🧪 テスト環境での利用適性

フロントエンドのテスト自動化において、どのライブラリを選ぶかはテストの目的によります。

jsdom は、ブラウザの挙動を再現する必要があるテストに最適です。

  • jestvitest などのテストランナーでデフォルト環境としてよく使われます。
  • click()dispatchEvent() などのイベント操作も可能です。
// jsdom: イベント処理のテスト
const { JSDOM } = require("jsdom");
const dom = new JSDOM(`<button id="btn">Click</button>`);
const btn = dom.window.document.getElementById("btn");
btn.click(); // イベントが発火する

cheerio は、HTML の出力内容を確認するスナップショットテストや、スクレイピングロジックのテストに向いています。

  • イベント処理やブラウザ固有の API は使えません。
// cheerio: 出力内容の検証
const $ = cheerio.load(renderedHtml);
expect($(".error-message").length).toBe(1);

domino は、DOM 構造の検証には使えますが、イベントシミュレーション機能は限定的です。

  • jsdom ほどテストエコシステムとの統合は進んでいません。
// domino: 構造検証
const doc = domino.createDocument(renderedHtml);
expect(doc.querySelectorAll(".item").length).toBe(5);

parse5 は、HTML パーサー自体のテストや、AST 変換ツールの開発に使われます。

  • アプリケーションの動作テストには通常使用しません。
// parse5: AST 構造の検証
const ast = parse5.parse(html);
// AST のノード構造が正しいか検証する

🛠️ API の使いやすさと学習コスト

開発者がどれだけ早くコードを書けるかも重要な選定基準です。

cheerio は、jQuery を知っている開発者にとって最も親しみやすいです。

  • チェーンメソッドで直感的に操作を書けます。
// cheerio: 直感的なチェーン操作
$("ul").find("li").addClass("active").text();

jsdom は、標準の Web API に準拠しているため、ブラウザでの開発経験がそのまま活かせます。

  • querySelectoraddEventListener など、普段使う API が使えます。
// jsdom: 標準 Web API
document.querySelector("ul").classList.add("active");

domino も標準 DOM API に準拠していますが、window がないため一部のコードは修正が必要です。

  • ブラウザ依存のコードをサーバーに持ってくる際に注意が必要です。
// domino: 標準 API だが window なし
doc.querySelector("ul").classList.add("active");

parse5 は、AST を直接扱うため、他の 3 つに比べて学習コストが高いです。

  • HTML 構造の深い理解が必要になります。
// parse5: AST 直接操作
// ノードを再帰的に走査する関数を書く必要がある
function traverse(node) { /*...*/ }

🌐 実世界のユースケース

シナリオ 1:Web スクレイピング

大量のページから特定のデータを抽出したい。

  • 最適: cheerio
  • 理由:高速で、必要なデータ抽出に特化した API が揃っているため。
const $ = cheerio.load(html);
const price = $(".price").text();

シナリオ 2:コンポーネントのサーバーサイドレンダリングテスト

React や Vue コンポーネントが正しくレンダリングされるか確認したい。

  • 最適: jsdom
  • 理由:ブラウザ環境をエミュレートし、フレームワークのライフサイクルを正しく動作させるため。
const { JSDOM } = require("jsdom");
global.window = new JSDOM().window;
// ここでコンポーネントをマウントしてテスト

シナリオ 3:HTML のサニタイズや変換ツール開発

HTML 構造を安全に書き換えたり、別の形式に変換したい。

  • 最適: parse5
  • 理由:パーシングとシリアライズを正確に行え、中間表現を自由に制御できるため。
const ast = parse5.parse(html);
// AST を加工して
const html = parse5.serialize(ast);

シナリオ 4:軽量な DOM 操作が必要だが jsdom は重すぎる

DOM 操作は必要だが、イベントやウィンドウ機能は不要。

  • 最適: domino
  • 理由:jsdom より軽量で、標準 DOM API が使えるため。
const doc = domino.createDocument(html);
doc.querySelector("div").remove();

📊 比較サマリーテーブル

特徴cheeriojsdomdominoparse5
主な用途スクレイピング、HTML 操作テスト、ブラウザエミュレーション軽量 DOM 操作パーシング基盤
API スタイルjQuery ライク標準 Web API標準 DOM APIAST 操作
DOM 実装独自(簡易)完全準拠準拠(window なし)なし(AST)
JavaScript 実行
イベント処理⚠️ 限定的
パフォーマンス🚀 非常に高速🐢 重い🏃 中程度🚀 高速(パーシングのみ)
メンテナンス✅ 活発✅ 活発⚠️ 低調✅ 活発

💡 最終的な推奨事項

プロジェクトの要件に応じて、以下のように選択するのが賢明です。

  • スクレイピングや単純な HTML 加工cheerio を選択。開発速度と実行速度のバランスが最も優れています。
  • ブラウザ挙動のテストや SSR テストjsdom を選択。環境の再現性が最も重要です。
  • 標準 DOM API が必要だが軽量さが欲しいdomino を検討。ただしメンテナンス状況を注視してください。
  • コンパイラや変換ツールを開発するparse5 を選択。最も低レベルで正確な制御が可能です。

これら 4 つのライブラリは互いに排他的なものではなく、状況に応じて使い分けることで、Node.js での HTML 処理を効率的かつ確実に行うことができます。

選び方: parse5 vs cheerio vs domino vs jsdom

  • parse5:

    HTML パーシングやシリアライズそのものを行いたい場合、あるいは独自の DOM 実装の上にパーサーを構築したい場合に使用します。DOM 操作 API は提供しないため、他のライブラリと組み合わせて使うことが一般的です。

  • cheerio:

    jQuery に似た構文で HTML を操作したい場合や、スクレイピングで特定の要素を素早く抽出したい場合に選択します。ブラウザの DOM 仕様全体を必要とせず、パフォーマンスと記述のしやすさを重視するプロジェクトに適しています。

  • domino:

    ブラウザのレイアウトや描画機能を必要とせず、純粋な DOM ツリー操作だけを行いたい場合に適しています。jsdom よりも軽量ですが、メンテナンス頻度は低いため、長期プロジェクトでは注意が必要です。

  • jsdom:

    ブラウザ環境をシミュレートして JavaScript を実行する必要がある場合や、React や Vue などのフレームワークをサーバーサイドでテストする場合に選択します。DOM 仕様のサポートが最も充実していますが、リソース消費は大きめです。

parse5 のREADME

parse5

parse5

HTML parser and serializer.

npm install --save parse5

📖 Documentation 📖


List of parse5 toolset packages

GitHub

Online playground

Changelog