@samitouri / QOS-React-2 / commits / cd7d863f20

Avoid unnecessary array allocations in dangerouslyRenderMarkup.

Ben Newman committed Sep 9, 2013 at 14:55 UTC cd7d863f205dbeac5f6b43b947a139ce51eb0a6e
1 file changed +32 -20
src/dom/Danger.js
+32 -20
@@ -31,6 +31,9 @@ var mutateHTMLNodeWithMarkup = require('mutateHTMLNodeWithMarkup');
31
32 var COMMENT_NODE_TYPE = 8;
33
34 +// This buffer will be reused in dangerouslyRenderMarkup to avoid unnecessary
35 +// array allocations.
36 +var reusableBuffer = [];
37
38 /**
39 * Extracts the `nodeName` from a string of markup.
@@ -50,9 +53,9 @@ function getNodeName(markup) {
53 var Danger = {
54
55 /**
53 - * Renders markup into an array of nodes. The markup is expected to
54 - * render into a list of root nodes. Also, the length of `resultList`
55 - * and `markupList` should be the same.
56 + * Renders markup into an array of nodes. The markup is expected to render
57 + * into a list of root nodes. Also, the length of `resultList` and
58 + * `markupList` should be the same.
59 *
60 * @param {array<string>} markupList List of markup strings to render.
61 * @return {array<DOMElement>} List of rendered nodes.
@@ -86,15 +89,17 @@ var Danger = {
89 }
90 var markupListByNodeName = markupByNodeName[nodeName];
91
89 - var commentedMarkupList = [];
90 - // This for-in loop skips the holes of the sparse array. The order
91 - // of iteration should follow the order of assignment, which happens
92 - // to match numerical index order, but we don't rely on that.
92 + var commentedMarkupList = reusableBuffer;
93 + commentedMarkupList.length = 0;
94 +
95 + // This for-in loop skips the holes of the sparse array. The order of
96 + // iteration should follow the order of assignment, which happens to match
97 + // numerical index order, but we don't rely on that.
98 for (var resultIndex in markupListByNodeName) {
99 if (markupListByNodeName.hasOwnProperty(resultIndex)) {
100 // Push the requested markup followed by a sentinel HTML
96 - // comment. Comments are a good choice for sentinels because
97 - // they can appear as children of any HTML node.
101 + // comment. Comments are a good choice for sentinels because they can
102 + // appear as children of any HTML node.
103 commentedMarkupList.push(
104 markupListByNodeName[resultIndex],
105 // This resultIndex will be parsed back out below.
@@ -103,14 +108,15 @@ var Danger = {
108 }
109 }
110
106 - // Render each group of markup with similar wrapping `nodeName`,
107 - // with sentinel comments interspersed.
111 + // Render each group of markup with similar wrapping `nodeName`, with
112 + // sentinel comments interspersed.
113 var renderNodes = createNodesFromMarkup(
114 commentedMarkupList.join(''),
115 emptyFunction // Do nothing special with <script> tags.
116 );
117
113 - var renderBuffer = [];
118 + var renderBuffer = reusableBuffer;
119 + renderBuffer.length = 0;
120
121 for (i = 0; i < renderNodes.length; ++i) {
122 var renderNode = renderNodes[i];
@@ -137,8 +143,8 @@ var Danger = {
143 "rendered as " + renderBuffer.length + " nodes instead of 1:"
144 ];
145
140 - // Pass the nodes as arguments to console.error so that
141 - // they can be inspected in the browser.
146 + // Pass the nodes as arguments to console.error so that they can
147 + // be inspected in the browser.
148 args.push.apply(args, renderBuffer);
149
150 // Use console.error instead of throwing so that we don't
@@ -151,13 +157,13 @@ var Danger = {
157 // resultList[resultIndex];
158 renderBuffer.length = 0;
159
154 - // This should match resultList.length and markupList.length
155 - // when we're done.
160 + // This should match resultList.length and markupList.length when
161 + // we're done.
162 resultListAssignmentCount += 1;
163
164 } else {
159 - // It's some other kind of comment that we didn't create.
160 - // Weirder things have happened.
165 + // It's some other kind of comment that we didn't create. Weirder
166 + // things have happened.
167 renderBuffer.push(renderNode);
168 console.warn(
169 'Danger: Markup unexpectedly rendered a comment node:',
@@ -168,8 +174,14 @@ var Danger = {
174 }
175 }
176
171 - // Although resultList was populated out of order, it should now be a
172 - // dense array.
177 + invariant(
178 + reusableBuffer.length === 0,
179 + 'Danger: Rendered malformed markup: %s.',
180 + reusableBuffer
181 + );
182 +
183 + // Although resultList was populated out of order, it should now be a dense
184 + // array.
185 invariant(
186 resultListAssignmentCount === resultList.length,
187 'Danger: Did not assign to every index of resultList.'