Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stress Test: add random tree #24896

Merged
merged 3 commits into from
Sep 22, 2022
Merged

Conversation

spmonahan
Copy link
Contributor

Current Behavior

Test cases are simple benchmarks.

New Behavior

This PR adds code for generating and rendering deep and broad DOM trees allowing us to better simulate a real application with a benchmarking tool.

Note: tree generation is "random" but done with a seedable RNG for repeatable results.

The core of this is RandomTree a class for generating trees with random breadth and depth. This class is generic with an API for generating specific trees. This PR adds a "selector tree" which builds of RandomTree to generate a tree with many selectors (CSS classes, data attributes, etc) as well as generate the selectors themselves.

RandomTree is UI library agnostic and can be used to generate trees for React, Web Components, vanilla DOM or any other library we care to investigate.

Building off RandomTree this PR adds three library-specific tree implementations. One for React, one for (vanilla) Web Components and one for vanilla DOM.

Related Issue(s)

This PR is a foundational piece taken from #24799 (that other PR was far too large).

@codesandbox-ci
Copy link

codesandbox-ci bot commented Sep 21, 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 d2431ef:

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

@fabricteam
Copy link
Collaborator

fabricteam commented Sep 21, 2022

Perf Analysis (@fluentui/react-components)

No significant results to display.

All results

Scenario Render type Master Ticks PR Ticks Iterations Status
Avatar mount 1505 1486 5000
Button mount 1126 1102 5000
FluentProvider mount 1825 1782 5000
FluentProviderWithTheme mount 712 714 10
FluentProviderWithTheme virtual-rerender 673 672 10
FluentProviderWithTheme virtual-rerender-with-unmount 713 717 10
MakeStyles mount 2155 2176 50000
SpinButton mount 2913 2871 5000

@size-auditor
Copy link

size-auditor bot commented Sep 21, 2022

Asset size changes

Size Auditor did not detect a change in bundle size for any component!

Baseline commit: 483f160617f1037e672fe74b8e52abfee9378517 (build)

@fabricteam
Copy link
Collaborator

fabricteam commented Sep 21, 2022

📊 Bundle size report

Unchanged fixtures
Package & Exports Size (minified/GZIP)
global-context
createContext
533 B
341 B
global-context
createContextSelector
554 B
348 B
priority-overflow
createOverflowManager
2.936 kB
1.212 kB
react-accordion
Accordion (including children components)
78.914 kB
24.06 kB
react-alert
Alert
83.511 kB
20.921 kB
react-avatar
Avatar
48.381 kB
13.696 kB
react-avatar
AvatarGroup
14.95 kB
5.989 kB
react-avatar
AvatarGroupItem
68.349 kB
19.039 kB
react-badge
Badge
22.6 kB
7.205 kB
react-badge
CounterBadge
23.503 kB
7.497 kB
react-badge
PresenceBadge
24.05 kB
7.067 kB
react-button
Button
36.119 kB
9.647 kB
react-button
CompoundButton
43.144 kB
10.86 kB
react-button
MenuButton
38.813 kB
10.551 kB
react-button
SplitButton
46.228 kB
11.933 kB
react-button
ToggleButton
51.888 kB
11.127 kB
react-card
Card - All
67.002 kB
19.261 kB
react-card
Card
62.684 kB
18.177 kB
react-card
CardFooter
8.561 kB
3.601 kB
react-card
CardHeader
9.604 kB
3.94 kB
react-card
CardPreview
8.662 kB
3.656 kB
react-combobox
Combobox (including child components)
74.636 kB
24.186 kB
react-combobox
Dropdown (including child components)
74.236 kB
24.086 kB
react-components
react-components: Accordion, Button, FluentProvider, Image, Menu, Popover
188.672 kB
52.359 kB
react-components
react-components: FluentProvider & webLightTheme
33.394 kB
11.007 kB
react-dialog
Dialog (including children components)
82.755 kB
24.581 kB
react-divider
Divider
16.459 kB
5.902 kB
react-image
Image
10.78 kB
4.264 kB
react-input
Input
23.757 kB
7.704 kB
react-label
Label
9.338 kB
3.86 kB
react-link
Link
11.784 kB
4.867 kB
react-menu
Menu (including children components)
116.572 kB
35.778 kB
react-menu
Menu (including selectable components)
119.641 kB
36.297 kB
react-overflow
hooks only
10.685 kB
4.104 kB
react-popover
Popover
102.963 kB
31.553 kB
react-portal
Portal
10.576 kB
3.875 kB
react-portal-compat
PortalCompatProvider
5.851 kB
1.964 kB
react-positioning
usePositioning
19.7 kB
7.404 kB
react-provider
FluentProvider
15.755 kB
5.883 kB
react-radio
Radio
35.56 kB
11.929 kB
react-radio
RadioGroup
14.248 kB
5.7 kB
react-select
Select
20.846 kB
7.346 kB
react-slider
Slider
31.526 kB
10.046 kB
react-spinbutton
SpinButton
44.102 kB
12.425 kB
react-spinner
Spinner
19.977 kB
6.438 kB
react-switch
Switch
32.097 kB
10.27 kB
react-text
Text - Default
11.782 kB
4.605 kB
react-text
Text - Wrappers
15.092 kB
5.044 kB
react-textarea
Textarea
25.013 kB
8.133 kB
react-theme
Single theme token import
69 B
89 B
react-theme
Teams: all themes
29.65 kB
6.444 kB
react-theme
Teams: Light theme
17.486 kB
5.057 kB
react-tooltip
Tooltip
41.535 kB
14.639 kB
react-utilities
SSRProvider
180 B
159 B
🤖 This report was generated against 483f160617f1037e672fe74b8e52abfee9378517

