Files
react-native/ReactCommon/react/renderer/core/EventQueueProcessor.cpp
T
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

91 lines
2.4 KiB
C++

/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include <cxxreact/JSExecutor.h>
#include "EventEmitter.h"
#include "EventLogger.h"
#include "EventQueue.h"
#include "ShadowNodeFamily.h"
namespace facebook::react {
EventQueueProcessor::EventQueueProcessor(
EventPipe eventPipe,
StatePipe statePipe)
: eventPipe_(std::move(eventPipe)), statePipe_(std::move(statePipe)) {}
void EventQueueProcessor::flushEvents(
jsi::Runtime &runtime,
std::vector<RawEvent> &&events) const {
{
std::lock_guard<std::mutex> lock(EventEmitter::DispatchMutex());
for (const auto &event : events) {
if (event.eventTarget) {
event.eventTarget->retain(runtime);
}
}
}
for (auto const &event : events) {
if (event.category == RawEvent::Category::ContinuousEnd) {
hasContinuousEventStarted_ = false;
}
auto reactPriority = hasContinuousEventStarted_
? ReactEventPriority::Default
: ReactEventPriority::Discrete;
if (event.category == RawEvent::Category::Continuous) {
reactPriority = ReactEventPriority::Default;
}
if (event.category == RawEvent::Category::Discrete) {
reactPriority = ReactEventPriority::Discrete;
}
auto eventLogger = getEventLogger();
if (eventLogger != nullptr) {
eventLogger->onEventDispatch(event.loggingTag);
}
eventPipe_(
runtime,
event.eventTarget.get(),
event.type,
reactPriority,
event.payloadFactory);
if (eventLogger != nullptr) {
eventLogger->onEventEnd(event.loggingTag);
}
if (event.category == RawEvent::Category::ContinuousStart) {
hasContinuousEventStarted_ = true;
}
}
// No need to lock `EventEmitter::DispatchMutex()` here.
// The mutex protects from a situation when the `instanceHandle` can be
// deallocated during accessing, but that's impossible at this point because
// we have a strong pointer to it.
for (const auto &event : events) {
if (event.eventTarget) {
event.eventTarget->release(runtime);
}
}
}
void EventQueueProcessor::flushStateUpdates(
std::vector<StateUpdate> &&states) const {
for (const auto &stateUpdate : states) {
statePipe_(stateUpdate);
}
}
} // namespace facebook::react