Skip to content

fix: Scope keydown event listener so that it is added to the FocusZone itself instead of the window#24175

Merged
khmakoto merged 3 commits intomicrosoft:masterfrom
khmakoto:scopeFocusZoneKeyDownCaptureEventListener
Aug 2, 2022
Merged

fix: Scope keydown event listener so that it is added to the FocusZone itself instead of the window#24175
khmakoto merged 3 commits intomicrosoft:masterfrom
khmakoto:scopeFocusZoneKeyDownCaptureEventListener

Conversation

@khmakoto
Copy link
Member

@khmakoto khmakoto commented Aug 1, 2022

Current Behavior

FocusZone currently attaches an event listener on keydown to the window, so that whenever the tab key is pressed all outer FocusZone's indexes are updated (an outer FocusZone is a FocusZone that is not within another one). This ensures tab indexes are always correct, but can cause a big performance dip since the keydown function is called even on elements that are not within FocusZones.

New Behavior

This PR fixes the issue described above by attaching the listeners to the FocusZone elements instead of the window. This means that there is the potential of more event listeners being on the page (one per outer FocusZone vs one for the window), but scopes the listeners to be called only when the event happens within one of these FocusZones. This has a performance benefit because indexes are now updated only in the scope of FocusZones, so tabbing on any element outside of them doesn't incur this cost. It is also safe because indexes shouldn't need to be updated if interacting with something outside of a FocusZone either way.

Related Issue(s)

Fixes #23785

A further improvement is left out of this PR but suggested in #24174.

@khmakoto khmakoto requested a review from a team as a code owner August 1, 2022 23:46
@khmakoto khmakoto self-assigned this Aug 1, 2022
@github-actions github-actions bot added this to the July Project Cycle Q3 2022 milestone Aug 1, 2022
@codesandbox-ci
Copy link

codesandbox-ci bot commented Aug 1, 2022

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 020c8ad:

Sandbox Source
@fluentui/react 8 starter Configuration
@fluentui/react-components 9 starter Configuration

@size-auditor
Copy link

size-auditor bot commented Aug 2, 2022

Asset size changes

Project Bundle Baseline Size New Size Difference
office-ui-fabric-react fluentui-react-SwatchColorPicker 179.44 kB 179.385 kB BelowBaseline     -55 bytes
office-ui-fabric-react fluentui-react-ShimmeredDetailsList 230.703 kB 230.648 kB BelowBaseline     -55 bytes
office-ui-fabric-react fluentui-react-TimePicker 225.391 kB 225.336 kB BelowBaseline     -55 bytes
office-ui-fabric-react fluentui-react-SearchBox 176.562 kB 176.507 kB BelowBaseline     -55 bytes
office-ui-fabric-react fluentui-react-SpinButton 180.461 kB 180.406 kB BelowBaseline     -55 bytes
office-ui-fabric-react fluentui-react-TeachingBubble 192.741 kB 192.686 kB BelowBaseline     -55 bytes
office-ui-fabric-react fluentui-react-Dropdown 219.929 kB 219.874 kB BelowBaseline     -55 bytes
office-ui-fabric-react fluentui-react-Rating 77.841 kB 77.786 kB BelowBaseline     -55 bytes
office-ui-fabric-react fluentui-react-Pivot 177.86 kB 177.805 kB BelowBaseline     -55 bytes
office-ui-fabric-react fluentui-react-ExtendedPicker 92.998 kB 92.943 kB BelowBaseline     -55 bytes
office-ui-fabric-react fluentui-react-Dialog 198.199 kB 198.144 kB BelowBaseline     -55 bytes
office-ui-fabric-react fluentui-react-Facepile 199.032 kB 198.977 kB BelowBaseline     -55 bytes
office-ui-fabric-react fluentui-react-DatePicker 175.025 kB 174.97 kB BelowBaseline     -55 bytes
office-ui-fabric-react fluentui-react-ContextualMenu 143.517 kB 143.462 kB BelowBaseline     -55 bytes
office-ui-fabric-react fluentui-react-CommandBar 190.053 kB 189.998 kB BelowBaseline     -55 bytes
office-ui-fabric-react fluentui-react-ComboBox 236.244 kB 236.189 kB BelowBaseline     -55 bytes
office-ui-fabric-react fluentui-react-FloatingPicker 229.278 kB 229.223 kB BelowBaseline     -55 bytes
office-ui-fabric-react fluentui-react-FocusZone 53.501 kB 53.446 kB BelowBaseline     -55 bytes
office-ui-fabric-react fluentui-react-Grid 169.748 kB 169.693 kB BelowBaseline     -55 bytes
office-ui-fabric-react fluentui-react-GroupedList 122.324 kB 122.269 kB BelowBaseline     -55 bytes
office-ui-fabric-react fluentui-react-Calendar 116.955 kB 116.9 kB BelowBaseline     -55 bytes
office-ui-fabric-react fluentui-react-ButtonGrid 169.748 kB 169.693 kB BelowBaseline     -55 bytes
office-ui-fabric-react fluentui-react-Button 183.81 kB 183.755 kB BelowBaseline     -55 bytes
office-ui-fabric-react fluentui-react-Breadcrumb 189.015 kB 188.96 kB BelowBaseline     -55 bytes
office-ui-fabric-react fluentui-react-MessageBar 177.604 kB 177.549 kB BelowBaseline     -55 bytes
office-ui-fabric-react fluentui-react-Nav 177.058 kB 177.003 kB BelowBaseline     -55 bytes
office-ui-fabric-react fluentui-react-Panel 188.035 kB 187.98 kB BelowBaseline     -55 bytes
office-ui-fabric-react fluentui-react-DocumentCard 204.333 kB 204.278 kB BelowBaseline     -55 bytes
office-ui-fabric-react fluentui-react-Pickers 275.857 kB 275.802 kB BelowBaseline     -55 bytes
office-ui-fabric-react fluentui-react-DetailsList 220.215 kB 220.16 kB BelowBaseline     -55 bytes
office-ui-fabric-react fluentui-react-SelectedItemsList 219.008 kB 218.952 kB BelowBaseline     -56 bytes
office-ui-fabric-react fluentui-react-WeeklyDayPicker 97.535 kB 97.479 kB BelowBaseline     -56 bytes

