Skip to content

Conversation

@michaldudak
Copy link
Member

@michaldudak michaldudak commented Jul 10, 2025

Proof of concept for Dialog's detached triggers.

Ordinary triggers: https://deploy-preview-2283--base-ui.netlify.app/experiments/dialog/perf-ordinary-triggers
Detached triggers: https://deploy-preview-2283--base-ui.netlify.app/experiments/dialog/perf-detached-triggers

Usage: see docs/src/app/(private)/experiments/dialog/perf-detached-triggers.tsx

The idea of a "detached" trigger is to place it outside of Dialog.Root. Such a trigger references a target dialog by its id (we might allow refs as well). This helps to avoid rendering many Dialog.Root components in scenarios like data lists with actions (as shown in the demos). Many triggers can reuse a single Dialog instance providing different data to it.
This requires an extra Dialog.Provider component that sets up a global context so relation between dialogs and triggers can be established.

This implementation assumes the usage of DetachedTrigger is optional. Dialogs still work the same way using the existing Dialog.Trigger API (without requiring Dialog.Provider).

Detached triggers show significant perf improvements.

The charts display less scripting work needed for detached triggers. Results vary from run to run, but the trend is clear - for the example with 200 rows, scripting time after the load event takes about 2x more time with ordinary triggers (~300ms vs ~600ms on 6x CPU slowdown). Also memory usage is significantly lower (peaking at ~15MB for detached and ~24MB for ordinary triggers). This is mostly due to reducing the number of rendered React nodes and contexts.

cc @romgrk

Screenshot 2025-07-10 113610

Screenshot 2025-07-10 113629

@michaldudak michaldudak added component: dialog Changes related to the dialog component. proof of concept labels Jul 10, 2025
@mui-bot
Copy link

mui-bot commented Jul 10, 2025

Bundle size report

Bundle Parsed Size Gzip Size
@base-ui-components/react 🔺+972B(+0.32%) 🔺+400B(+0.41%)

Details of bundle changes

Generated by 🚫 dangerJS against 56de2c5

@netlify
Copy link

netlify bot commented Jul 10, 2025

Deploy Preview for base-ui ready!

Name Link
🔨 Latest commit 56de2c5
🔍 Latest deploy log https://app.netlify.com/projects/base-ui/deploys/68760c3d9dd3d900087446c6
😎 Deploy Preview https://deploy-preview-2283--base-ui.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged. label Jul 11, 2025
@atomiks
Copy link
Contributor

atomiks commented Jul 14, 2025

Does this API also solve #2157?

@KingSora
Copy link

Just as an thought, the keyword detached could be used to identify this API / Pattern for all of the sub-components related:

e.g. Dialog.DetachedRoot, Dialog.DetachedTrigger, Dialog.createDetachedDialog() instead of inventing new names like Dialog.TypedRoot.

This would only apply if Dialog.TypedRoot for example can't be used for any other pattern / API as well.

@michaldudak
Copy link
Member Author

michaldudak commented Jul 15, 2025

The latest version doesn't use any new parts (except for Dialog.Provider) - only Dialog.Root and Dialog.Trigger are used. If a Dialog.Trigger has a dialog (naming TBD) prop, it acts as a detached trigger and doesn't have to be placed within the Root.

@github-actions github-actions bot removed the PR: out-of-date The pull request has merge conflicts and can't be merged. label Jul 15, 2025
@pkg-pr-new
Copy link

pkg-pr-new bot commented Jul 15, 2025

vite-css-base-ui-example

npm i https://pkg.pr.new/@base-ui-components/react@2283
npm i https://pkg.pr.new/@base-ui-components/utils@2283

commit: 56de2c5

@beeirl
Copy link

beeirl commented Jul 23, 2025

interesting poc! are you planning to make a detached trigger reactive to the open state?

@michaldudak
Copy link
Member Author

Yes, I'm going to. I'm also going to change the implementation significantly based on my learnings from #2336.

@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged. label Jul 30, 2025
@michaldudak
Copy link
Member Author

Implemented in #2974

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component: dialog Changes related to the dialog component. PR: out-of-date The pull request has merge conflicts and can't be merged.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants