Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@steverep
Copy link
Contributor

@steverep steverep commented Sep 27, 2023

Edited per discussion below and also fixes #3831

Fixes #4182 by adding a check that the controller is not null. At the risk of being slightly out of scope, also:

  • Allow null controller and observers on disconnect (if they were never setup properly on connection, you'd still want the benefits of a full cleanup instead of throwing)
  • Removed a couple of unnecessary non-null assertions

PS - Looks like there was supposed to be a PR template, but the field was just filled with "...LL error" for me

@changeset-bot
Copy link

changeset-bot bot commented Sep 27, 2023

🦋 Changeset detected

Latest commit: abe6b37

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@lit-labs/virtualizer Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions
Copy link
Contributor

github-actions bot commented Sep 27, 2023

📊 Tachometer Benchmark Results

Summary

⏳ Benchmarks are currently running. Results below are out of date.

nop-update

  • this-change, tip-of-tree, previous-release: unsure 🔍 -10% - +1% (-2.25ms - +0.35ms)
    this-change vs tip-of-tree

render

  • this-change: 79.68ms - 82.43ms
  • this-change, tip-of-tree, previous-release: unsure 🔍 -4% - +7% (-1.33ms - +2.21ms)
    this-change vs tip-of-tree
  • this-change, tip-of-tree, previous-release: unsure 🔍 -2% - +3% (-0.87ms - +1.94ms)
    this-change vs tip-of-tree
  • this-change, tip-of-tree, previous-release: unsure 🔍 -3% - +2% (-1.61ms - +0.91ms)
    this-change vs tip-of-tree

update

  • this-change: 849.51ms - 862.19ms
  • this-change, tip-of-tree, previous-release: unsure 🔍 -3% - +4% (-2.32ms - +2.77ms)
    this-change vs tip-of-tree
  • this-change, tip-of-tree, previous-release: unsure 🔍 -3% - +2% (-3.11ms - +2.38ms)
    this-change vs tip-of-tree
  • this-change, tip-of-tree, previous-release: unsure 🔍 -1% - +1% (-12.45ms - +8.00ms)
    this-change vs tip-of-tree

update-reflect

  • this-change: 828.86ms - 845.08ms
  • this-change, tip-of-tree, previous-release: unsure 🔍 -1% - +1% (-10.03ms - +11.56ms)
    this-change vs tip-of-tree

Results

⏳ Benchmarks are currently running. Results below are out of date.
this-change

render

VersionAvg timevs
79.68ms - 82.43ms-

update

VersionAvg timevs
849.51ms - 862.19ms-

update-reflect

VersionAvg timevs
828.86ms - 845.08ms-
this-change, tip-of-tree, previous-release

render

VersionAvg timevs this-change
vs tip-of-tree
tip-of-tree
vs previous-release
previous-release
this-change
30.46ms - 33.05ms-unsure 🔍
-4% - +7%
-1.33ms - +2.21ms
unsure 🔍
-7% - +5%
-2.19ms - +1.60ms
tip-of-tree
tip-of-tree
30.11ms - 32.53msunsure 🔍
-7% - +4%
-2.21ms - +1.33ms
-unsure 🔍
-8% - +3%
-2.58ms - +1.11ms
previous-release
previous-release
30.66ms - 33.44msunsure 🔍
-5% - +7%
-1.60ms - +2.19ms
unsure 🔍
-4% - +8%
-1.11ms - +2.58ms
-

update

VersionAvg timevs this-change
vs tip-of-tree
tip-of-tree
vs previous-release
previous-release
this-change
65.64ms - 68.72ms-unsure 🔍
-3% - +4%
-2.32ms - +2.77ms
unsure 🔍
-7% - +1%
-4.63ms - +0.84ms
tip-of-tree
tip-of-tree
64.93ms - 68.98msunsure 🔍
-4% - +3%
-2.77ms - +2.32ms
-unsure 🔍
-7% - +1%
-5.16ms - +0.92ms
previous-release
previous-release
66.82ms - 71.33msunsure 🔍
-1% - +7%
-0.84ms - +4.63ms
unsure 🔍
-1% - +8%
-0.92ms - +5.16ms
-

nop-update

VersionAvg timevs this-change
vs tip-of-tree
tip-of-tree
vs previous-release
previous-release
this-change
20.04ms - 21.61ms-unsure 🔍
-10% - +1%
-2.25ms - +0.35ms
unsure 🔍
-11% - +1%
-2.51ms - +0.17ms
tip-of-tree
tip-of-tree
20.74ms - 22.81msunsure 🔍
-2% - +11%
-0.35ms - +2.25ms
-unsure 🔍
-8% - +6%
-1.72ms - +1.28ms
previous-release
previous-release
20.91ms - 23.08msunsure 🔍
-1% - +12%
-0.17ms - +2.51ms
unsure 🔍
-6% - +8%
-1.28ms - +1.72ms
-
this-change, tip-of-tree, previous-release

render

VersionAvg timevs this-change
vs tip-of-tree
tip-of-tree
vs previous-release
previous-release
this-change
58.22ms - 60.06ms-unsure 🔍
-2% - +3%
-0.87ms - +1.94ms
unsure 🔍
-2% - +3%
-1.04ms - +1.48ms
tip-of-tree
tip-of-tree
57.54ms - 59.67msunsure 🔍
-3% - +1%
-1.94ms - +0.87ms
-unsure 🔍
-3% - +2%
-1.68ms - +1.05ms
previous-release
previous-release
58.06ms - 59.77msunsure 🔍
-2% - +2%
-1.48ms - +1.04ms
unsure 🔍
-2% - +3%
-1.05ms - +1.68ms
-

update

VersionAvg timevs this-change
vs tip-of-tree
tip-of-tree
vs previous-release
previous-release
this-change
120.32ms - 123.93ms-unsure 🔍
-3% - +2%
-3.11ms - +2.38ms
unsure 🔍
-4% - +1%
-4.85ms - +0.69ms
tip-of-tree
tip-of-tree
120.42ms - 124.56msunsure 🔍
-2% - +3%
-2.38ms - +3.11ms
-unsure 🔍
-4% - +1%
-4.67ms - +1.24ms
previous-release
previous-release
122.10ms - 126.31msunsure 🔍
-1% - +4%
-0.69ms - +4.85ms
unsure 🔍
-1% - +4%
-1.24ms - +4.67ms
-
this-change, tip-of-tree, previous-release

render

VersionAvg timevs this-change
vs tip-of-tree
tip-of-tree
vs previous-release
previous-release
this-change
52.25ms - 53.79ms-unsure 🔍
-3% - +2%
-1.61ms - +0.91ms
unsure 🔍
-2% - +3%
-1.13ms - +1.57ms
tip-of-tree
tip-of-tree
52.37ms - 54.36msunsure 🔍
-2% - +3%
-0.91ms - +1.61ms
-unsure 🔍
-2% - +4%
-0.92ms - +2.05ms
previous-release
previous-release
51.70ms - 53.91msunsure 🔍
-3% - +2%
-1.57ms - +1.13ms
unsure 🔍
-4% - +2%
-2.05ms - +0.92ms
-

update

VersionAvg timevs this-change
vs tip-of-tree
tip-of-tree
vs previous-release
previous-release
this-change
864.73ms - 877.17ms-unsure 🔍
-1% - +1%
-12.45ms - +8.00ms
unsure 🔍
-1% - +1%
-10.60ms - +7.96ms
tip-of-tree
tip-of-tree
865.06ms - 881.29msunsure 🔍
-1% - +1%
-8.00ms - +12.45ms
-unsure 🔍
-1% - +1%
-9.74ms - +11.55ms
previous-release
previous-release
865.38ms - 879.15msunsure 🔍
-1% - +1%
-7.96ms - +10.60ms
unsure 🔍
-1% - +1%
-11.55ms - +9.74ms
-

update-reflect

VersionAvg timevs this-change
vs tip-of-tree
tip-of-tree
vs previous-release
previous-release
this-change
857.30ms - 871.43ms-unsure 🔍
-1% - +1%
-10.03ms - +11.56ms
unsure 🔍
-1% - +2%
-5.45ms - +15.13ms
tip-of-tree
tip-of-tree
855.44ms - 871.77msunsure 🔍
-1% - +1%
-11.56ms - +10.03ms
-unsure 🔍
-1% - +2%
-7.00ms - +15.15ms
previous-release
previous-release
852.04ms - 867.02msunsure 🔍
-2% - +1%
-15.13ms - +5.45ms
unsure 🔍
-2% - +1%
-15.15ms - +7.00ms
-

tachometer-reporter-action v2 for Benchmarks

@rictic
Copy link
Collaborator

rictic commented Sep 27, 2023

PS - Looks like there was supposed to be a PR template, but the field was just filled with "...LL error" for me

I think that was just the end of your commit message

@rictic rictic requested a review from graynorton September 27, 2023 16:30
@rictic
Copy link
Collaborator

rictic commented Sep 27, 2023

This looks like a great change to me. I'd like to give Gray a chance to review in case there's some subtlety where we'd rather fail on a missing controller here

@rictic
Copy link
Collaborator

rictic commented Sep 27, 2023

Oh, please add a changeset by running npm run changeset at the root of the monorepo

@steverep steverep changed the title fix(labs/virtualizer): check for null controller when correcting scro… fix(labs/virtualizer): check for null controller when correcting scroll error Sep 27, 2023
@steverep steverep requested a review from rictic September 27, 2023 17:14
@graynorton
Copy link
Contributor

These changes may indeed be good, but if possible I'd like to understand better how it is that the virtualizer in HomeAssistant ends up in a state where it has no ScrollerController but is trying to correct a scroll error, and ideally I'd like to come up with a minimal repro case so that we can write a test or two.

My guess is that the virtualizer is being disconnected somewhere in the chain of events and then subsequently responds to an async scroll error message (perhaps triggered by a MutationObserver callback) that no longer applies. If this is the case, there may be a spot earlier in the codepath where we can short-circuit, rather than getting all the way into _correctScrollError() without a controller in place.

@steverep
Copy link
Contributor Author

It's originating from the children resize observer, and it certainly occurs only after a disconnect. It's possible the items get removed before the virtualizer element is fully disconnected (and maybe that observer isn't considering that situation?). I don't quite understand that callback enough at the moment and probably not the best to come up with a minimal test. Here's the longer stack trace:

Uncaught (in promise) TypeError: this._scrollerController is null
_correctScrollError
Virtualizer.ts:741

_finishDOMUpdate
Virtualizer.ts:546

_updateDOM
Virtualizer.ts:538

_handleLayoutMessage
Virtualizer.ts:603

_layout
Virtualizer.ts:441

_sendStateChangedMessage
BaseLayout.ts:478

_reflow
BaseLayout.ts:364

_reflow
flow.ts:491

reflowIfNeeded
BaseLayout.ts:257

_updateLayout
Virtualizer.ts:563

_schedule
Virtualizer.ts:520

_measureChildren
Virtualizer.ts:501

_childrenSizeChanged
Virtualizer.ts:888

_initObservers
Virtualizer.ts:275

connected
Virtualizer.ts:287

_makeVirtualizer
virtualize.ts:130

_initialize
virtualize.ts:141

update
virtualize.ts:91

@steverep
Copy link
Contributor Author

Given that, I suppose another solution would be to change the order in disconnected(), so that the observers are disconnected before _scrollerController is detached, but maybe that's a distinction without much of a difference?

@graynorton
Copy link
Contributor

Thanks for the additional info, @steverep. I'll play around a bit and see if I can come up with a minimal repro, though I may have to come back to you with followup questions.

@graynorton
Copy link
Contributor

@steverep I expect to have time to dig into this later today, but two quick questions:

  1. Does this happen to be reproducible in the Home Assistant demo deployment, where I can easily see it?
  2. Would it be easy to point me to the relevant source files in the Home Assistant repo?

@steverep
Copy link
Contributor Author

1. Does this happen to be reproducible in the Home Assistant demo deployment, where I can easily see it?

Unfortunately, it is not. Most if not all the virtualizers are in the settings area which isn't in the demo.

2. Would it be easy to point me to the relevant source files in the Home Assistant repo?

Yes, of course. The repro I am using comes from the virtualizer in our ha-data-table component. Sorry, it's one of the more complicated components though.

Essentially, the repro goes like this:

  1. Scroll it
  2. Click a row which brings you to another page in the SPA (removes the virtualizer from DOM)
  3. Click another link in the new page to navigate again, then error is in the console

Let me know if I can test anything for you.

@graynorton
Copy link
Contributor

@cintaccs In your case (as described in #4238), can you explain how and why the virtualizer is being destroyed / disconnected when the data provided by the containing view changes? I would expect the virtualizer to rerender, but not disconnect.

@steverep
Copy link
Contributor Author

steverep commented Sep 29, 2023

FWIW, I took a closer look at this today. If I'm reading the ResizeObserver spec correctly, calling disconnect on the RO should theoretically guarantee the callbacks have all returned since everything is done in the event loop. That doesn't include anything spawned asynchronously of course, which the _childrenRO does.

The deeper problem seems to be that in _finishDOMUpdate, which is within the asynchronous part of the callback, _childrenRO.observe() is being called. So the RO is is disconnected, only to just start observing again if that stuff hasn't finished. Indeed if I set this._childrenRO = null after disconnecting, I get the following error instead:

Uncaught (in promise) TypeError: this._childrenRO is null
    _finishDOMUpdate Virtualizer.ts:545
    _finishDOMUpdate Virtualizer.ts:545
    _updateDOM Virtualizer.ts:542
    _handleLayoutMessage Virtualizer.ts:605
    _layout Virtualizer.ts:449
    _sendStateChangedMessage BaseLayout.ts:478
    _reflow BaseLayout.ts:364
    _reflow flow.ts:491
    reflowIfNeeded BaseLayout.ts:257
    _updateLayout Virtualizer.ts:566
    _schedule Virtualizer.ts:524
    async*set items Virtualizer.ts:252
    _updateVirtualizerConfig virtualize.ts:107
    update virtualize.ts:89
    _$resolve directive.ts:134
    resolveDirective lit-html.ts:1083
    _$setValue lit-html.ts:1362
    _update lit-html.ts:1192
    _commitTemplateResult lit-html.ts:1540
    _$setValue lit-html.ts:1384
    render lit-html.ts:2183
    update lit-element.ts:165
    performUpdate reactive-element.ts:1329
    scheduleUpdate reactive-element.ts:1261
    __enqueueUpdate reactive-element.ts:1233
    requestUpdate reactive-element.ts:1208
    set reactive-element.ts:726
    _commitValue lit-html.ts:1883
    _$setValue lit-html.ts:1825
    _update lit-html.ts:1192
    _commitTemplateResult lit-html.ts:1540
    _$setValue lit-html.ts:1384
    _update lit-html.ts:1192
    _commitTemplateResult lit-html.ts:1540
    _$setValue lit-html.ts:1384
    render lit-html.ts:2183
    update lit-element.ts:165
    performUpdate reactive-element.ts:1329
    scheduleUpdate reactive-element.ts:1261
    __enqueueUpdate reactive-element.ts:1233
    requestUpdate reactive-element.ts:1208
Virtualizer.ts:545

Note the RO callback is not in the trace this time. It's coming from an earlier call to update the DOM.

@graynorton
Copy link
Contributor

graynorton commented Sep 29, 2023

@steverep Yes, I believe the problem is that something in application code (probably related to the mechanism for switching between views as the user navigates) is causing the virtualizer to kick off an update cycle after it has been disconnected.

In trying to create a minimal repro was, I have tried various ways of toggling between a view with a virtualizer and a view without a virtualizer. However, the only way I've been able to end up in _correctScrollError without a ScrollerController present is really contrived: I intentionally trigger a virtualizer update (by setting its items property to a different value) at the same time as I'm triggering the view update that will cause the virtualizer to be disconnected.

The following Playground example illustrates:

https://lit.dev/playground/#gist=e18207161b9d96c5d81dfb7032f474ad

If you run it as-is (with the Console open to view log statements) and click the Toggle button, everything is fine. But if you uncomment line 35 and then toggle, you'll see we end up in _correctScrollError without a controller.

The good news is that it should probably be fairly straightforward to short-circuit the virtualizer update cycle in the case where it is not currently connected.

However, I would still like to see if we can figure out what it is in the Home Assistant code (and in @cintaccs app) that triggers a virtualizer update after disconnection so that we can make some more realistic tests.

I do see that there's a set items in your stack trace. Do you know why that would be happening after (or concurrently with) the view change that causes the virtualizer to disconnect?

@steverep
Copy link
Contributor Author

@graynorton based on my testing, I would suggest you set this._childrenRO = null per my last reply. I find that the problem is much more reproducible after doing that.

In trying to create a minimal repro was, I have tried various ways of toggling between a view with a virtualizer and a view without a virtualizer. However, the only way I've been able to end up in _correctScrollError without a ScrollerController present is really contrived: I intentionally trigger a virtualizer update (by setting its items property to a different value) at the same time as I'm triggering the view update that will cause the virtualizer to be disconnected.

Yeah, I think that's more or less what is happening.

I do see that there's a set items in your stack trace. Do you know why that would be happening after (or concurrently with) the view change that causes the virtualizer to disconnect?

Nope, the only thing I've narrowed down is that it only seems to error when we have the data filtered, and that means a web worker is involved in returning the reactive property that holds the items. Although I don't immediately see why that would be a problem.

I'll amend my last post with the full stack trace. It actually seems to be looping inside lit for a couple update cycles, so maybe the items were actually set long before? 😕

@steverep
Copy link
Contributor Author

steverep commented Oct 1, 2023

The good news is that it should probably be fairly straightforward to short-circuit the virtualizer update cycle in the case where it is not currently connected.

I'm looking at how to implement that, but how far upstream which would still be safe is not obvious to me. Certainly stopping at the start of this._updateDOM would work, but are you thinking further?

@cintaccs
Copy link

cintaccs commented Oct 2, 2023

@cintaccs In your case (as described in #4238), can you explain how and why the virtualizer is being destroyed / disconnected when the data provided by the containing view changes? I would expect the virtualizer to rerender, but not disconnect.

The virtualizer is within a child component of the page that is being refreshed. In order to ensure that the content is really refreshed one of the parents are re-created. In some earlier lit versions at least - this was the only way I could figure out to get the page to refresh. Later the virtualizer was introduced in the child list component. (where the list component is a child of the page component...).

From my point of view - I wouldn't consider it bad to check for existence before destroying .... I guess destroy could happen for a lot of difference reasons - navigating away etc.

@graynorton
Copy link
Contributor

@steverep My apologies—of course! The screenshot was a dumb way to share the diff in the first place.

diff --git a/packages/labs/virtualizer/src/Virtualizer.ts b/packages/labs/virtualizer/src/Virtualizer.ts
index f7fb07c8..7ba732f8 100644
--- a/packages/labs/virtualizer/src/Virtualizer.ts
+++ b/packages/labs/virtualizer/src/Virtualizer.ts
@@ -549,8 +549,16 @@ export class Virtualizer {
     }
   }
 
+  _shouldUpdateLayout() {
+    // Only update the layout and trigger a re-render if we have...
+    //   a) A layout
+    //   b) A scrollerController, which means we're connected
+    //   c) An offsetParent, which means we're not hidden
+    return this._layout && this._scrollerController && this._hostElement?.offsetParent;
+  }
+
   _updateLayout() {
-    if (this._layout) {
+    if (this._shouldUpdateLayout()) {
       this._layout!.items = this._items;
       this._updateView();
       if (this._childMeasurements !== null) {

@steverep
Copy link
Contributor Author

steverep commented Oct 2, 2023

@graynorton I can test with HA later tonight and let you know.

Regarding no other changes, correct me if I'm missing something, but wouldn't the changes in this branch still be necessary as a safeguard? Your change may catch most issues, but it doesn't guarantee the timing, i.e. a disconnect can still happen after that checkpoint.

@graynorton
Copy link
Contributor

@steverep I don’t believe so, if everything is working as designed. The fact there is no guard code there is actually intentional, so we don’t inadvertently mask more serious issues, like the unnecessary render that #4182 revealed.

We can and should still remove the truly redundant non-null assertions you noticed in other spots, though.

@graynorton
Copy link
Contributor

@steverep I’ll add that I’m very much open to being proven wrong, but before we go and guard against it on a blanket basis, I’d really like to have a concrete, understandable repro that shows how a disconnection might occur in the middle of a virtualizer update cycle. I believe the timing of the mutation and resize observers makes this unlikely or impossible, but I’m not 100% sure.

@steverep
Copy link
Contributor Author

steverep commented Oct 3, 2023

@graynorton I tested HA last night and was unable to reproduce the error with just your change. 👍🏻

I'll admit my gut is still telling me the timing cannot be guaranteed once _updateDOM fires, but I'll defer to your judgement as you obviously understand the code much better than me. Time will tell anyway, because if there's a way to break it, HA users will find it. 😉

To that end, I reverted the controller and observer checks here. The only thing I kept (other than the removal of non-null assertions) was nullifying the the observers on disconnect. I would argue that's still a worthwhile change as, to your point, it would cause earlier failures after a disconnect by making sure re-observations cannot occur (as was happening here with _childrenRO).

Do you want to add your change here or shall I change the commit message to reflect it as is?

@cintaccs
Copy link

cintaccs commented Oct 4, 2023

@cintaccs thank you for your response!

The virtualizer is within a child component of the page that is being refreshed. In order to ensure that the content is really refreshed one of the parents are re-created. In some earlier lit versions at least - this was the only way I could figure out to get the page to refresh. Later the virtualizer was introduced in the child list component. (where the list component is a child of the page component...).

From what you've reported, it seems most likely that the "old" virtualizer (the descendant of the ancestor view that is being replaced) is somehow receiving property updates that trigger it to re-render, despite no longer being present in the document's DOM tree. This is a case we should be handle better regardless, but I would still like to understand as clearly as I can the patterns that cause it to occur and write minimal but realistic tests representing these patterns. With that goal in mind, here are a couple of follow-up questions for you:

  • Am I understanding correctly that the ancestor element is not just re-rendered, but actually destroyed and recreated? How is this achieved?
  • By what means does the virtualizer receive its data? For instance, is the items property simply populated by properties flowing down the tree of rendered components, or is the virtualizer (or a detached ancestor) subscribed to async updates via some other means?

hmm.. I wish it was simple to answer.
The challenge here is that in the original design of components (early lit days) I had issues triggering a re-render when switching views on the same data model (i.e. switching from cards to list view on the same data - OR - switching in-between different sets of filters for the listings). Also the UI is created to not flicker blank white pages so the header will stay the sub-header might stay - the body of the list will either refresh or be replaced with another type of view etc.

In general I am using the properties of the lit element class components - normal use I would think - however some of these properties are either ARRAYs or OBJECTS and also might be delayed with a event UP and await down flow...

The virtualizer is not subscribing in itself to this - it just knows the items array ...

@graynorton
Copy link
Contributor

Thanks, @steverep!

To that end, I reverted the controller and observer checks here. The only thing I kept (other than the removal of non-null assertions) was nullifying the the observers on disconnect. I would argue that's still a worthwhile change as, to your point, it would cause earlier failures after a disconnect by making sure re-observations cannot occur (as was happening here with _childrenRO).

Agreed!

Do you want to add your change here or shall I change the commit message to reflect it as is?

I am flexible on this. I guess it might be somewhat simpler to go ahead and land your improvements first, then have me make a follow-up PR with my change (and likely also some new tests)—only because that way, we don't need to worry about permissions for me to push to your fork, etc.

Another possibility would be for you to just go ahead and apply my patch to your fork so that it ends up here; that would be fine with me if it works for you. Just let me know what you prefer!

Regardless, I personally won't have much time with my computer for the next few days, as I'm about to head out on a trip. I'm hoping there will be some downtime that I can spend to advance this, but in the worst case it would be next Tuesday or Wednesday before I was able to get back to it. I should be able to keep my eye on the discussion here, though.

@graynorton
Copy link
Contributor

@cintaccs

hmm.. I wish it was simple to answer.

No worries! Thanks for the additional background. I suspect that the changes Steve and I have identified in this PR will fix the issue for you as well. If it would be feasible for you to try applying my patch to your local setup, that would be great. But if not, that's fine—you can wait until the changes land and let us know if you're still seeing the problem then.

@steverep steverep changed the title fix(labs/virtualizer): check for null controller when correcting scroll error fix(labs/virtualizer): guard against layout updates or re-observing when disconnected Oct 5, 2023
@steverep
Copy link
Contributor Author

steverep commented Oct 5, 2023

@graynorton I went ahead and applied your patch with a minor refactoring because your "should" method confusingly didn't return a boolean and it would just force back more non-null assertions. Rather than adjust that I just incorporated the check into _updateLayout. Hope that's okay.

If so, I suppose this is ready to go.

Copy link
Contributor

@graynorton graynorton 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! I requested an update to the change description, and I believe this branch also needs to merge the latest changes from main (or be rebased). I approve merging this PR once those changes have been made.

The only other thing I’d like to do is add some tests, but I’m happy to do that in a separate PR.

@steverep
Copy link
Contributor Author

Whenever this is merged and released, it's now going to be difficult to incorporate without first upgrading to lit 3.0. The choice to only have a patch release 2.0.8 after updating the lit dependency doesn't make sense to me.

@justinfagnani
Copy link
Collaborator

@steverep

The choice to only have a patch release 2.0.8 after updating the lit dependency doesn't make sense to me.

Can you explain what you mean here? Making this a minor release wouldn't help, would it?

@steverep
Copy link
Contributor Author

Can you explain what you mean here? Making this a minor release wouldn't help, would it?

No, this PR should definitely only be a patch. My point was that the just released 2.0.8 now has a direct dependency on lit 3.0, with no inclusion of 2.x versions. That makes it a breaking change IMO, and the new virtualizer version should have been 3.0 (unless it still supports lit 2.0 in which case the manifest should be updated).

Right now, you cannot update to 2.0.8 without also updating lit to 3.0 unless you bundle 2 different lit versions which I wouldn't dare do (home-assistant/frontend#18206).

@graynorton graynorton merged commit f84963d into lit:main Oct 13, 2023
@graynorton
Copy link
Contributor

That makes it a breaking change IMO, and the new virtualizer version should have been 3.0 (unless it still supports lit 2.0 in which case the manifest should be updated).

Agreed. I went ahead and merged this PR; will make a separate one to update the version range for the lit dependency.

@steverep steverep deleted the fix-scroller-controller-null-check branch October 13, 2023 23:54
This was referenced Oct 27, 2023
// Only update the layout and trigger a re-render if we have:
// a) A layout
// b) A scrollerController, which means we're connected
// c) An offsetParent, which means we're not hidden
Copy link

@bramkragten bramkragten Nov 9, 2023

Choose a reason for hiding this comment

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

This will be null if the hostElement has a parent that is positioned fixed (in chrome, in firefox it returns body). The virtualizer doesn't render inside a mwc-dialog anymore now for example in chrome.

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

Labels

None yet

Projects

None yet

6 participants