Commit Graph

10 Commits

Author SHA1 Message Date
Ruslan Shestopalyuk 21dbc67c03 Use a more robust method of finding out which events to report
Summary:
[Changelog][Internal]

Use the [list of supported events](https://www.w3.org/TR/event-timing/#sec-events-exposed) explicitly to both filter and transform reported event types, which makes this both more robust and less ambiguous.

The mapping is using a compile-time hash/lookup, similarly to how we do it with the ViewProps in the RN core.

Reviewed By: rubennorte

Differential Revision: D42342655

fbshipit-source-id: 3d0b2465fd5611db110c4792913e0a92e76cd067
2023-01-04 08:57:40 -08:00
Ruslan Shestopalyuk 3aea05651d Remove "first-input" event type from Event Timing API logging implementation (#35771)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/35771

[Changelog][Internal]
Based on the internal discussion, we don't want to report `first-input` event types for RN (just use plain `event` instead), in the way that [Event Timing API standard suggests](https://www.w3.org/TR/event-timing), as this is doesn't have that clear semantics in the context of RN, also to keep it simpler.

Reviewed By: rubennorte

Differential Revision: D42341923

fbshipit-source-id: eff2487dee17ef082604e4c807b4d41485328114
2023-01-04 08:29:15 -08:00
Ruslan Shestopalyuk 09ad0cc0c6 Implement reporting of events from native side to WebPerformance API (#35768)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/35768

Changelog: [Internal]

This implements native side mechanics for reporting user events timing to JS  (PerformanceObserver API).

See the standard for more details: https://www.w3.org/TR/event-timing/

The events are only logged when there are any active subscriptions (via `PerformanceObserver.observe`), also we only log "discrete events" (i.e. no likes of mouse move), so the overhead is non-existing.

There are two main metrics of interest for an event lifecycle:
* Time the event is spent in the queue, i.e. the time between it's created and dispatched
* Time that is spend in the event handler on the JS side (event dispatch), or processing time

Both of these are measured, and the corresponding fields are populated.

Reviewed By: sammy-SC

Differential Revision: D42294947

fbshipit-source-id: 4fd7938c04b942400befa4057d4929fb2763cee1
2023-01-03 11:11:37 -08:00
Ruslan Shestopalyuk 4eecab3a76 API to report events
Summary:
Extends the WebPerformance API with ability to report events, [according to the standard](https://www.w3.org/TR/event-timing/#sec-performance-event-timing).

This is an API-only change, the actual reporting comes in a separate diff, to simplify reviewing.

Changelog: [Internal]

Reviewed By: christophpurrer

Differential Revision: D42097695

fbshipit-source-id: d8b468ffed50c1c3d889151df5e8ca644d6e1a68
2022-12-16 11:45:06 -08:00
Ruslan Shestopalyuk d09c5fd7a9 Limit perf entry buffer size and send back 'droppedEntriesCount' to PerformanceObserver callback
Summary:
Prevents scenarios when internal performance buffer may grow indefinitely (e.g. due to a broken logging), communicating back to `PerformanceObserver` the corresponding amount of dropped entries, `droppedEntriesCount`, [according to the standard](https://w3c.github.io/performance-timeline/#dom-performanceobservercallbackoptions-droppedentriescount).

NOTE: The backwards compatibility check is failing, which is an orthogonal issue. I am looking into it and won't land this one before it is sorted.

Changelog: [Internal]

Reviewed By: christophpurrer

Differential Revision: D42008409

fbshipit-source-id: 40d30e44d39e643bfb58a6254572823cb2b3b8df
2022-12-16 11:45:06 -08:00
Ruslan Shestopalyuk 41c17ddd56 Batch/throttle reporting of the performance entries
Summary:
Makes sure that we don't spam too often the JS performance entry reporting callback, which further dispatches entries to `PerformanceObserver` instances.

The logic is as following:
* ~~~If internal buffer of entries reaches the limit, we schedule the callback (with background priority)~~~
*~~~ Once the callback is processed, we schedule the next flush after a timeout of 500ms, this will also be scheduled from native with background priority~~~
* ~~~Whenever new performance type starts to be observed, we also schedule the callback, in order to prime the above~~~
* Schedule the flush with low priority, whenever there is the first entry coming into an empty buffer, and rely on the Scheduler to "do the right thing" when asked to flush it with background priority and not doo it exceedingly often (see the prolonged discussion)

Changelog: [internal]

Reviewed By: rubennorte

Differential Revision: D41875085

fbshipit-source-id: 368b525203215350ceabb43d5e9e8e3bd5242aca
2022-12-12 04:53:31 -08:00
Ruslan Shestopalyuk 62a28e4bdb Native side implementation for Performance.measure()
Summary:
Changelog: [Internal]

This implements the C++ side logic of handling `Performance.measure` calls.

Since measures may refer to earlier logged marks by name, we need to keep track of the former. I also use a fixed size (circular) buffer to prevent the marks from piling forever.

Also adds implementation of clearing marks/measures, as per standard.

Reviewed By: mdvacca

Differential Revision: D41756928

fbshipit-source-id: 19dce28d6af4c5646274e6d5db20b41869282780
2022-12-06 17:34:24 -08:00
Ruslan Shestopalyuk cb552f62f2 Create NativePerformance C++ module
Summary:
[Changelog][Internal]

The NativePerformance module functionality corresponds to the [timing extensions of the Performance API standard interface](https://www.w3.org/TR/user-timing/#extensions-performance-interface).

As this is logically separate from `PerformanceObserver` (which may exist without it), it makes sense to have it as a different native module, so there is no coupling between both.

Reviewed By: christophpurrer

Differential Revision: D41690145

fbshipit-source-id: 7443f4c51f54cc2fdddbdb2e89f9a1fa457ab280
2022-12-03 08:32:58 -08:00
Ruslan Shestopalyuk 862a99c491 Use NativePerformanceObserver.popPendingEntries instead of getPendingEntries
Summary:
[Changelog][Internal]

The name corresponds more precisely to what the method does.

Reviewed By: christophpurrer

Differential Revision: D41686205

fbshipit-source-id: 36c47b57fdeb757515cd14b890f38247f7fe8d02
2022-12-02 17:23:58 -08:00
Ruslan Shestopalyuk 14e69db482 Implement native logic for performance event reporting (#35526)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/35526

[Changelog][Internal]

This closes the full loop according to the [technical design](https://fb.quip.com/MdqgAk1Eb2dV) of the WebPerf API implementation, with the main components and the working central data flow in place.

The next step is to add some buffering/throttling, as in this diff we just spawn an idle-priority task after every performance entry coming (even though they still naturally do come in batches, because they manage to accumulate before the task is executed).

Reviewed By: christophpurrer

Differential Revision: D41496082

fbshipit-source-id: 5fd4cf22e75806f7bc98d1d1b6691596ccadf8b9
2022-12-01 09:49:44 -08:00