@fabricteam
Copy link
Collaborator

fabricteam commented Sep 21, 2022

Perf Analysis (@fluentui/react-northstar)

Perf tests with no regressions
Scenario Current PR Ticks Baseline Ticks Ratio
AccordionMinimalPerf.default 117 110 1.06:1
ImageMinimalPerf.default 320 303 1.06:1
AlertMinimalPerf.default 227 216 1.05:1
FormMinimalPerf.default 320 304 1.05:1
SkeletonMinimalPerf.default 292 278 1.05:1
HeaderMinimalPerf.default 299 288 1.04:1
LayoutMinimalPerf.default 292 282 1.04:1
CardMinimalPerf.default 438 424 1.03:1
LabelMinimalPerf.default 312 304 1.03:1
ListCommonPerf.default 526 512 1.03:1
ReactionMinimalPerf.default 304 294 1.03:1
IconMinimalPerf.default 546 529 1.03:1
TableMinimalPerf.default 332 323 1.03:1
TextAreaMinimalPerf.default 394 383 1.03:1
AvatarMinimalPerf.default 150 147 1.02:1
RosterPerf.default 1794 1759 1.02:1
PopupMinimalPerf.default 532 522 1.02:1
ProviderMinimalPerf.default 338 330 1.02:1
SplitButtonMinimalPerf.default 3656 3599 1.02:1
AnimationMinimalPerf.default 445 440 1.01:1
BoxMinimalPerf.default 280 276 1.01:1
CheckboxMinimalPerf.default 1726 1706 1.01:1
DatepickerMinimalPerf.default 4807 4779 1.01:1
DialogMinimalPerf.default 639 635 1.01:1
EmbedMinimalPerf.default 3026 2997 1.01:1
ListMinimalPerf.default 419 415 1.01:1
MenuMinimalPerf.default 702 692 1.01:1
MenuButtonMinimalPerf.default 1405 1386 1.01:1
PortalMinimalPerf.default 138 136 1.01:1
RadioGroupMinimalPerf.default 360 358 1.01:1
StatusMinimalPerf.default 552 546 1.01:1
TableManyItemsPerf.default 1555 1542 1.01:1
TextMinimalPerf.default 281 279 1.01:1
TreeMinimalPerf.default 670 661 1.01:1
AttachmentMinimalPerf.default 121 121 1:1
ButtonOverridesMissPerf.default 1085 1080 1:1
CarouselMinimalPerf.default 379 378 1:1
DropdownMinimalPerf.default 2233 2234 1:1
HeaderSlotsPerf.default 624 626 1:1
InputMinimalPerf.default 936 937 1:1
LoaderMinimalPerf.default 544 542 1:1
ProviderMergeThemesPerf.default 1062 1059 1:1
SegmentMinimalPerf.default 276 277 1:1
SliderMinimalPerf.default 1331 1326 1:1
CustomToolbarPrototype.default 2237 2236 1:1
TreeWith60ListItems.default 135 135 1:1
VideoMinimalPerf.default 596 595 1:1
ButtonSlotsPerf.default 447 452 0.99:1
ChatDuplicateMessagesPerf.default 231 233 0.99:1
DividerMinimalPerf.default 287 290 0.99:1
DropdownManyItemsPerf.default 544 548 0.99:1
GridMinimalPerf.default 269 271 0.99:1
ItemLayoutMinimalPerf.default 955 964 0.99:1
ListNestedPerf.default 447 450 0.99:1
ToolbarMinimalPerf.default 758 767 0.99:1
TooltipMinimalPerf.default 1947 1966 0.99:1
ChatMinimalPerf.default 595 606 0.98:1
ChatWithPopoverPerf.default 304 309 0.98:1
ListWith60ListItems.default 513 522 0.98:1
RefMinimalPerf.default 171 177 0.97:1
AttachmentSlotsPerf.default 865 897 0.96:1
FlexMinimalPerf.default 222 232 0.96:1
ButtonMinimalPerf.default 126 133 0.95:1

