question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Support just-in-time measured content

See original GitHub issue

In order to avoid adding cost to existing list and grid components, create a new variant (e.g. DynamicSizeList and DynamicSizeGrid). This variant should automatically measure its content during the commit phase.

MVP

The initial implementation of this could work similarly to how CellMeasurer works in react-virtualized:

  1. Content is measured only if no current measurements exists.
  2. Measurements need to be reset externally (imperatively) if something changes.
  3. Cells at a given index can only be positioned after all cells before that index have been measured.

Goal

This component could perform better if we removed the third constraint above, allowing random access (by either item index or scroll offset) without measuring the preceding items. This would make react-window much more performant for use cases like chat applications.

This would also unlock the ability to use a ResizeObserver (via react-measure) to automatically detect item sizing and remove the position and measurements cache entirely. This would remove the need for imperatively resetting cached measurements and dramatically improve the API.

In order for the above to be possible, the dynamic list/grid components would need to use a dramatically different approach for mapping offset to index and vice versa. (This comment about “scroll anchoring” in react-virtualized has some nice visuals.) Essentially, we would need to do something like this:

  • Estimate total size based on the number of items multiplied by a estimatedItemSize prop. (This estimated size won’t need to be adjusted, since the mapping described below doesn’t is fuzzy.)

  • When scroll position changes, compare the new offset to the previous offset. If the delta is greater than some [to be determined] threshold, set the new offset as the “scroll anchor”. Map the offset to an estimated index (e.g. divide the offset by total estimated scrollable size and multiply that by the number of items in the collection). Store this mapped index as the “anchor index”. For example, if the list described by the image below had 250 items, the “anchor index” would be 132.

screen shot 2018-06-10 at 11 58 38 am
  • When scroll position changes, if the delta is less than the threshold, choose which new items to render relative to the anchor index. Position these items relative to the previously positioned items. Continuing with the example above, if the list was scrolled by a small amount (200px) then 200px worth of additional rows would need to be appended below the previously positioned items:
screen shot 2018-06-10 at 12 01 01 pm

The above approach has only one major downside: aligning items correctly at list boundaries. If item indices are estimated (as described above) then they likely won’t line up exactly with the beginning or end of the scrollable area.

  • The end could potentially be accounted for by adjusting the total estimated size as the user scrolls closer to the end (although this might make scrolling feel janky).

  • The start of the list is harder to handle, since the first item needs to align with offset zero while still appearing to connect contiguously with items from some offset greater than zero. Perhaps another threshold could be used, a “safe zone”, near the start of the list (e.g. if the scroll offset is less than some absolute value) which would force the list to measure all cells up to that point so they align correctly. The cost of this forced measurement would be relatively low, since it would only be a small number of items. screen shot 2018-06-10 at 5 04 42 pm

The one case that would still not be handled correctly with the above approach would be a scroll anchor that is set outside of the “safe zone” but a current scroll that goes inside of the safe zone (as shown below). If the user scrolls slowly back toward the beginning of the list, it may be difficult to align the first cell with zero without introducing scroll janky. screen shot 2018-06-10 at 5 08 26 pm

Issue Analytics

  • State:open
  • Created 5 years ago
  • Reactions:297
  • Comments:138 (30 by maintainers)

github_iconTop GitHub Comments

47reactions
bvaughncommented, Aug 18, 2019

There is no “you guys” on this project. It’s maintained by a single person.

And it’s kind of inconsiderate to leave comments on multiple issues in the same day complaining about the same thing. By all means, please just use react-virtualized.

46reactions
milieucommented, Mar 11, 2019

@bvaughn Thank you for all of the work that has gone in the issues/6 branch for the past year! I am currently testing ^1.6.0-alpha.1 and plan on shipping to production with that version.

Thought I’d post what I needed to do in order to work with the new DynamicSizeList for anyone else looking at this issue and using the latest on the branch.

Following the docs linked above and those generated from the issues/6 branch will lead to

Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?

and so the fix was to imitate what you do in tests and…

import { DynamicSizeList as List } from 'react-window';
import AutoSizer from 'react-virtualized-auto-sizer';

// in constructor(props) for handling scrolling
this.listRef = React.createRef();

// in render()
const allItems = [...];
const Renderer = ({ forwardedRef, style, index, ...rest }) => (
  <div ref={forwardedRef} style={style}>
    <MyCoolComponent index={index} otherProps={otherPropsBasedOnAllItems} />
  </div>
);

const RefForwarder = React.forwardRef((props, ref) => (
  <Renderer forwardedRef={ref} {...props} />
));

return <div style={{ display: 'flex', flexDirection: 'column', height: '100%' }}>
  <div style={{ flexGrow: 0, flexShrink: 0, width: '100%', position: 'sticky', top: 0, zIndex: zIndexHideLayers }}>
    <MyCoolComponentThatControlsScrolling listRef={this.listRef} />
  </div>
  <div style={{ flex: 1, width: '100%' }}>
    <AutoSizer>
      {({ height, width }) => (
        <List ref={this.listRef} itemCount={allItems.length} width={width} height={height}>
          {RefForwarder}
        </List>
      )}
    </AutoSizer>
  </div>
</div>;

My example probably includes more than what you’d want on that docs page, but hopefully will make the doc update easier for you

Feedback on the current version of the branch? 💯 works well 🎉 thanks again for all the work!

edit: DynamicSizeList seriously makes this library so easy to use now.

Read more comments on GitHub >

github_iconTop Results From Across the Web

"Just in Time" Web-based Training - SAMHSA
This web-based training is designed to provide crisis counselors, supervisors, and team leaders with a basic understanding of the Crisis ...
Read more >
Just-in-Time (JIT): Definition, Example, and Pros & Cons
A just-in-time (JIT) inventory system is a management strategy that aligns raw-material orders from suppliers directly with production schedules.
Read more >
Just in Time Training: Definition, Benefits, and Examples
Learn what's so special about just in time training, ... Here are a few ideas to help you measure the effectiveness of JIT...
Read more >
Just-in-Time Teaching - CITL
Just-in-time teaching actively involves students in the learning process through ... more student responsibility for learning the content outside of class, ...
Read more >
"Application does not support just-in-time (JIT) debugging ...
When launching AutoCAD products the prompt " Application does not support just-in-time (JIT) debugging" comes up.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found