Home | History | Annotate | Download | only in dom-perf
      1 /*
      2  * Copyright (C) 2009 Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions are
      6  * met:
      7  *
      8  *     * Redistributions of source code must retain the above copyright
      9  * notice, this list of conditions and the following disclaimer.
     10  *     * Redistributions in binary form must reproduce the above
     11  * copyright notice, this list of conditions and the following disclaimer
     12  * in the documentation and/or other materials provided with the
     13  * distribution.
     14  *     * Neither the name of Google Inc. nor the names of its
     15  * contributors may be used to endorse or promote products derived from
     16  * this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 // CreateNodes
     32 // Test mechanisms for creating and inserting nodes into a DOM tree.
     33 //
     34 // There are many ways to add nodes into a DOM tree.  This test exercises
     35 // use of:
     36 //    - createElement()/appendChild()
     37 //    - createDocumentFragment()
     38 //    - innerHTML()
     39 //    - spans
     40 
     41 function CreateNodes() {}
     42 
     43 CreateNodes.nIterations = 10000;
     44 CreateNodes.nIterationsSlow = 2000;
     45 CreateNodes.currentIterations = CreateNodes.nIterations;
     46 CreateNodes.nodeProto = null;
     47 
     48 CreateNodes.createNode = function() {
     49     if (!CreateNodes.nodeProto) {
     50         var html = this.getNodeHTML();
     51         var span = document.createElement("span");
     52         span.innerHTML = html;
     53         CreateNodes.nodeProto = span.firstChild;
     54     }
     55     return CreateNodes.nodeProto;
     56 };
     57 
     58 CreateNodes.getNodeHTML = function() {
     59     return "<div style=\"font-style:bold\">test</div>";
     60 };
     61 
     62 CreateNodes.appendNodesWithDOM = function(node) {
     63     var nodes = CreateNodes.createNodesWithDOM(node);
     64     for (var i = 0; i < CreateNodes.nIterations; i++)
     65         this.suite.benchmarkContent.appendChild(nodes[i]);
     66     CreateNodes.forceNode(this);
     67 };
     68 
     69 CreateNodes.justAppendNodesWithDOM = function(nodes) {
     70     for (var i = 0; i < CreateNodes.nIterations; i++)
     71         this.suite.benchmarkContent.appendChild(nodes[i]);
     72 };
     73 
     74 CreateNodes.createNodesWithHTML = function(html) {
     75     var allHTML = "";
     76     for (var i = 0; i < CreateNodes.currentIterations; i++)
     77         allHTML += html;
     78     return allHTML;
     79 };
     80 
     81 CreateNodes.checkNodes = function() {
     82     var length = this.suite.benchmarkContent.childNodes.length;
     83     var count = CreateNodes.currentIterations;
     84     if (length != count)
     85         throw "Should have " + count + " nodes, have: " + length;
     86 };
     87 
     88 // Ensures that the node has really been created and not just delayed
     89 CreateNodes.forceNode = function(benchmark) {
     90     var child =  benchmark.suite.benchmarkContent.childNodes[CreateNodes.nIterations / 2];
     91 };
     92 
     93 CreateNodes.appendNodesWithHTML = function(html) {
     94     var allHTML = CreateNodes.createNodesWithHTML(html);
     95     this.suite.benchmarkContent.innerHTML = allHTML;
     96     CreateNodes.forceNode(this);
     97 };
     98 
     99 CreateNodes.createNodesWithDOM = function(node) {
    100     var nodes = [];
    101     for (var i = 0; i < CreateNodes.nIterations; i++)
    102         nodes.push(node.cloneNode(true));
    103     return nodes;
    104 };
    105 
    106 CreateNodes.createNodesWithDOMSetup = function() {
    107     return createNodesWithDOM(createNode());
    108 };
    109 
    110 CreateNodes.createNodeSetup = function() {
    111     CreateNodes.currentIterations = CreateNodes.nIterations;
    112     return CreateNodes.createNode();
    113 };
    114 
    115 CreateNodes.createNodesWithHTMLUsingSpans = function(html) {
    116     var spans = [];
    117     for (var i = 0; i < CreateNodes.currentIterations; i++) {
    118         var spanNode = document.createElement("span");
    119         spanNode.innerHTML = html;
    120         spans.push(spanNode);
    121     }
    122     return spans;
    123 };
    124 
    125 CreateNodes.appendNodesWithHTMLUsingSpans = function(html) {
    126     var spans = CreateNodes.createNodesWithHTMLUsingSpans(html);
    127     for (var i = 0; i < CreateNodes.currentIterations; i++)
    128         this.suite.benchmarkContent.appendChild(spans[i]);
    129     CreateNodes.forceNode(this);
    130 };
    131 
    132 CreateNodes.appendNodesWithHTMLUsingDocumentFragments = function(html) {
    133     var fragments = CreateNodes.createNodesWithHTMLUsingDocumentFragments(html);
    134     for (var i = 0; i < CreateNodes.nIterations; i++)
    135         this.suite.benchmarkContent.appendChild(fragments[i]);
    136     CreateNodes.forceNode(this);
    137 };
    138 
    139 CreateNodes.createNodesWithHTMLUsingDocumentFragments = function(html) {
    140     var fragments = [];
    141     for (var i = 0; i < CreateNodes.nIterations; i++) {
    142         var fragment = document.createDocumentFragment();
    143         fragment.innerHTML = html;
    144         fragments.push(fragment);
    145     }
    146     return fragments;
    147 };
    148 
    149 CreateNodes.appendNodesWithDOMUsingDocumentFragment = function(node) {
    150     var fragment = CreateNodes.createNodesWithDOMUsingDocumentFragment(node);
    151     this.suite.benchmarkContent.appendChild(fragment);
    152     CreateNodes.forceNode(this);
    153 };
    154 
    155 CreateNodes.appendNodesWithDOMUsingSharedDocumentFragment = function(fragment) {
    156     this.suite.benchmarkContent.appendChild(fragment.cloneNode(true));
    157     CreateNodes.forceNode(this);
    158 };
    159 
    160 CreateNodes.createNodesWithDOMUsingDocumentFragment = function(node) {
    161     var nodes = CreateNodes.createNodesWithDOM(node);
    162     var fragment = document.createDocumentFragment();
    163     for (var i = 0; i < CreateNodes.nIterations; i++)
    164         fragment.appendChild(nodes[i]);
    165     return fragment;
    166 };
    167 
    168 CreateNodes.createSharedDocumentFragment = function() {
    169     var nodes = CreateNodes.createNodesWithDOM(CreateNodes.createNode());
    170     var fragment = document.createDocumentFragment();
    171     for (var i = 0; i < CreateNodes.nIterations; i++)
    172         fragment.appendChild(nodes[i]);
    173     return fragment;
    174 };
    175 
    176 CreateNodes.createHTMLSetup = function() {
    177     CreateNodes.currentIterations = CreateNodes.nIterationsSlow;
    178     return CreateNodes.getNodeHTML();
    179 };
    180 
    181 CreateNodes.createIFramesHTML = function() {
    182     var html = [];
    183     for (var i = 0; i < 100; i++)
    184         html.push("<iframe src='blank.html'></iframe>");
    185     return html.join('');
    186 }
    187 
    188 CreateNodes.appendIFramesHTML = function(html) {
    189     this.suite.benchmarkContent.innerHTML = html;
    190 }
    191 
    192 CreateNodes.createIFramesDOM = function() {
    193     var nodes = [];
    194     for (var i = 0; i < 100; i++) {
    195         var iframe = document.createElement('iframe');
    196         iframe.src = 'blank.html';
    197         nodes.push(iframe);
    198     }
    199     return nodes;
    200 }
    201 
    202 CreateNodes.appendIFramesDOM = function(nodes) {
    203     var content = this.suite.benchmarkContent;
    204     for (var i = 0, l = nodes.length; i < l; i++)
    205         content.appendChild(nodes[i]);
    206 }
    207 
    208 var CreateNodesTest = new BenchmarkSuite('CreateNodes', [
    209     new Benchmark("append, DOM, DocumentFragment",
    210         CreateNodes.appendNodesWithDOMUsingDocumentFragment, CreateNodes.createNodeSetup, CreateNodes.checkNodes),
    211     new Benchmark("create, DOM, DocumentFragment",
    212         CreateNodes.createNodesWithDOMUsingDocumentFragment, CreateNodes.createNodeSetup),
    213     new Benchmark("append, DOM, SharedDocumentFragment",
    214         CreateNodes.appendNodesWithDOMUsingSharedDocumentFragment, CreateNodes.createSharedDocumentFragment,  CreateNodes.checkNodes),
    215     new Benchmark("create, DOM",
    216         CreateNodes.createNodesWithDOM, CreateNodes.createNodeSetup),
    217     new Benchmark("append, DOM",
    218         CreateNodes.appendNodesWithDOM, CreateNodes.createNodeSetup, CreateNodes.checkNodes),
    219     new Benchmark("append, DOM, iFrame",
    220         CreateNodes.appendIFramesDOM, CreateNodes.createIFramesDOM),
    221     new Benchmark("append, HTML",
    222         CreateNodes.appendNodesWithHTML, CreateNodes.createHTMLSetup, CreateNodes.checkNodes),
    223     new Benchmark("create, HTML, Spans",
    224         CreateNodes.createNodesWithHTMLUsingSpans, CreateNodes.createHTMLSetup),
    225     new Benchmark("append, HTML, Spans",
    226         CreateNodes.appendNodesWithHTMLUsingSpans, CreateNodes.createHTMLSetup, CreateNodes.checkNodes),
    227     new Benchmark("append, HTML, iFrame",
    228         CreateNodes.appendIFramesHTML, CreateNodes.createIFramesHTML)
    229 ]);
    230