@fabricteam
Copy link
Collaborator

fabricteam commented Sep 21, 2022

Perf Analysis (@fluentui/react)

No significant results to display.

All results

Scenario Render type Master Ticks PR Ticks Iterations Status
BaseButton mount 1204 1213 5000
Breadcrumb mount 2778 2823 1000
Checkbox mount 2619 2656 5000
CheckboxBase mount 2387 2370 5000
ChoiceGroup mount 4231 4311 5000
ComboBox mount 1188 1190 1000
CommandBar mount 9339 9322 1000
ContextualMenu mount 10418 10594 1000
DefaultButton mount 1358 1356 5000
DetailsRow mount 3367 3389 5000
DetailsRowFast mount 3386 3375 5000
DetailsRowNoStyles mount 3242 3290 5000
Dialog mount 2947 2989 1000
DocumentCardTitle mount 583 593 1000
Dropdown mount 3182 3161 5000
FocusTrapZone mount 1980 1955 5000
FocusZone mount 1947 1900 5000
GroupedList mount 48671 55056 2
GroupedList virtual-rerender 23479 23162 2
GroupedList virtual-rerender-with-unmount 83155 83107 2
GroupedListV2 mount 569 562 2
GroupedListV2 virtual-rerender 525 530 2
GroupedListV2 virtual-rerender-with-unmount 545 547 2
IconButton mount 1822 1801 5000
Label mount 753 748 5000
Layer mount 4104 4113 5000
Link mount 865 859 5000
MenuButton mount 1601 1613 5000
MessageBar mount 2345 2345 5000
Nav mount 3066 3079 1000
OverflowSet mount 1422 1395 5000
Panel mount 2472 2479 1000
Persona mount 1255 1277 1000
Pivot mount 1512 1542 1000
PrimaryButton mount 1470 1486 5000
Rating mount 6914 6990 5000
SearchBox mount 1489 1512 5000
Shimmer mount 2936 3005 5000
Slider mount 2080 2107 5000
SpinButton mount 4257 4275 5000
Spinner mount 839 827 5000
SplitButton mount 2874 2871 5000
Stack mount 887 892 5000
StackWithIntrinsicChildren mount 2265 2266 5000
StackWithTextChildren mount 4936 4963 5000
SwatchColorPicker mount 9448 9498 5000
TagPicker mount 2360 2364 5000
TeachingBubble mount 76488 75534 5000
Text mount 834 831 5000
TextField mount 1558 1560 5000
ThemeProvider mount 1435 1445 5000
ThemeProvider virtual-rerender 1143 1142 5000
ThemeProvider virtual-rerender-with-unmount 1993 2007 5000
Toggle mount 1149 1141 5000
buttonNative mount 536 526 5000

Copy link
Contributor

@behowell behowell left a comment

Choose a reason for hiding this comment

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

