Guest User

Untitled

a guest
May 27th, 2018
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.60 KB | None | 0 0
  1. # Profiler
  2.  
  3. React 16.4 will introduce a new `Profiler` component (initially exported as `React.unstable_Profiler`) for collecting render timing information in order to measure the "cost" of rendering for both sync and async modes.
  4.  
  5. `Profiler` timing metrics are significantly faster than those built around the User Timing API, and as such we plan to provide a production+profiling bundle in the future. (The initial release will only log timing information in DEV mode, although the component will still render its children- without timings- in production mode.)
  6.  
  7. ## How is it used?
  8.  
  9. `Profiler` can be declared anywhere within a React tree to measure the cost of rendering that portion of the tree. For example, a `Navigation` component and its descendants:
  10. ```js
  11. const Profiler = React.unstable_Profiler;
  12.  
  13. render(
  14. <App>
  15. <Profiler id="Navigation" onRender={callback}>
  16. <Navigation {...props} />
  17. </Profiler>
  18. <Main {...props} />
  19. </App>
  20. );
  21. ```
  22.  
  23. Multiple `Profiler`s can be used to measure different parts of an application:
  24. ```js
  25. const Profiler = React.unstable_Profiler;
  26.  
  27. render(
  28. <App>
  29. <Profiler id="Navigation" onRender={callback}>
  30. <Navigation {...props} />
  31. </Profiler>
  32. <Profiler id="Main" onRender={callback}>
  33. <Main {...props} />
  34. </Profiler>
  35. </App>
  36. );
  37. ```
  38.  
  39. `Profiler`s can also be nested to measure different components within the same subtree:
  40. ```js
  41. const Profiler = React.unstable_Profiler;
  42.  
  43. render(
  44. <App>
  45. <Profiler id="Panel" onRender={callback}>
  46. <Panel {...props}>
  47. <Profiler id="Content" onRender={callback}>
  48. <Content {...props} />
  49. </Profiler>
  50. <Profiler id="PreviewPane" onRender={callback}>
  51. <PreviewPane {...props} />
  52. </Profiler>
  53. </Panel>
  54. </Profiler>
  55. </App>
  56. );
  57. ```
  58.  
  59. Although `Profiler` is a light-weight component, it should be used sparingly. Every component adds CPU and memory overhead to an application.
  60.  
  61. ## `onRender` callback
  62.  
  63. The `onRender` callback is called each time the root renders. It receives the following parameters:
  64. * `id: string` - The `id` value of the `Profiler` tag that was measured. (This `id` can change between renders if it is derived from `state` or `props`.)
  65. * `phase: string` - Either "mount" or "update" (depending on whether this root was newly mounted or has just been updated).
  66. * `actualTime: number` - Time spent rendering the `Profiler` and its descendants for the most recent "mount" or "update" render. <sup>1</sup>
  67. * `baseTime: number` - Duration of the most recent `render` time for each individual component within the `Profiler` tree. <sup>1</sup>
  68. * `startTime: number` - When the `Profiler` began the recently committed render. <sup>2</sup>
  69. * `commitTime: number` - The time at which the current commit took place. <sup>2</sup>
  70.  
  71. <sup>1: See [**"Timing metrics"**](#timing-metrics) section below for more detailed information about what this time represents.</sup>
  72.  
  73. <sup>2: See [**"Start and commit times"**](#start-and-commit-times) section below for more detailed information about what this time represents.</sup>
  74.  
  75. ## Timing metrics
  76.  
  77. Here is a review of the types of timing React is now capable of reporting:
  78.  
  79. #### User Timing API
  80.  
  81. Measures start/stop times for each component lifecycle.
  82.  
  83. * **Opt in mechanism**: Feature flag (typically DEV mode only)
  84. * **Scope**: Tracked for all components in an app
  85. * **How is it measured?**
  86. * Start/stop times for each component lifecycle
  87. * Measured as a realtime graph
  88. * **When is it recorded?**
  89. * Realtime graph is recorded after each lifecycle call.
  90. * **What does it tell us?**
  91. * Flame graph paints a useful picture of how events (e.g. mouse clicks) tie together with rendering.
  92.  
  93. #### “Actual” render time (new)
  94.  
  95. Time spent rendering the `Profiler` and its descendants for the most recent render/update.
  96.  
  97. * **Opt in mechanism**: Wrap a component with `<Profiler>`
  98. * **Scope**: Measured for descendants of `Profiler` only
  99. * **How is it measured?**
  100. * Start timer during “begin” phase, stop during “complete” phase
  101. * Paused (and accumulated) for scheduling/timing interruptions <sup>3</sup>
  102. * Paused (and accumulated) for aborted renders (e.g. suspense)
  103. * **When is it recorded?**
  104. * A new snapshot is recorded each time a `Profiler` is re-rendered
  105. * **What does it tell us?**
  106. * How well does the subtree make use of `shouldComponentUpdate` for memoization?
  107. * The more this time decreases for update renders, the better the memoization.
  108.  
  109. #### “Base” render time (new)
  110.  
  111. Duration of the most recent `render` time for each individual component within the `Profiler` tree.
  112.  
  113. * **Opt in mechanism**: Wrap a component with `<Profiler>`
  114. * **Scope**: Measured for descendants of `Profiler` only
  115. * **How is it measured?**
  116. * Measured for each fiber below a `Profiler` component.
  117. * Recorded during “begin” phase.
  118. * Times are not updated/recorded if a component skips render because of `shouldComponentUpdate`
  119. * (Descendant times are also not updated in that case)
  120. * Bubble up (summed) for the `Profiler` during “complete” phase
  121. * Total times logged for `Profiler` (not for individual fibers)
  122. * **When is it recorded?**
  123. * A new snapshot is recorded each time a `Profiler` is re-rendered
  124. * **What does it tell us?**
  125. * How expensive our render functions are in the worst case (no memoization).
  126. * Lower this number by reducing the work done in render.
  127.  
  128. <sup>3: Until "resume" behavior is implemented, interruptions will not accumulate time.</sup>
  129.  
  130. ## Start and commit times
  131.  
  132. At first glance, these values may seem redundant. Why is commit time necessary? Why isn't it just the time at which the `onRender` callback is called? And why is start time not just the commit time less the "actual" time?
  133.  
  134. #### Start time
  135.  
  136. Start time identifies when a particular commit started rendering. Although insufficient to determine the cause of the render, it can at least be used to rule out certain interactions (e.g. mouse click, Flux action). This may be helpful if you are also collecting other types of interactions and trying to correlate them with renders.
  137.  
  138. Start time isn't just the commit time less the "actual" time, because in async rendering mode React may yield during a render. This "yielded time" (when React was not doing work) is not included in either the "actual" or "base" time measurements.
  139.  
  140. #### Commit time
  141.  
  142. Commit time could be roughly determined using e.g. `performance.now()` within the `onRender` callback, but multiple `Profiler` components would end up with slightly different times for a single commit. Instead, an explicit time is provided (shared between all `Profiler`s in the commit) enabling them to be grouped if desirable.
Add Comment
Please, Sign In to add comment