@samitouri / QOS-React / commits / 0a248ee7b9

Show React events in the timeline when ReactPerf is active (#7549)

* Show React events in the timeline when ReactPerf is active This currently only seems to work on Chrome. * Address Chrome issue

Dan Abramov committed Aug 24, 2016 at 18:40 UTC 0a248ee7b953d5c207b87d2840bd4295891760e2
1 file changed +65
src/renderers/shared/ReactDebugTool.js
+65
@@ -192,6 +192,63 @@ function resumeCurrentLifeCycleTimer() {
192 currentTimerType = timerType;
193 }
194
195 +var lastMarkTimeStamp = null;
196 +var canUsePerformanceMeasure =
197 + typeof performance !== 'undefined' &&
198 + typeof performance.mark === 'function' &&
199 + typeof performance.clearMarks === 'function' &&
200 + typeof performance.measure === 'function' &&
201 + typeof performance.clearMeasures === 'function';
202 +
203 +function shouldMark(debugID) {
204 + if (!isProfiling || !canUsePerformanceMeasure) {
205 + return false;
206 + }
207 + var element = ReactComponentTreeHook.getElement(debugID);
208 + if (element == null || typeof element !== 'object') {
209 + return false;
210 + }
211 + var isHostElement = typeof element.type === 'string';
212 + if (isHostElement) {
213 + return false;
214 + }
215 + return true;
216 +}
217 +
218 +function markBegin(debugID, markType) {
219 + if (!shouldMark(debugID)) {
220 + return;
221 + }
222 +
223 + var markName = `${debugID}::${markType}`;
224 + lastMarkTimeStamp = performanceNow();
225 + performance.mark(markName);
226 +}
227 +
228 +function markEnd(debugID, markType) {
229 + if (!shouldMark(debugID)) {
230 + return;
231 + }
232 +
233 + var markName = `${debugID}::${markType}`;
234 + var displayName = ReactComponentTreeHook.getDisplayName(debugID);
235 +
236 + // Chrome has an issue of dropping markers recorded too fast:
237 + // https://bugs.chromium.org/p/chromium/issues/detail?id=640652
238 + // To work around this, we will not report very small measurements.
239 + // I determined the magic number by tweaking it back and forth.
240 + // 0.05ms was enough to prevent the issue, but I set it to 0.1ms to be safe.
241 + // When the bug is fixed, we can `measure()` unconditionally if we want to.
242 + var timeStamp = performanceNow();
243 + if (timeStamp - lastMarkTimeStamp > 0.1) {
244 + var measurementName = `${displayName} [${markType}]`;
245 + performance.measure(measurementName, markName);
246 + }
247 +
248 + performance.clearMarks(markName);
249 + performance.clearMeasures(measurementName);
250 +}
251 +
252 var ReactDebugTool = {
253 addHook(hook) {
254 hooks.push(hook);
@@ -244,11 +301,13 @@ var ReactDebugTool = {
301 onBeginLifeCycleTimer(debugID, timerType) {
302 checkDebugID(debugID);
303 emitEvent('onBeginLifeCycleTimer', debugID, timerType);
304 + markBegin(debugID, timerType);
305 beginLifeCycleTimer(debugID, timerType);
306 },
307 onEndLifeCycleTimer(debugID, timerType) {
308 checkDebugID(debugID);
309 endLifeCycleTimer(debugID, timerType);
310 + markEnd(debugID, timerType);
311 emitEvent('onEndLifeCycleTimer', debugID, timerType);
312 },
313 onError(debugID) {
@@ -279,25 +338,31 @@ var ReactDebugTool = {
338 checkDebugID(debugID);
339 checkDebugID(parentDebugID, true);
340 emitEvent('onBeforeMountComponent', debugID, element, parentDebugID);
341 + markBegin(debugID, 'mount');
342 },
343 onMountComponent(debugID) {
344 checkDebugID(debugID);
345 + markEnd(debugID, 'mount');
346 emitEvent('onMountComponent', debugID);
347 },
348 onBeforeUpdateComponent(debugID, element) {
349 checkDebugID(debugID);
350 emitEvent('onBeforeUpdateComponent', debugID, element);
351 + markBegin(debugID, 'update');
352 },
353 onUpdateComponent(debugID) {
354 checkDebugID(debugID);
355 + markEnd(debugID, 'update');
356 emitEvent('onUpdateComponent', debugID);
357 },
358 onBeforeUnmountComponent(debugID) {
359 checkDebugID(debugID);
360 emitEvent('onBeforeUnmountComponent', debugID);
361 + markBegin(debugID, 'unmount');
362 },
363 onUnmountComponent(debugID) {
364 checkDebugID(debugID);
365 + markEnd(debugID, 'unmount');
366 emitEvent('onUnmountComponent', debugID);
367 },
368 onTestEvent() {