DOMParser vs js parser

JavaScript performance comparison

Test case created by Oleg

Preparation code


      
      <script>
Benchmark.prototype.setup = function() {
  function serialize(str, parent) {
      var i = 0,
          end = false,
          added = false,
          current,
          isWhite, isSlash, isOpen, isClose,
          inTag = false,
          inTagName = false,
          inAttrName = false,
          inAttrValue = false,
          inCloser = false,
          inClosing = false,
          isQuote, openQuote,
          attrName, attrValue,
          inText = false,
          tag = {parent: parent}
  
      parent || (parent = {})
  
      if (str) {
          tag.name = ''
      } else {
          return parent
      }
  
      while (!end) {
          current = str[i]
          isWhite = current == ' ' || current == '\t' || current == '\r' || current == '\n'
          isSlash = current == '/'
          isOpen = current == '<'
          isClose = current == '>'
          isQuote = current == "'" || current == '"'
          if (isSlash) inClosing = true
          if (isClose) inCloser = false
  
          if (current == null) {
              end = true
          } else {
              if (inTag) {
                  if (inCloser) {
                      delete tag.name
                  // Tag name
                  } else if (inTagName || !tag.name) {
                      inTagName = true
                      if ((tag.name && isWhite) || isSlash) {
                          inTagName = false
                          if (!tag.name) {
                              inCloser = true
                              if (parent.parent) parent = parent.parent
                          }
                      } else if (isClose) {
                          serialize(str.substr(i + 1), inClosing || inCloser ? parent : tag)
                          return parent
                      } else if (!isWhite) {
                          tag.name += current
                      }
                  // Attribute name
                  } else if (inAttrName || !attrName) {
                      inAttrName = true
                      if (attrName == null) attrName = ''
                      if (isSlash ||
                          (attrName && isWhite) ||
                          (attrName && current == '=')) {
  
                          inAttrName = false
                          if (attrName) {
                              tag.attributes || (tag.attributes = {})
                              tag.attributes[attrName] = ''
                          }
                      } else if (isClose) {
                          serialize(str.substr(i + 1), inClosing || inCloser ? parent : tag)
                          return parent
                      } else if (!isWhite) {
                          attrName += current
                      }
                  // Attribute value
                  } else if (inAttrValue || attrName) {
                      if (attrValue == null) attrValue = ''
  
                      if (isQuote) {
                          if (inAttrValue) {
                              if (current == openQuote) {
                                  if (attrValue) tag.attributes[attrName] = attrValue
                                  inAttrValue = false
                                  attrName = attrValue = null
                              } else {
                                  attrValue += current
                              }
                          } else {
                              inAttrValue = true
                              openQuote = current
                          }
                      } else if (inAttrValue) {
                          attrValue += current
                      }
                  }
              } else if (isOpen) {
                  if (inText) {
                      serialize(str.substr(i), parent)
                      return parent
                  }
                  inTag = true
              } else if (isSlash && !inAttrValue) {
                  end = true
              } else {
                  inText = true
                  inTag = false
                  tag.name || (tag.name = '#text')
                  if (tag.text == null) tag.text = ''
                  tag.text += current
              }
  
              if (tag.name && !added) {
                  parent.children || (parent.children = {length: 0})
                  parent.children[parent.children.length] = tag
                  parent.children.length++
                  added = true
              }
          }
  
          if (isClose) inClosing = false
  
          ++i
      }
  
      return parent
  }
  
  var html = Array(100).join('<div>aaa</div>')
  var domParser = new DOMParser()
  var element = document.createElement('div')
  var doc = document.implementation.createHTMLDocument('')

};
</script>

Test runner

Warning! For accurate results, please disable Firebug before running the tests. (Why?)

Java applet disabled.

Testing in CCBot 2.0.0 / Other 0.0.0
Test Ops/sec
DOMParser
// Using application/xml because text/html is not supported everywhere
domParser.parseFromString(html, "application/xml");
pending…
Element
element.innerHTML = html
pending…
HtmlDocument
doc.body.innerHTML = html
pending…
JS parser
serialize(html)
pending…

Compare results of other browsers

Revisions

You can edit these tests or add even more tests to this page by appending /edit to the URL.

0 Comments