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を使うといい。