素人がプログラミングを勉強していたブログ

プログラミング、セキュリティ、英語、Webなどのブログ since 2008

連絡先: すかいぷ:javascripter_  か javascripter あっと tsukkun.net skypeのほうがいいです

document.createTreeWalkerとArray.prototype.filterとXPathの比較、テキストノードを取得する場合

経由でTreeWalkerを知って、速度はどうなんだろうなーと思って調べた。
TreeWalkerについてはMozilla Developer Networkを参考にした。

function getTextNodes (parentNode) {
	var walker = document.createTreeWalker(
		parentNode,
		NodeFilter.SHOW_TEXT,
		{
			acceptNode: function() NodeFilter.FILTER_ACCEPT
		},
		false
	),
	textNodes = [];
	while (walker.nextNode()) textNodes.push(walker.currentNode);
	return textNodes;
}
function getTextNodes2 (parentNode) {
	var textNodes = [];
	return textNodes.concat(
		Array.filter(
			parentNode.childNodes,
			function (node) {
				if (node.hasChildNodes()) {
					textNodes.push.apply(textNodes, getTextNodes2(node));
					return false;
				}
				return node.nodeType == Node.TEXT_NODE;
			}
		)
	);
}
function getTextNodes3 (parentNode) {
	var xp = document.evaluate(
		'.//text()',
		document.body,
		null,
		XPathResult.ORDERED_NODE_ITERATOR_TYPE,
		null
	),
	textNodes = [],
	node;
	while (node = xp.iterateNext()) textNodes.push(node);
	return textNodes;
}
console.time('treeWalker');
for (var i = 0;i < 100;i ++)
	getTextNodes(document.body);
console.timeEnd('treeWalker');
console.time('filter');
for (var i = 0;i < 100;i ++)
	getTextNodes2(document.body);
console.timeEnd('filter');
console.time('xpath');
for (var i = 0;i < 100;i ++)
	getTextNodes3(document.body);
console.timeEnd('xpath');

treeWalker: 1351ms
filter: 2448ms
xpath: 320ms

XPathの圧勝。
Array.prototype.filterと再帰を組み合わせるのよりはTreeWalkerのほうが優位なので、XPathでは難しいような作業をするときにTreeWalkerを使うといい。