Looks good in general, except there are several very large files under src/fixtures. Is it necessary to add them to the repo? Can they just be randomly generated as needed instead?

apps/stress-test/src/shared/vanilla/VanillaTree.ts Outdated Show resolved Hide resolved
apps/stress-test/src/shared/wc/WCTree.ts Outdated Show resolved Hide resolved
@spmonahan
Copy link
Contributor Author

Looks good in general, except there are several very large files under src/fixtures. Is it necessary to add them to the repo? Can they just be randomly generated as needed instead?

Initially I had them generated on demand and since they all the randomness uses random-seedable under the hood the results are deterministic. However, when demoing this for some folks the consensus feedback was to add these fixtures to ensure we always used the same trees.

I was on the fence about following through on the change but I tested it out and while we now have these large fixture files in the repo the tests themselves run noticeably faster as they aren't re-computing the same tree over and over and just loading it instead. The tests already tend to be slow as they are run many times against many browsers so cutting down on test run time is nice.

I think we should keep the fixtures for now. While the files will likely change a bit as this app stabilizes its functionality they aren't going to change all the time.

@spmonahan spmonahan requested a review from behowell September 21, 2022 22:27
RandomTree is a class for generating trees with random depth and breadth.
The class is agnostic of UI technology and so can be used to generate
trees for rendering in React, Web Components, vanilla DOM or any other
tool.

RandomTree is a generic class and allows trees with different properties
to be created. This commit creates a "selector tree" that generates a
tree with many attributes like CSS classes, data-* attributes and CSS
selectors.

Internally RandomTree uses a seedable random number generator for
randomness so the results should always be deterministic.
Adds different tree rendering implementations for the UI libraries we
are currently focused on.
Copy link
Contributor

@behowell behowell left a comment

Choose a reason for hiding this comment

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

Looks good thanks!

In an offline conversation, we agreed to remove the large fixture files for now, and look into generating them at build time in the future. But if that's infeasible, it's ok to add them in a future PR when they're needed by the tests.

@spmonahan spmonahan merged commit c63200d into microsoft:master Sep 22, 2022
marcosmoura added a commit to marcosmoura/fluentui that referenced this pull request Sep 24, 2022
* master: (29 commits)
  chore(react-tooltip): update package scaffold (microsoft#24927)
  chore(react-popover): update package scaffold (microsoft#24925)
  chore(react-overflow): update package scaffold (microsoft#24926)
  chore(react-menu): update package scaffold (microsoft#24924)
  applying package updates
  chore: Bump workspace-tools to 0.27.0 (microsoft#24914)
  fix: Make Menu openOnHover prop work again (microsoft#24899)
  stress test: convert cli scripts to typescript (microsoft#24915)
  update package manifest to only include v8 controls (microsoft#24839)
  Stress Test: add random tree (microsoft#24896)
  chore: Expand scope of dependency mismatch generator (microsoft#24880)
  chore: run dependency mismatch generator in release pipeline (microsoft#24881)
  chore: scaffolds react-trigger package (microsoft#24887)
  applying package updates
  chore: a11y docs structure update (microsoft#24871)
  feat: add popupProps to Modal component to allow override internal Popup props (microsoft#24693)
  fix: Set github user in nightly release pipeline (microsoft#24850)
  chore(react-aria): restructure folder organization (microsoft#24884)
  ci(github): fix invalid json string in issues.yml v2 (microsoft#24886)
  Add react-components/unstable to tsconfig aliases (microsoft#24878)
  ...
NotWoods pushed a commit to NotWoods/fluentui that referenced this pull request Nov 18, 2022
* stress test: add random tree generator

RandomTree is a class for generating trees with random depth and breadth.
The class is agnostic of UI technology and so can be used to generate
trees for rendering in React, Web Components, vanilla DOM or any other
tool.

RandomTree is a generic class and allows trees with different properties
to be created. This commit creates a "selector tree" that generates a
tree with many attributes like CSS classes, data-* attributes and CSS
selectors.

Internally RandomTree uses a seedable random number generator for
randomness so the results should always be deterministic.

* stress test: add tree renderer implementations

Adds different tree rendering implementations for the UI libraries we
are currently focused on.

* clean up typescript types
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants