Bug 234928

Summary: Don't dispatch "focusin" / "focusout" events if there are no listeners
Product: WebKit Reporter: Alexey Shvayka <ashvayka>
Component: DOMAssignee: Alexey Shvayka <ashvayka>
Status: RESOLVED FIXED    
Severity: Normal CC: cdumez, cmarcelo, darin, esprehn+autocc, ews-watchlist, ggaren, hi, kangil.han, pangle, webkit-bug-importer
Priority: P2 Keywords: InRadar
Version: WebKit Nightly Build   
Hardware: All   
OS: All   
Bug Depends on: 234978    
Bug Blocks:    
Attachments:
Description Flags
Patch
none
Microbenchmark
none
Patch for landing none

Description Alexey Shvayka 2022-01-06 11:44:43 PST
Don't dispatch "focusin" / "focusout" events if there are no listeners, and drop their obsolete variants
Comment 1 Alexey Shvayka 2022-01-06 11:47:45 PST
Created attachment 448517 [details]
Patch
Comment 2 Alexey Shvayka 2022-01-06 11:49:36 PST
Created attachment 448518 [details]
Microbenchmark

r287686: 599.7ms
patch: 563.7ms (6% faster)
(50 runs)
Comment 3 Geoffrey Garen 2022-01-06 12:14:18 PST
Comment on attachment 448517 [details]
Patch

r=me
Comment 4 Darin Adler 2022-01-06 16:18:59 PST
Comment on attachment 448517 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=448517&action=review

> Source/WebCore/ChangeLog:13
> +          a) Avoids creating and dispatching "focusin" / "focusout" events if it's
> +             guaranteed there are no registered listeners for them. These events are
> +             rather new and not widely popular: according to Chrome stats, only 16%
> +             page loads use them [1], which is even less than `document.all`.

More than 1 out of 7 webpages listens for these events?

That sounds pretty popular to me!

But I guess a small optimization for those other pages is still good.

> Source/WebCore/dom/Element.h:569
> +    void dispatchFocusInEventIfNeeded(RefPtr<Element>&& oldFocusedElement);
> +    void dispatchFocusOutEventIfNeeded(RefPtr<Element>&& newFocusedElement);

I don’t understand why these functions take RefPtr<Element>&&, given that all callers always call copyRef; we’re not using the rvalue reference to optimize anything. The arguments should just be Element*, and the RefPtr can be inside the function.

For some reason that pattern is popular here, but I don’t get it.
Comment 5 Alexey Shvayka 2022-01-07 14:00:21 PST
(In reply to Geoffrey Garen from comment #3)
> Comment on attachment 448517 [details]
> Patch
> 
> r=me

Thanks Geoff!

(In reply to Darin Adler from comment #4)
> More than 1 out of 7 webpages listens for these events?
> 
> That sounds pretty popular to me!
> 
> But I guess a small optimization for those other pages is still good.

Yeah, 17% is kinda a lot in comparison with most other events in ListenerType, yet focus() currently is relatively slow while being heavily used in some Speedometer2 subtests (but not this path that emits events), hence this patch.

> > Source/WebCore/dom/Element.h:569
> > +    void dispatchFocusInEventIfNeeded(RefPtr<Element>&& oldFocusedElement);
> > +    void dispatchFocusOutEventIfNeeded(RefPtr<Element>&& newFocusedElement);
> 
> I don’t understand why these functions take RefPtr<Element>&&, given that
> all callers always call copyRef; we’re not using the rvalue reference to
> optimize anything. The arguments should just be Element*, and the RefPtr can
> be inside the function.

Since dispatchFocusEvent() / dispatchBlurEvent() have the same signature and their callers also call copyRef(), I will leave a FIXME for this to avoid bloating this patch.

Also, recalling your feedback on another change, I'm landing this patch in two changes: https://bugs.webkit.org/show_bug.cgi?id=234978 removes the obsolete events, while this one adds the optimisation for "focusin" / "focusout" events.

While this adds a bit of churn (especially if we would have to revert, which I doubt), it makes obvious what LayoutTests changes are related to, and makes the conditional dispatch optimization easier to follow as a separate commit.
Comment 6 Alexey Shvayka 2022-01-07 17:23:04 PST
Created attachment 448649 [details]
Patch for landing
Comment 7 EWS 2022-01-07 18:14:55 PST
Committed r287802 (245855@main): <https://commits.webkit.org/245855@main>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 448649 [details].
Comment 8 Radar WebKit Bug Importer 2022-01-07 18:15:20 PST
<rdar://problem/87282027>