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

UI: Improve sidebar performance when switching stories #26184

Merged

Conversation

literalpie
Copy link
Contributor

@literalpie literalpie commented Feb 24, 2024

What I did

3 changes that add up to a moderate speed-up when switching stories, especially in projects where there are many (several hundred) stories.

  1. Fuse and list within the Search component are now only calculated when needed (when the value of the search input changes), not on each render.
  2. The value returned by LayoutProvider is now memoized. This has a moderate impact because this hook is used in Node within the sidebar, which may have hundreds of instances. Before this change, useLayout was causing Node to rerender every time, making its React.memo useless.
  3. The list of items inside Tree is now memoized. This is helpful because this list is made by mapping over a very large list

In sum, I saw a performance improvement of 10-40ms (12-50%) per render when changing stories. The impact will be more or less depending on how many stories you have.

Expand to see performance profiles 📈 Before: storybook-perf-before-best After: storybook-perf-after-best

storybook-perf-profiles.zip (unzip, then open JSON files with React Dev Tools)

Checklist for Contributors

Testing

The changes in this PR are covered in the following automated tests:

  • stories
  • unit tests
  • integration tests
  • end-to-end tests

(Unfortunately, I don't know of a good way to test this kind of performance improvements in React. )

Manual testing

  1. To see the largest contrast in performance, choose any sandbox and create many stories. One way to do this quickly is by making a folder of tests with auto-generated names/titles and copy/paste the folder many times.
  2. Open Storybook in your browser with React Dev Tools installed
  3. Start a React profile, and switch between stories in the side bar

Documentation

  • Add or update documentation reflecting your changes
  • If you are deprecating/removing a feature, make sure to update
    MIGRATION.MD

(N/A)

Checklist for Maintainers

  • When this PR is ready for testing, make sure to add ci:normal, ci:merged or ci:daily GH label to it to run a specific set of sandboxes. The particular set of sandboxes can be found in code/lib/cli/src/sandbox-templates.ts

  • Make sure this PR contains one of the labels below:

    Available labels
    • bug: Internal changes that fixes incorrect behavior.
    • maintenance: User-facing maintenance tasks.
    • dependencies: Upgrading (sometimes downgrading) dependencies.
    • build: Internal-facing build tooling & test updates. Will not show up in release changelog.
    • cleanup: Minor cleanup style change. Will not show up in release changelog.
    • documentation: Documentation only changes. Will not show up in release changelog.
    • feature request: Introducing a new feature.
    • BREAKING CHANGE: Changes that break compatibility in some way with current major version.
    • other: Changes that don't fit in the above categories.

🦋 Canary release

This PR does not have a canary release associated. You can request a canary release of this pull request by mentioning the @storybookjs/core team here.

core team members can create a canary release here or locally with gh workflow run --repo storybookjs/storybook canary-release-pr.yml --field pr=<PR_NUMBER>

3 changes that add up to a moderate speed-up when switching stories, especially in projects where there are many (several hundred) stories.
1. Fuse and list within the Search component are now only calculated when needed (when the value of the search input changes), not on each render.
2. The value returned by LayoutProvider is now memoized. This has a moderate impact because this hook is used in Node within the sidebar, which may have hundreds of instances. Before this change, useLayout was causing Node to rerender every time, making its React.memo useless.
3. The list of items inside Tree is now memoized. This is helpful because this list is made by mapping over a very large list
@literalpie literalpie marked this pull request as ready for review February 24, 2024 21:31
@yannbf yannbf changed the title perf(manager): improve performance when switching stories UI: Improve sidebar performance when switching stories Feb 26, 2024
@ndelangen ndelangen merged commit 5771455 into storybookjs:next Feb 27, 2024
47 of 48 checks passed
@github-actions github-actions bot mentioned this pull request Feb 27, 2024
30 tasks
@vanessayuenn vanessayuenn added the maintenance User-facing maintenance tasks label Feb 28, 2024
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.

4 participants