ExceedsTolerance Over Tolerance (1024 B) ExceedsBaseline Over Baseline BelowBaseline Below Baseline New New Deleted  Removed 1 kB = 1000 B

Baseline commit: 9100e12e984aaa523b996be5ab11db0ec687b497 (build)

@fabricteam
Copy link
Collaborator

fabricteam commented Aug 2, 2022

📊 Bundle size report

🤖 This report was generated against 9100e12e984aaa523b996be5ab11db0ec687b497

Copy link
Contributor

@jspurlin jspurlin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@fabricteam
Copy link
Collaborator

fabricteam commented Aug 2, 2022

Perf Analysis (@fluentui/react)

No significant results to display.

All results

Scenario Render type Master Ticks PR Ticks Iterations Status
BaseButton mount 784 795 5000
Breadcrumb mount 2244 2276 1000
Checkbox mount 2231 2239 5000
CheckboxBase mount 1964 1973 5000
ChoiceGroup mount 3933 3957 5000
ComboBox mount 770 841 1000
CommandBar mount 8890 8821 1000
ContextualMenu mount 9289 9289 1000
DefaultButton mount 963 957 5000
DetailsRow mount 3052 3032 5000
DetailsRowFast mount 3063 3036 5000
DetailsRowNoStyles mount 2884 2923 5000
Dialog mount 2288 2255 1000
DocumentCardTitle mount 158 152 1000
Dropdown mount 2798 2808 5000
FocusTrapZone mount 1548 1566 5000
FocusZone mount 1483 1518 5000
IconButton mount 1411 1414 5000
Label mount 333 317 5000
Layer mount 2689 2687 5000
Link mount 438 448 5000
MenuButton mount 1217 1230 5000
MessageBar mount 1838 1848 5000
Nav mount 2641 2625 1000
OverflowSet mount 951 995 5000
Panel mount 1778 1827 1000
Persona mount 853 836 1000
Pivot mount 1143 1137 1000
PrimaryButton mount 1083 1082 5000
Rating mount 6599 6631 5000
SearchBox mount 1108 1120 5000
Shimmer mount 2176 2219 5000
Slider mount 1688 1699 5000
SpinButton mount 3949 3943 5000
Spinner mount 400 391 5000
SplitButton mount 2514 2527 5000
Stack mount 468 479 5000
StackWithIntrinsicChildren mount 1891 1875 5000
StackWithTextChildren mount 4662 4681 5000
SwatchColorPicker mount 9074 8967 5000
TagPicker mount 1995 2019 5000
TeachingBubble mount 73132 71880 5000
Text mount 406 395 5000
TextField mount 1179 1191 5000
ThemeProvider mount 962 966 5000
ThemeProvider virtual-rerender 640 629 5000
ThemeProvider virtual-rerender-with-unmount 1396 1382 5000
Toggle mount 732 722 5000
buttonNative mount 104 101 5000

Comment on lines 6 to 8
// HEADS UP: this test is intentionally in a separate file aside from the rest of FocusZone tests
// As it is testing ref counting on a global `window` object it would interfere with other FocusZone tests
// which use ReactTestUtils.renderIntoDocument() which renders FocusZone into a detached DOM node and never unmounts.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment appears to no longer be correct. Can it be updated or deleted?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, I've just deleted it.

@khmakoto khmakoto enabled auto-merge (squash) August 2, 2022 16:27
@khmakoto khmakoto merged commit cf05f80 into microsoft:master Aug 2, 2022
@khmakoto khmakoto deleted the scopeFocusZoneKeyDownCaptureEventListener branch August 2, 2022 17:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: FocusZone triggers FocusZone._onKeyDownCapture on every pressing "tab" event (even outside fluent components)

4 participants