Git Product home page Git Product logo

preact-virtual-list's Introduction

<VirtualList /> for Preact

NPM Travis

A "virtual" list component that renders only visible rows of a given data set.

Useful for those super important business applications where one must show all million rows.

preview

Usage Example

Provide the list of items as data, an item renderer as renderRow, and the height of a single row as rowHeight. Everything else is optional.

<VirtualList
    data={['a', 'b', 'c']}
    renderRow={ row => <div>{row}</div> }
    rowHeight={22}
    overscanCount={10}
    sync
/>

Props

Prop Type Description
data Array List of data items
renderRow Function Renders a single row
rowHeight Number Static height of a row
sync Boolean If true, forces synchronous rendering *
overscanCount Number Number of extra rows to render above and below visible list. Defaults to 10. **

* About synchronous rendering: It's best to try without sync enabled first. If the normal async rendering behavior is fine, it's best to leave sync turned off. If you're seeing flickering, enabling sync will ensure every update gets out to the screen without dropping renders, but does so at the expense of actual framerate.

** Why overscan? Rendering normalized blocks of rows reduces the number of DOM interactions by grouping all row renders into a single atomic update.

Without Overscan With Overscan

Simple Example

View this example on JSFiddle

import VirtualList from 'preact-virtual-list';

// Generate 100,000 rows of data
const DATA = [];
for (let x=1e5; x--; ) DATA[x] = `Item #${x+1}`;

class Demo extends Component {
    // 30px tall rows
    rowHeight = 30;

    // Renders a single row
    renderRow(row) {
        return <div class="row">{row}</div>;
    }

    render() {
        return (
            <VirtualList sync class="list"
                data={DATA}
                rowHeight={this.rowHeight}
                renderRow={this.renderRow}
            />
        );
    }
}

render(Demo, document.body);

Functional Example

View this example on JSFiddle

import VirtualList from 'preact-virtual-list';

// Generate 100,000 rows of data
const DATA = [];
for (let x=1e5; x--; ) DATA[x] = `Item #${x+1}`;

// renders a single row
const Row = row => (
    <div class="row">{row}</div>
);

render((
    <VirtualList data={DATA} rowHeight={30} renderRow={Row} />
), document.body);

License

MIT

preact-virtual-list's People

Contributors

developit avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

preact-virtual-list's Issues

Millions?

Hi @developit, was looking through the list of Preact Libraries & Add-ons and was struck by the phrasing that this library can handle "millions". I went to the demo to try with my browser, which took a while to load, I figured because it was generating a lot of data, but turns out it was only 100k rows... I'm skeptical this can handle the amount advertised.

Most of my skepticism is due to my experiments with HyperList a vanilla-js virtual scrolling tool, that has a demo w/ 2 million rows. This was incredibly hard to test and won't even work in some browsers due to max element height issues. Basically if you want a native scrollbar, you cannot have millions of rows working across various browsers. React Virtualized "solves" this, but not in an elegant way and severely breaks scrolling with the mouse (tries to offset more items based on where you are in the vertical scroll).

Just looking for clarification here. Is this library doing something different making it capable of rendering "millions", or is it just a marking claim that should be adjusted?

Thanks for your time!

scrollToIndex is missing

It would be great if you could add scrollToIndex property which will show list starting from index x.

Thank you.

Instead of a data prop, allow for an item getter function

I implemented something similar to this and if you truly are going to make 1M rows available for scrolling, you definitely don't want them all in memory at the same time.

The way I got around this was to have my component accept a getRow() function that when called with an index returns a Promise. When the promise resolves, the data is then popped into the listview. If the row is already in the backing store, it's easy enough to ship a pre-resolved Promise. You'd use a storage pattern like an LRU to keep overall memory impact low.

Cheers!

onScroll event swallowed after upgrade to preact 8.x

The onScroll on my top level element does not get triggered anymore after upgrade to 8.x.

<div id="music-sources-container" onScroll={this._onScroll.bind(this)}>
	{headlineNodes}
	<ul id="browser-container">
	    <VirtualList
	        rowHeight={50} sync={true} class="scrollcontainer"
		data={[actionNodes].concat(listItemNodes)}
		renderRow={this._renderRow.bind(this)}
		>
	     </VirtualList>
    </ul>
</div>

Can't build after `git clone`

After fresh git clone and npm install or manual npm run build I get this error:

$ npm run build

> [email protected] build /home/gabriel/opt/preact-virtual-list
> npm-run-all transpile optimize minify


> [email protected] transpile /home/gabriel/opt/preact-virtual-list
> rollup -c rollup.config.js -m ${npm_package_main}.map -f umd -n $npm_package_amdName $npm_package_jsnext_main -o $npm_package_main

resolve failed for "babel-runtime": Error: Cannot find module 'babel-runtime'
Treating 'preact' as external dependency
No name was provided for external module 'preact' in options.globals โ€“ guessing 'preact'
Bad sourcemap
Error: Bad sourcemap
    at Object.traceSegment (/home/gabriel/opt/preact-virtual-list/node_modules/rollup/www/ROLLUP/rollup/src/utils/collapseSourcemaps.js:75:26)
    at /home/gabriel/opt/preact-virtual-list/node_modules/rollup/www/ROLLUP/rollup/src/utils/collapseSourcemaps.js:31:27
    at Array.forEach (native)
    at /home/gabriel/opt/preact-virtual-list/node_modules/rollup/www/ROLLUP/rollup/src/utils/collapseSourcemaps.js:29:9
    at Array.map (native)
    at Object.traceMappings (/home/gabriel/opt/preact-virtual-list/node_modules/rollup/www/ROLLUP/rollup/src/utils/collapseSourcemaps.js:26:34)
    at collapseSourcemaps (/home/gabriel/opt/preact-virtual-list/node_modules/rollup/www/ROLLUP/rollup/src/utils/collapseSourcemaps.js:102:37)
    at Bundle.render (/home/gabriel/opt/preact-virtual-list/node_modules/rollup/www/ROLLUP/rollup/src/Bundle.js:280:11)
    at Object.write (/home/gabriel/opt/preact-virtual-list/node_modules/rollup/www/ROLLUP/rollup/src/rollup.js:62:32)
    at /home/gabriel/opt/preact-virtual-list/node_modules/rollup/bin/runRollup.js:138:18
Type rollup --help for help, or visit https://github.com/rollup/rollup/wiki

Clarification - how does overscan reduce DOM operations?

Is it my understanding from reading the code that overscan will "align" the {startIndex, endIndex} to modulo overscan. However, I can't really see how this reduces any work in the DOM - if a continuous scroll operation results in adding 10 rows, sync mode would add them one by one (in the worst case) and overscan mode would add something like 10 rows in one operations. That sounds to me like the same "amortized" amount of work. Could you please elaborate on why this approach is more performant in terms of DOM operations?

Note: I do see an obvious perf optimization in not reconciling the entire visible viewport on each scroll event - but if I understand it correctly that is only VDOM work.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.