fluentui icon indicating copy to clipboard operation
fluentui copied to clipboard

perf: add stress test app

Open spmonahan opened this issue 3 years ago • 6 comments

This PR adds a new app called "Stress Test" that allows Fluent developers to test and compare the performance of v8, v9 and Web Component (WC) Fluent implementations. Today if you want to build a web app using Fluent v8, v9 and WC are the implementations the Fluent team provides and Stress Test exists so we can understand the different performance characteristics of each implementation. This application is still a work in progress but I feel it's reached a point where it should be merged before more work is done with it.

The immediate goal of this application is to establish a performance baseline so we can understand the state of Fluent performance today. Longer term there is much opportunity for Stress Test but the next step is to look at automation and how Stress Test fits into our build pipeline.

Stress Test is a "vanilla" Webpack application because it needs to support React (Fluent v8 and v9) and Web Components (Fluent WC) and for stress testing it needs to treat each implementation "natively". That is, React should work like a typical React app; Web Components should work like a typical WC app.

Initial Test Results

I've compiled the initial test results into a Codesandbox app: https://6u9n59.csb.app/ These tests were run on Windows 11 with an Intel(R) Core(TM) i7-1065G7 CPU @ 1.30GHz 1.50 GHz and 32GB of RAM. Tests were run in Chrome and Firefox.

The test cases are:

  1. mount: measures the amount of time required for the first mount of components
  2. inject-styles: injects styles into the document head and measures how long style recalculation and layout takes
  3. prop-update: measures the amount of time a prop update takes to render
  4. add-node: measures how long it takes to add nodes to the DOM
  5. remove-node: measures how long it takes to remove nodes from the DOM

Each of these test cases was run for 100, 250, 500, 750 and 1000 "nodes" (where a "node" is a StressComponent that renders several Fluent components). The number of nodes is the initial number rendered and the number added for add-node. For remove-node the number removed is "initial - 1" (so 100 removes 99 nodes, 250 removes 249, etc).

Other Approaches

Standalone App

A case could be made that Stress Test should live outside the main Fluent repo. I discarded this idea because it's important for it to stay current with the daily changes made to Fluent and ultimately it should be part of the build pipeline.

Vite App

The original implementation of Stress Test used Vite. This is great because it supports both Fluent and WC and provides a fast out-of-the-box experience, however it does not use Webpack. This app needs to use Webpack as some build-time Griffel optimizations are made with Webpack.

Create React App

Stress Test needs to "natively" support WCs and CRA is geared toward React. This isn't to say WCs couldn't work in CRA it just felt like swimming against the tide. Additionally, Stress Test needs to customize the Webpack config for Griffel and this can be challenging in CRA.

Related Issue(s)

Fixes #23422

spmonahan avatar Aug 08 '22 18:08 spmonahan

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 94b46d016f715ea9f2110e5436dc16a18d78ccd8:

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

codesandbox-ci[bot] avatar Aug 08 '22 18:08 codesandbox-ci[bot]

Asset size changes

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

Baseline commit: 0232344dc028b9054c9cd73211b09e491aaa8ab1 (build)

size-auditor[bot] avatar Aug 08 '22 18:08 size-auditor[bot]

Perf Analysis (@fluentui/react-components)

No significant results to display.

All results

Scenario Render type Master Ticks PR Ticks Iterations Status
Avatar mount 1147 1291 5000
Button mount 961 956 5000
FluentProvider mount 1574 1569 5000
FluentProviderWithTheme mount 634 640 10
FluentProviderWithTheme virtual-rerender 600 598 10
FluentProviderWithTheme virtual-rerender-with-unmount 636 640 10
MakeStyles mount 1915 1934 50000
SpinButton mount 2505 2480 5000

fabricteam avatar Aug 08 '22 19:08 fabricteam

