Skip to content

Commit d547374

Browse files
petehuntzpao
authored andcommitted
[perf] Log DOM time
Log the time it takes to perform all DOM operations
1 parent 756bd97 commit d547374

File tree

1 file changed

+102
-74
lines changed

1 file changed

+102
-74
lines changed

src/browser/ReactDOMIDOperations.js

Lines changed: 102 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ var CSSPropertyOperations = require('CSSPropertyOperations');
2525
var DOMChildrenOperations = require('DOMChildrenOperations');
2626
var DOMPropertyOperations = require('DOMPropertyOperations');
2727
var ReactMount = require('ReactMount');
28+
var ReactPerf = require('ReactPerf');
2829

2930
var getTextContentAccessor = require('getTextContentAccessor');
3031
var invariant = require('invariant');
@@ -66,23 +67,27 @@ var ReactDOMIDOperations = {
6667
* @param {*} value New value of the property.
6768
* @internal
6869
*/
69-
updatePropertyByID: function(id, name, value) {
70-
var node = ReactMount.getNode(id);
71-
invariant(
72-
!INVALID_PROPERTY_ERRORS.hasOwnProperty(name),
73-
'updatePropertyByID(...): %s',
74-
INVALID_PROPERTY_ERRORS[name]
75-
);
76-
77-
// If we're updating to null or undefined, we should remove the property
78-
// from the DOM node instead of inadvertantly setting to a string. This
79-
// brings us in line with the same behavior we have on initial render.
80-
if (value != null) {
81-
DOMPropertyOperations.setValueForProperty(node, name, value);
82-
} else {
83-
DOMPropertyOperations.deleteValueForProperty(node, name);
70+
updatePropertyByID: ReactPerf.measure(
71+
'ReactDOMIDOperations',
72+
'updatePropertyByID',
73+
function(id, name, value) {
74+
var node = ReactMount.getNode(id);
75+
invariant(
76+
!INVALID_PROPERTY_ERRORS.hasOwnProperty(name),
77+
'updatePropertyByID(...): %s',
78+
INVALID_PROPERTY_ERRORS[name]
79+
);
80+
81+
// If we're updating to null or undefined, we should remove the property
82+
// from the DOM node instead of inadvertantly setting to a string. This
83+
// brings us in line with the same behavior we have on initial render.
84+
if (value != null) {
85+
DOMPropertyOperations.setValueForProperty(node, name, value);
86+
} else {
87+
DOMPropertyOperations.deleteValueForProperty(node, name);
88+
}
8489
}
85-
},
90+
),
8691

8792
/**
8893
* Updates a DOM node to remove a property. This should only be used to remove
@@ -92,15 +97,19 @@ var ReactDOMIDOperations = {
9297
* @param {string} name A property name to remove, see `DOMProperty`.
9398
* @internal
9499
*/
95-
deletePropertyByID: function(id, name, value) {
96-
var node = ReactMount.getNode(id);
97-
invariant(
98-
!INVALID_PROPERTY_ERRORS.hasOwnProperty(name),
99-
'updatePropertyByID(...): %s',
100-
INVALID_PROPERTY_ERRORS[name]
101-
);
102-
DOMPropertyOperations.deleteValueForProperty(node, name, value);
103-
},
100+
deletePropertyByID: ReactPerf.measure(
101+
'ReactDOMIDOperations',
102+
'deletePropertyByID',
103+
function(id, name, value) {
104+
var node = ReactMount.getNode(id);
105+
invariant(
106+
!INVALID_PROPERTY_ERRORS.hasOwnProperty(name),
107+
'updatePropertyByID(...): %s',
108+
INVALID_PROPERTY_ERRORS[name]
109+
);
110+
DOMPropertyOperations.deleteValueForProperty(node, name, value);
111+
}
112+
),
104113

105114
/**
106115
* Updates a DOM node with new style values. If a value is specified as '',
@@ -110,10 +119,14 @@ var ReactDOMIDOperations = {
110119
* @param {object} styles Mapping from styles to values.
111120
* @internal
112121
*/
113-
updateStylesByID: function(id, styles) {
114-
var node = ReactMount.getNode(id);
115-
CSSPropertyOperations.setValueForStyles(node, styles);
116-
},
122+
updateStylesByID: ReactPerf.measure(
123+
'ReactDOMIDOperations',
124+
'updateStylesByID',
125+
function(id, styles) {
126+
var node = ReactMount.getNode(id);
127+
CSSPropertyOperations.setValueForStyles(node, styles);
128+
}
129+
),
117130

118131
/**
119132
* Updates a DOM node's innerHTML.
@@ -122,38 +135,42 @@ var ReactDOMIDOperations = {
122135
* @param {string} html An HTML string.
123136
* @internal
124137
*/
125-
updateInnerHTMLByID: function(id, html) {
126-
var node = ReactMount.getNode(id);
127-
128-
// IE8: When updating a just created node with innerHTML only leading
129-
// whitespace is removed. When updating an existing node with innerHTML
130-
// whitespace in root TextNodes is also collapsed.
131-
// @see quirksmode.org/bugreports/archives/2004/11/innerhtml_and_t.html
132-
133-
if (useWhitespaceWorkaround === undefined) {
134-
// Feature detection; only IE8 is known to behave improperly like this.
135-
var temp = document.createElement('div');
136-
temp.innerHTML = ' ';
137-
useWhitespaceWorkaround = temp.innerHTML === '';
138-
}
139-
140-
if (useWhitespaceWorkaround) {
141-
// Magic theory: IE8 supposedly differentiates between added and updated
142-
// nodes when processing innerHTML, innerHTML on updated nodes suffers
143-
// from worse whitespace behavior. Re-adding a node like this triggers
144-
// the initial and more favorable whitespace behavior.
145-
node.parentNode.replaceChild(node, node);
146-
}
147-
148-
if (useWhitespaceWorkaround && html.match(/^[ \r\n\t\f]/)) {
149-
// Recover leading whitespace by temporarily prepending any character.
150-
// \uFEFF has the potential advantage of being zero-width/invisible.
151-
node.innerHTML = '\uFEFF' + html;
152-
node.firstChild.deleteData(0, 1);
153-
} else {
154-
node.innerHTML = html;
138+
updateInnerHTMLByID: ReactPerf.measure(
139+
'ReactDOMIDOperations',
140+
'updateInnerHTMLByID',
141+
function(id, html) {
142+
var node = ReactMount.getNode(id);
143+
144+
// IE8: When updating a just created node with innerHTML only leading
145+
// whitespace is removed. When updating an existing node with innerHTML
146+
// whitespace in root TextNodes is also collapsed.
147+
// @see quirksmode.org/bugreports/archives/2004/11/innerhtml_and_t.html
148+
149+
if (useWhitespaceWorkaround === undefined) {
150+
// Feature detection; only IE8 is known to behave improperly like this.
151+
var temp = document.createElement('div');
152+
temp.innerHTML = ' ';
153+
useWhitespaceWorkaround = temp.innerHTML === '';
154+
}
155+
156+
if (useWhitespaceWorkaround) {
157+
// Magic theory: IE8 supposedly differentiates between added and updated
158+
// nodes when processing innerHTML, innerHTML on updated nodes suffers
159+
// from worse whitespace behavior. Re-adding a node like this triggers
160+
// the initial and more favorable whitespace behavior.
161+
node.parentNode.replaceChild(node, node);
162+
}
163+
164+
if (useWhitespaceWorkaround && html.match(/^[ \r\n\t\f]/)) {
165+
// Recover leading whitespace by temporarily prepending any character.
166+
// \uFEFF has the potential advantage of being zero-width/invisible.
167+
node.innerHTML = '\uFEFF' + html;
168+
node.firstChild.deleteData(0, 1);
169+
} else {
170+
node.innerHTML = html;
171+
}
155172
}
156-
},
173+
),
157174

158175
/**
159176
* Updates a DOM node's text content set by `props.content`.
@@ -162,10 +179,14 @@ var ReactDOMIDOperations = {
162179
* @param {string} content Text content.
163180
* @internal
164181
*/
165-
updateTextContentByID: function(id, content) {
166-
var node = ReactMount.getNode(id);
167-
node[textContentAccessor] = content;
168-
},
182+
updateTextContentByID: ReactPerf.measure(
183+
'ReactDOMIDOperations',
184+
'updateTextContentByID',
185+
function(id, content) {
186+
var node = ReactMount.getNode(id);
187+
node[textContentAccessor] = content;
188+
}
189+
),
169190

170191
/**
171192
* Replaces a DOM node that exists in the document with markup.
@@ -175,10 +196,14 @@ var ReactDOMIDOperations = {
175196
* @internal
176197
* @see {Danger.dangerouslyReplaceNodeWithMarkup}
177198
*/
178-
dangerouslyReplaceNodeWithMarkupByID: function(id, markup) {
179-
var node = ReactMount.getNode(id);
180-
DOMChildrenOperations.dangerouslyReplaceNodeWithMarkup(node, markup);
181-
},
199+
dangerouslyReplaceNodeWithMarkupByID: ReactPerf.measure(
200+
'ReactDOMIDOperations',
201+
'dangerouslyReplaceNodeWithMarkupByID',
202+
function(id, markup) {
203+
var node = ReactMount.getNode(id);
204+
DOMChildrenOperations.dangerouslyReplaceNodeWithMarkup(node, markup);
205+
}
206+
),
182207

183208
/**
184209
* Updates a component's children by processing a series of updates.
@@ -187,13 +212,16 @@ var ReactDOMIDOperations = {
187212
* @param {array<string>} markup List of markup strings.
188213
* @internal
189214
*/
190-
dangerouslyProcessChildrenUpdates: function(updates, markup) {
191-
for (var i = 0; i < updates.length; i++) {
192-
updates[i].parentNode = ReactMount.getNode(updates[i].parentID);
215+
dangerouslyProcessChildrenUpdates: ReactPerf.measure(
216+
'ReactDOMIDOperations',
217+
'dangerouslyProcessChildrenUpdates',
218+
function(updates, markup) {
219+
for (var i = 0; i < updates.length; i++) {
220+
updates[i].parentNode = ReactMount.getNode(updates[i].parentID);
221+
}
222+
DOMChildrenOperations.processUpdates(updates, markup);
193223
}
194-
DOMChildrenOperations.processUpdates(updates, markup);
195-
}
196-
224+
)
197225
};
198226

199227
module.exports = ReactDOMIDOperations;

0 commit comments

Comments
 (0)