shoelace: Chrome freezes when dropping down select

Describe the bug

Under certain conditions, if the dropdown of an SlSelect is dropped down, Chrome will freeze in an infinite loop.

To Reproduce

Steps to reproduce the behavior:

  1. Go to https://codepen.io/oliversalzburg/pen/VwQdYgO?editors=1100
  2. Drop down the lists one after another until one makes the browser freeze

If this doesn’t happen, go into Responsive Design mode and reduce the viewport size as shown below.

Screenshots

image

Browser / OS

  • OS: Windows
  • Browser: Chrome
  • Browser: 102.0.5005.63

Additional information

This doesn’t seem to happen in Firefox. From what I could tell, this seems to be an infinite loop in https://github.com/floating-ui/floating-ui

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 6
  • Comments: 18 (10 by maintainers)

Most upvoted comments

I’m happy to report that this has been resolved. I was able to replicate it consistently and patch it by waiting for the next frame prior to repositioning. After 624a8bbe71e59ae6255730e34d71e0b13d5ecf90, I’m no longer able to replicate it.

Thanks to everyone who helped troubleshoot this one! Shoutout to @oliversalzburg for this comment that pointed me in the right direction and @atomiks for offering help with his excellent Floating UI library.

I was able to repro this in CodePen, but I can’t seem to break it in any other environment. I did update Floating UI to 0.5.2 in 6dd9773f2c75148d41998036ecda86c6ea3dee89, but I don’t see anything in the changelog that addresses an issue similar to this.

I think the next step is to narrow down the repro. Does it happen with just one <sl-select> on the page? How can I reliably reproduce it?

I’m also pinging @atomiks, creator of Floating UI, to see if any other users have experienced this and if it’s a known issue. (Apologies for tagging you but this seems like it might be more deeply rooted than Shoelace’s integration.)

Thanks!

@oliversalzburg I would say that’s the most likely cause for the infinite loop! Running them in parallel is going to cause conflicts with the positioning logic, so ensuring only one of them is active should fix the issue

Edit: I just confirmed that in my local repro. Removing this.dropdown.reposition() removes the infinite loop in the current version, but it still gets positioned correctly because the other computation is running.

Key takeaways:

  • Floating UI shouldn’t default to a loop in prod in case things like this happen accidentally. It now doesn’t, so while the position will not be correct, at least there will be no loop.
  • Running two computePosition()s in parallel causes conflicts with the positioning calculations and leads to the infinite loop in the first place. Only one should be active.

I took another close look at this and noticed something of interest.

When the select is dropped down, two position computations run in parallel and are likely conflicting with each other. You have one positioner running in handleOpenChange in the dropdown and you have another in handleMenuShow in the select.

I tried to dive into this and I think it may be a bug with the minified code that’s being distributed since beta-74 (it was hard to debug on minified code). It doesn’t exist in beta-73.

https://github.com/floating-ui/floating-ui/blob/84ecd57433ec9b4b788e4ed6f1ed6ef2c4b3aa28/packages/core/src/middleware/flip.ts#L105-L119

middlewareData.flip doesn’t seem to exist on subsequent runs and so an infinite loop occurs - the minifier is breaking some part here.

This seems to be happening for me as well when the dropdown doesn’t have enough space to render the full list without overflow. To reproduce it for me its as simple as just sliding up my devtools bar