📊 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)
79.562 kB
24.121 kB
react-alert
Alert
83.79 kB
20.841 kB
react-avatar
Avatar
48.283 kB
13.644 kB
react-avatar
AvatarGroup
15.072 kB
6.016 kB
react-avatar
AvatarGroupItem
68.464 kB
19.067 kB
react-badge
Badge
22.503 kB
7.153 kB
react-badge
CounterBadge
23.406 kB
7.449 kB
react-badge
PresenceBadge
23.947 kB
7.022 kB
react-button
Button
36.396 kB
9.575 kB
react-button
CompoundButton
43.469 kB
10.812 kB
react-button
MenuButton
39.014 kB
10.456 kB
react-button
SplitButton
46.544 kB
11.84 kB
react-button
ToggleButton
51.91 kB
11.003 kB
react-card
Card - All
67.458 kB
19.264 kB
react-card
Card
63.14 kB
18.176 kB
react-card
CardFooter
8.461 kB
3.555 kB
react-card
CardHeader
9.504 kB
3.896 kB
react-card
CardPreview
8.562 kB
3.61 kB
react-combobox
Combobox (including child components)
72.762 kB
23.757 kB
react-combobox
Dropdown (including child components)
71.026 kB
23.291 kB
react-components
react-components: Accordion, Button, FluentProvider, Image, Menu, Popover
189.031 kB
51.967 kB
react-components
react-components: FluentProvider & webLightTheme
32.895 kB
10.778 kB
react-dialog
Dialog (including children components)
85.574 kB
25.521 kB
react-divider
Divider
16.359 kB
5.853 kB
react-image
Image
10.68 kB
4.215 kB
react-input
Input
23.554 kB
7.644 kB
react-label
Label
9.238 kB
3.815 kB
react-link
Link
12.231 kB
4.925 kB
react-menu
Menu (including children components)
115.929 kB
35.379 kB
react-menu
Menu (including selectable components)
119.128 kB
35.874 kB
react-overflow
hooks only
10.898 kB
4.174 kB
react-popover
Popover
103.05 kB
31.561 kB
react-portal
Portal
10.576 kB
3.875 kB
react-positioning
usePositioning
19.7 kB
7.404 kB
react-provider
FluentProvider
15.655 kB
5.835 kB
react-radio
Radio
36.238 kB
12 kB
react-radio
RadioGroup
14.361 kB
5.728 kB
react-select
Select
20.746 kB
7.299 kB
react-slider
Slider
32.07 kB
10.033 kB
react-spinbutton
SpinButton
43.899 kB
12.362 kB
react-spinner
Spinner
19.848 kB
6.384 kB
react-switch
Switch
32.562 kB
10.253 kB
react-text
Text - Default
11.682 kB
4.561 kB
react-text
Text - Wrappers
14.992 kB
4.995 kB
react-textarea
Textarea
23.674 kB
7.83 kB
react-theme
Single theme token import
69 B
89 B
react-theme
Teams: all themes
29.224 kB
6.255 kB
react-theme
Teams: Light theme
17.088 kB
4.89 kB
react-tooltip
Tooltip
41.504 kB
14.622 kB
react-utilities
SSRProvider
180 B
159 B
🤖 This report was generated against 0232344dc028b9054c9cd73211b09e491aaa8ab1

fabricteam avatar Aug 08 '22 19:08 fabricteam

Perf Analysis (@fluentui/react-northstar)

