Skip to content

Commit 21dbc67

Browse files
rshestfacebook-github-bot
authored andcommitted
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
1 parent 3aea056 commit 21dbc67

File tree

2 files changed

+75
-18
lines changed

2 files changed

+75
-18
lines changed

Libraries/WebPerformance/PerformanceEntryReporter.cpp

+73-16
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#include <react/renderer/core/EventLogger.h>
1111
#include "NativePerformanceObserver.h"
1212

13-
#include <algorithm>
13+
#include <unordered_map>
1414

1515
// All the unflushed entries beyond this amount will get discarded, with
1616
// the amount of discarded ones sent back to the observers' callbacks as
@@ -167,14 +167,14 @@ double PerformanceEntryReporter::getMarkTime(
167167
}
168168

169169
void PerformanceEntryReporter::event(
170-
const std::string &name,
170+
std::string name,
171171
double startTime,
172172
double duration,
173173
double processingStart,
174174
double processingEnd,
175175
uint32_t interactionId) {
176176
logEntry(
177-
{name,
177+
{std::move(name),
178178
static_cast<int>(PerformanceEntryType::EVENT),
179179
startTime,
180180
duration,
@@ -203,31 +203,89 @@ void PerformanceEntryReporter::scheduleFlushBuffer() {
203203
}
204204
}
205205

206-
static bool isDiscreteEvent(const char *name) {
207-
return !std::strstr(name, "Move") && !std::strstr(name, "Layout");
208-
}
206+
struct StrKey {
207+
uint32_t key;
208+
constexpr StrKey(const char *s)
209+
: key(folly::hash::fnv32_buf(s, std::strlen(s))) {}
210+
211+
constexpr bool operator==(const StrKey &rhs) const {
212+
return key == rhs.key;
213+
}
214+
};
215+
216+
struct StrKeyHash {
217+
constexpr size_t operator()(const StrKey &strKey) const {
218+
return static_cast<size_t>(strKey.key);
219+
}
220+
};
221+
222+
// Supported events for reporting, see
223+
// https://www.w3.org/TR/event-timing/#sec-events-exposed
224+
// Not all of these are currently supported by RN, but we map them anyway for
225+
// future-proofing.
226+
static const std::unordered_map<StrKey, const char *, StrKeyHash>
227+
SUPPORTED_EVENTS = {
228+
{"topAuxClick", "auxclick"},
229+
{"topClick", "click"},
230+
{"topContextMenu", "contextmenu"},
231+
{"topDblClick", "dblclick"},
232+
{"topMouseDown", "mousedown"},
233+
{"topMouseEnter", "mouseenter"},
234+
{"topMouseLeave", "mouseleave"},
235+
{"topMouseOut", "mouseout"},
236+
{"topMouseOver", "mouseover"},
237+
{"topMouseUp", "mouseup"},
238+
{"topPointerOver", "pointerover"},
239+
{"topPointerEnter", "pointerenter"},
240+
{"topPointerDown", "pointerdown"},
241+
{"topPointerUp", "pointerup"},
242+
{"topPointerCancel", "pointercancel"},
243+
{"topPointerOut", "pointerout"},
244+
{"topPointerLeave", "pointerleave"},
245+
{"topGotPointerCapture", "gotpointercapture"},
246+
{"topLostPointerCapture", "lostpointercapture"},
247+
{"topTouchStart", "touchstart"},
248+
{"topTouchEnd", "touchend"},
249+
{"topTouchCancel", "touchcancel"},
250+
{"topKeyDown", "keydown"},
251+
{"topKeyPress", "keypress"},
252+
{"topKeyUp", "keyup"},
253+
{"topBeforeInput", "beforeinput"},
254+
{"topInput", "input"},
255+
{"topCompositionStart", "compositionstart"},
256+
{"topCompositionUpdate", "compositionupdate"},
257+
{"topCompositionEnd", "compositionend"},
258+
{"topDragStart", "dragstart"},
259+
{"topDragEnd", "dragend"},
260+
{"topDragEnter", "dragenter"},
261+
{"topDragLeave", "dragleave"},
262+
{"topDragOver", "dragover"},
263+
{"topDrop", "drop"},
264+
};
209265

210266
EventTag PerformanceEntryReporter::onEventStart(const char *name) {
211-
if (!isReportingEvents() || !isDiscreteEvent(name)) {
267+
if (!isReportingEvents()) {
212268
return 0;
213269
}
214270

271+
auto it = SUPPORTED_EVENTS.find(name);
272+
if (it == SUPPORTED_EVENTS.end()) {
273+
return 0;
274+
}
275+
276+
const char *reportedName = it->second;
277+
215278
sCurrentEventTag_++;
216279
if (sCurrentEventTag_ == 0) {
217280
// The tag wrapped around (which is highly unlikely, but still)
218281
sCurrentEventTag_ = 1;
219282
}
220283

221-
if (std::strstr(name, "top") == name) {
222-
// Skip the "top" prefix if present
223-
name += 3;
224-
}
225-
226284
auto timeStamp = JSExecutor::performanceNow();
227285
{
228286
std::lock_guard<std::mutex> lock(eventsInFlightMutex_);
229-
eventsInFlight_.emplace(
230-
std::make_pair(sCurrentEventTag_, EventEntry{name, timeStamp, 0.0}));
287+
eventsInFlight_.emplace(std::make_pair(
288+
sCurrentEventTag_, EventEntry{reportedName, timeStamp, 0.0}));
231289
}
232290
return sCurrentEventTag_;
233291
}
@@ -259,13 +317,12 @@ void PerformanceEntryReporter::onEventEnd(EventTag tag) {
259317
}
260318
auto &entry = it->second;
261319
auto &name = entry.name;
262-
std::transform(name.begin(), name.end(), name.begin(), ::tolower);
263320

264321
// TODO: Define the way to assign interaction IDs to the event chains
265322
// (T141358175)
266323
const uint32_t interactionId = 0;
267324
event(
268-
std::move(name),
325+
name,
269326
entry.startTime,
270327
timeStamp - entry.startTime,
271328
entry.dispatchTime,

Libraries/WebPerformance/PerformanceEntryReporter.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ class PerformanceEntryReporter : public EventLogger {
9191
void clearMeasures(const std::optional<std::string> &measureName);
9292

9393
void event(
94-
const std::string &name,
94+
std::string name,
9595
double startTime,
9696
double duration,
9797
double processingStart,
@@ -125,7 +125,7 @@ class PerformanceEntryReporter : public EventLogger {
125125
uint32_t droppedEntryCount_{0};
126126

127127
struct EventEntry {
128-
std::string name;
128+
const char *name;
129129
double startTime{0.0};
130130
double dispatchTime{0.0};
131131
};

0 commit comments

Comments
 (0)