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

Updated profiler overview

Brian Vaughn committed May 24, 2019 at 14:43 UTC c8411019f18e9bb16d2e8fbdac29ab1039b9131a
1 file changed +7 -152
OVERVIEW.md
+7 -152
@@ -243,7 +243,7 @@ The Profiler UI is a powerful tool for identifying and fixing performance proble
243 * Minimizing bridge traffic.
244 * Making expensive computations lazy.
245
246 -Profiling information is stored on the backend. The backend push-notifies the frontend of when profiling starts or stops by sending a "_profilingStatus_" message. (The frontend also asks for the current status after mounting by sending a "_getProfilingStatus_" message.)
246 +The majority of profiling information is stored on the backend. The backend push-notifies the frontend of when profiling starts or stops by sending a "_profilingStatus_" message. (The frontend also asks for the current status after mounting by sending a "_getProfilingStatus_" message.)
247
248 When profiling begins, the frontend takes a snapshot/copy of each root. This snapshot includes the id, name, key, and child IDs for each node in the tree. (This information is already present on the frontend, so it does not require any additional bridge traffic.) While profiling is active, each time React commits– the frontend also stores a copy of the "_operations_" message (described above). Once profiling has finished, the frontend can use the original snapshot along with each of the stored "_operations_" messages to reconstruct the tree for each of the profiled commits.
249
@@ -252,161 +252,16 @@ When profiling begins, the backend records the base durations of each fiber curr
252 * Which elements were rendered during that commit.
253 * Which interactions (if any) were part of the commit.
254
255 -This information is kept on the backend until requested by the frontend (as described below).
255 +This information will eventually be required by the frontend in order to render its profiling graphs, but it will not be sent across the bridge until profiling has completed (to minimize the performance impact of profiling).
256
257 <sup>1</sup> In the future, the backend may also store additional metadata (e.g. which props/states changed between rendered for a given component).
258
259 -### Profiling summary
259 +### Combining profiling data
260
261 -The profiling tab shows information for the currently-selected React root. When profiling completes (or when a new root is selected) the frontend first checks to see if there is any profiling data for the selected root. (Has it cached any "_operations_"?)
261 +Once profiling is finished, the frontend requests profiling data from the backend one renderer at a time by sending a "_getProfilingData_" message. The backend responds with a "_profilingData_" message that contains per-root commit timing and duration information. The frontend then combines this information with its own snapshots to form a complete picture of the profiling session. Using this data, charts and graphs are lazily computed (and incrementally cached) on demand, based on which commits and views are selected in the Profiler UI.
262
263 -If so, then it sends a "_getProfilingSummary_" message with an id that identifies the root. The backend then returns a "_profilingSummary_" message with the following information:
263 +### Importing/exporting data
264
265 -* root id (to match request and response)
266 -* number of interactions that were traced for this root
267 -* the commits (each consisting of a timestamp and duration) that were profiled for the root
268 -* tree base durations as of when profiling started
265 +Because all of the data is merged in the frontend after a profiling session is completed, it can be exported and imported (as JSON), enabling profiling sessions to be shared between users.
266
270 -This is the minimal information required to render the main ["commit selector"](https://reactjs.org/blog/2018/09/10/introducing-the-react-profiler.html#browsing-commits).
271 -
272 -Here is an example profile summary:
273 -```js
274 -{
275 - rootID: 1,
276 - interactionCount: 2,
277 -
278 - // Commit durations
279 - commitDurations: [
280 - 10, // first commit took 10ms
281 - 13, // second commit took 13ms
282 - 5, // third commit took 5ms
283 - ]
284 -
285 - // Commit times (relative to when profiling started)
286 - commitTimes: [
287 - 210, // first commit started 210ms after profiling began
288 - 284, // second commit started 284ms after profiling began
289 - 303, // third commit started 303ms after profiling began
290 - ],
291 -
292 - // Tuples of fiber id and initial tree base duration
293 - initialTreeBaseDurations: [
294 - 1, // fiber id
295 - 11, // tree base duration when profiling started
296 -
297 - 2, // fiber id
298 - 12, // tree base duration when profiling started
299 -
300 - 3, // fiber id
301 - 8, // tree base duration when profiling started
302 - ]
303 -]
304 -```
305 -
306 -Additional information (e.g. which components were part of a specific commit, which interactions were logged) are lazily requested by the frontend as a user interacts with the Profiler UI.
307 -
308 -### Commit details
309 -
310 -When a commit is selected in the profiling view, the frontend needs to reconstruct the tree at that point in time using the snapshot and the "_operations_" it has cached.
311 -
312 -In addition to this, it also needs to ask the backend for some additional information needed to display the ["flame chart"](https://reactjs.org/blog/2018/09/10/introducing-the-react-profiler.html#flame-chart) and ["ranked chart"](https://reactjs.org/blog/2018/09/10/introducing-the-react-profiler.html#ranked-chart) views. The frontend sends a "_profileCommitDetails_" message specifying which root and commit (index) it is interested in. The backend sends a response to fill in missing details about the commit:
313 -
314 -* root id and commit index (to match request and response)
315 -* which elements were rendered during the commit <sup>1</sup> and how long did they take
316 -* which interactions were part of the commit
317 -
318 -Here is an example commit in which two elements were rendered and one interaction was traced:
319 -
320 -```js
321 -{
322 - rootID: 1,
323 - commitIndex: 0,
324 - interactions: [
325 - {
326 - id: 8,
327 - timestamp: 4,
328 - name: "Foo"
329 - },
330 - {
331 - id: 11,
332 - timestamp: 4,
333 - name: "Bar"
334 - }
335 - ],
336 - nodes: [
337 - {
338 - id: 1,
339 - baseDuration: 15,
340 - actualDuration: 15
341 - },
342 - {
343 - id: 2,
344 - baseDuration: 11,
345 - actualDuration: 11
346 - }
347 - }
348 -}
349 -```
350 -
351 -<sup>1</sup> Elements in the tree that are not explicitly included in the above response were not rendered during the current commit.
352 -
353 -### Component commits
354 -
355 -When a particular component (fiber) is selected, the frontend polls the backend for the aggregate data required to render the ["component chart"](https://reactjs.org/blog/2018/09/10/introducing-the-react-profiler.html#component-chart) view. The frontend sends a "_profileComponentDetails_" message specifying which root and component (id) it is interested in. The backend sends a response that includes:
356 -
357 -* root and component ids (to match request and response)
358 -* which commits was the component rendered in and how long did each take
359 -
360 -Here is an example of a component that committed twice during a profiling session:
361 -
362 -```js
363 -{
364 - rootID: 1,
365 - id: 2,
366 -
367 - // Tuples of commit index and render duration (ms)
368 - commits: [
369 - 0, // index of first
370 - 11 // duration (ms)
371 -
372 - 2, // index of second commit
373 - 7 // duration (ms)
374 - ]
375 -}
376 -```
377 -
378 -### Interactions
379 -
380 -The [Interactions chart](https://reactjs.org/blog/2018/09/10/introducing-the-react-profiler.html#interactions) shows a time series for every interaction that was traced in the recent profiler session. The frontend sends a "_profileInteractions_" message specifying which root it would like interaction data for. The backend sends the following response:
381 -
382 -* root id (to match request and response)
383 -* interaction metadata
384 -
385 -Here is an example of a profiling session consisting of two interactions:
386 -
387 -```js
388 -{
389 - rootID: 1,
390 - interactions: [
391 - {
392 - id: 8,
393 - name: "Foo",
394 - timestamp: 4,
395 - commits: [
396 - 0, // index of first commit
397 - 2 // index of second commit
398 - ]
399 - },
400 - {
401 - id: 11,
402 - name: "Bar",
403 - timestamp: 4,
404 - commits: [
405 - 0 // index of first commit
406 - ]
407 - }
408 - ]
409 -}
410 -```
411 -
412 -The backend does not need to resend the timestamp for each of the commits because that was already sent as part of the "_profilingSummary_" message.
267 +At the moment, screenshots are not included in the exported data (to keep the export filesize small) but this could be changed in the future.
\ No newline at end of file