Perf tests with no regressions
Scenario Current PR Ticks Baseline Ticks Ratio
RefMinimalPerf.default 187 160 1.17:1
AlertMinimalPerf.default 215 188 1.14:1
RadioGroupMinimalPerf.default 357 317 1.13:1
AvatarMinimalPerf.default 163 150 1.09:1
PortalMinimalPerf.default 150 137 1.09:1
IconMinimalPerf.default 499 457 1.09:1
TextAreaMinimalPerf.default 413 382 1.08:1
ToolbarMinimalPerf.default 774 716 1.08:1
ChatDuplicateMessagesPerf.default 240 227 1.06:1
DialogMinimalPerf.default 645 608 1.06:1
MenuMinimalPerf.default 715 677 1.06:1
ChatWithPopoverPerf.default 273 261 1.05:1
HeaderSlotsPerf.default 643 615 1.05:1
MenuButtonMinimalPerf.default 1402 1337 1.05:1
ReactionMinimalPerf.default 313 299 1.05:1
CheckboxMinimalPerf.default 2251 2168 1.04:1
GridMinimalPerf.default 280 270 1.04:1
ListCommonPerf.default 513 493 1.04:1
SegmentMinimalPerf.default 285 275 1.04:1
CustomToolbarPrototype.default 2267 2171 1.04:1
DropdownManyItemsPerf.default 560 546 1.03:1
SkeletonMinimalPerf.default 281 272 1.03:1
TableMinimalPerf.default 339 328 1.03:1
DropdownMinimalPerf.default 2616 2573 1.02:1
HeaderMinimalPerf.default 282 277 1.02:1
ProviderMinimalPerf.default 338 331 1.02:1
SliderMinimalPerf.default 1400 1378 1.02:1
TreeWith60ListItems.default 132 129 1.02:1
FormMinimalPerf.default 332 329 1.01:1
InputMinimalPerf.default 1084 1072 1.01:1
LabelMinimalPerf.default 315 311 1.01:1
ListMinimalPerf.default 422 416 1.01:1
SplitButtonMinimalPerf.default 3618 3596 1.01:1
TableManyItemsPerf.default 1533 1512 1.01:1
TooltipMinimalPerf.default 923 913 1.01:1
EmbedMinimalPerf.default 3404 3421 1:1
FlexMinimalPerf.default 234 234 1:1
LoaderMinimalPerf.default 573 571 1:1
PopupMinimalPerf.default 517 516 1:1
ProviderMergeThemesPerf.default 1053 1050 1:1
StatusMinimalPerf.default 553 553 1:1
ButtonMinimalPerf.default 124 125 0.99:1
ChatMinimalPerf.default 582 589 0.99:1
ImageMinimalPerf.default 304 308 0.99:1
LayoutMinimalPerf.default 285 288 0.99:1
ListNestedPerf.default 452 457 0.99:1
ButtonSlotsPerf.default 387 394 0.98:1
ItemLayoutMinimalPerf.default 969 992 0.98:1
TreeMinimalPerf.default 647 661 0.98:1
AttachmentSlotsPerf.default 881 910 0.97:1
ButtonOverridesMissPerf.default 1207 1238 0.97:1
DividerMinimalPerf.default 284 293 0.97:1
ListWith60ListItems.default 492 511 0.96:1
RosterPerf.default 897 932 0.96:1
TextMinimalPerf.default 260 272 0.96:1
DatepickerMinimalPerf.default 4394 4614 0.95:1
VideoMinimalPerf.default 508 533 0.95:1
CardMinimalPerf.default 403 438 0.92:1
AccordionMinimalPerf.default 107 117 0.91:1
AttachmentMinimalPerf.default 106 116 0.91:1
AnimationMinimalPerf.default 382 426 0.9:1
BoxMinimalPerf.default 245 272 0.9:1
CarouselMinimalPerf.default 345 385 0.9:1

fabricteam avatar Aug 08 '22 19:08 fabricteam

Perf Analysis (@fluentui/react)

No significant results to display.

All results

Scenario Render type Master Ticks PR Ticks Iterations Status
BaseButton mount 787 804 5000
Breadcrumb mount 2376 2338 1000
Checkbox mount 2250 2241 5000
CheckboxBase mount 1970 1976 5000
ChoiceGroup mount 4071 4097 5000
ComboBox mount 839 843 1000
CommandBar mount 9116 9079 1000
ContextualMenu mount 10252 10222 1000
DefaultButton mount 976 973 5000
DetailsRow mount 3298 3375 5000
DetailsRowFast mount 3368 3323 5000
DetailsRowNoStyles mount 3153 3145 5000
Dialog mount 2516 2504 1000
DocumentCardTitle mount 166 143 1000
Dropdown mount 2837 2839 5000
FocusTrapZone mount 1618 1654 5000
FocusZone mount 1570 1576 5000
IconButton mount 1507 1546 5000
Label mount 297 313 5000
Layer mount 2876 2859 5000
Link mount 410 400 5000
MenuButton mount 1290 1281 5000
MessageBar mount 1800 1896 5000
Nav mount 2829 2862 1000
OverflowSet mount 956 971 5000
Panel mount 1927 1951 1000
Persona mount 849 865 1000
Pivot mount 1247 1269 1000
PrimaryButton mount 1149 1132 5000
Rating mount 6699 6745 5000
SearchBox mount 1120 1117 5000
Shimmer mount 2162 2141 5000
Slider mount 1667 1673 5000
SpinButton mount 4625 4376 5000
Spinner mount 373 366 5000
SplitButton mount 2768 2750 5000
Stack mount 456 445 5000
StackWithIntrinsicChildren mount 1969 1978 5000
StackWithTextChildren mount 4508 4520 5000
SwatchColorPicker mount 10042 10091 5000
TagPicker mount 2389 2332 5000
TeachingBubble mount 85365 84116 5000
Text mount 376 354 5000
TextField mount 1201 1208 5000
ThemeProvider mount 1113 1100 5000
ThemeProvider virtual-rerender 631 635 5000
ThemeProvider virtual-rerender-with-unmount 1617 1634 5000
Toggle mount 697 700 5000
buttonNative mount 109 113 5000

fabricteam avatar Aug 08 '22 19:08 fabricteam

dat pipeline is paaaaassing 🤝😍

Hotell avatar Aug 18 '22 17:08 Hotell