PolymerElements / iron-list

Element for a virtual, "infinite" list
https://www.webcomponents.org/element/PolymerElements/iron-list
219 stars 131 forks source link

Physical items can grow unbounded when scrolling heterogeneously-sized list #559

Closed kevinpschaaf closed 5 years ago

kevinpschaaf commented 5 years ago

Description

iron-list can suffer from a runaway condition where _increasePoolIfNeeded can loop indefinitely due to the physical average becoming large enough (due to heterogeneously-sized items) to position the physical top lower than the scroll position, causing _isClientFull to return true.

Expected outcome

Count of physical items never grows significantly larger than needed to cover the viewport.

Actual outcome

Count of physical items grows close to the virtual size of a large virtual list.

Live Demo

https://glitch.com/edit/#!/circular-breeze?path=index.html

Steps to reproduce

  1. Create list with large items array and heterogeneously-sized items
  2. Scroll to a point in the list such that the physical average becomes larger than at the start of the list
  3. Scroll back to the top of the list; if the physical average is significantly large enough, _scrollHandler will reset the _physicalTop to a value larger than the _scrollPosition.
  4. Fire an iron-resize event at the list. This will cause _increasePoolIfNeeded to check _isClientFull, which will return falsey because the items don't cover the viewport, and will loop indefinitely.

This bug appears to have been at least partially introduced in https://github.com/PolymerElements/iron-list/pull/435/files, where the _physicalTop is re-calculated purely as a function of physicalAverage, losing a guarantee that the _physicalTop is no longer above the start of the scroll position.

This could also explain some reported issues in https://github.com/PolymerElements/iron-list/issues/506 (although the OP of that issue seems to have been a user error with list sizing, others report similar runaway physical item creation behavior with a correctly sized list). I created a separate issue here since a GIF posted in that issue appears to have uniformly-sized items, and I believe this particular bug only occurs when the _physicalAverage used for estimation random-access scrolling becomes significantly larger than the physical items in the viewport.

Browsers Affected