うさぎのメモ帳

NodeでHTMLをパースする場合 cheerio より node-html-parser の方が40倍以上速い

2019年10月06日 - 2019年10月06日

HTMLテキストをパースして情報を抜き出して使いたいときに、(名だたるスポンサーと記述が分かりやすいため)考えなしにcheerioを使っていましたが、node-html-parserが速いとのことで比較しました。

時間の計測方法は以下の通り。

const { PerformanceObserver, performance } = require('perf_hooks')

const obs = new PerformanceObserver((items) => {
  console.log(items.getEntries()[0].duration)
  performance.clearMarks()
})
obs.observe({ entryTypes: ['measure'] })

performance.mark('A')

// node-html-parser の処理

performance.mark('B')
performance.measure('A to B', 'A', 'B')

performance.mark('A2')

// cheerio の処理

performance.mark('B2')
performance.measure('A2 to B2', 'A2', 'B2')

via: Performance Timing API | Node.js v12.11.1 Documentation

Round 1: IDセレクタの取得速度

node-html-parser

const root: any = parse('<ul id="list"><li>Hello World</li></ul>')
for (let i = 0; i < 100000; i++) {
  root.querySelector('#list')
}

cheerio

const $ = cheerio.load('<ul id="list"><li>Hello World</li></ul>')
for (let i = 0; i < 100000; i++) {
  $('#list')
}
# node-html-parser (ms) cheerio (ms)
1 39.410153 1974.832278
2 25.997488 1799.667974
3 26.361492 1680.988045
4 27.336596 1670.949191
5 28.018640 1868.625294
avg. 29.424874 1799.012556

61.139176624倍node-html-parserが速い

Round 2: 子セレクタのテキスト取得

node-html-parser

const root: any = parse('<ul id="list"><li>Hello World</li></ul>')
for (let i = 0; i < 100000; i++) {
  root.querySelector('#list li').rawText
}

cheerio

const $ = cheerio.load('<ul id="list"><li>Hello World</li></ul>')
for (let i = 0; i < 100000; i++) {
  $('#list li').text()
}
# node-html-parser (ms) cheerio (ms)
1 40.164331 2004.584263
2 39.167340 1911.739948
3 38.970721 1918.269257
4 38.370929 1821.918526
5 47.613663 1810.410197
avg. 40.857397 1893.384438

46.34128913倍node-html-parserが速い

内容変更する必要のない単純な取得ならnode-html-parserでこと足りそうなので、一度使ってみようと思います。