What is a virtual list?

Rendering a part of a long list of data according to the visual area of the scrolling container, i.e., on-demand rendering of a long list

Performance cost of plain long lists

Start by creating a plain long list of 5000 items

import React from 'react' export default class App extends React.Component { constructor (props) { super(props) this.state = { complexDOMs: [] } this.onCreateComplexDOMs = this.onCreateComplexDOMs.bind(this) } onCreateComplexDOMs () { this.setState({ complexDOMs: Array.from(Array(5000).keys()) }); } render () { const {complexDOMs}=this.state; return ( <div style={{ marginLeft: '10px'}}> <h3>Creat large of DOMs: </h3> <button onClick={this.onCreateComplexDOMs}>Create Complex DOMs</button> <div>{complexDOMs.map((item) => { return (  <div key={item}> <p>#${item} eligendi voluptatem quisquam</p> <p> Modi autem fugiat maiores. Doloremque est sed quis qui nobis. Accusamus dolorem aspernatur sed rem. </p> </div> ); })}</div> </div> ) } }import React from 'react' function createMarkup (doms) { return doms.length ? { __html: doms.join(' ') } : { __html: '' } } export default class App extends React.Component { constructor (props) { super(props) this.state = { complexDOMs:  [] } this.onCreateComplexDOMs = this.onCreateComplexDOMs.bind(this) } onCreateComplexDOMs () { const array = [] for (var i = 0; i < 5000; i++) { array.push(` <div class='list-item'> <p>#${i} eligendi voluptatem quisquam</p> <p>Modi autem fugiat maiores. Doloremque est sed quis qui nobis. Accusamus dolorem aspernatur sed rem.</p> </div> `) } this.setState({ complexDOMs: array }) } render () { return ( <div style={{ marginLeft: '10px'}}> <h3>Creat large of DOMs: </h3> <button onClick={this.onCreateComplexDOMs}>Create Complex DOMs</button> <div dangerouslySetInnerHTML={createMarkup(this.state.complexDOMs)} /> </div> ) } }Copy the code



Consumes 808 ms



Display the above list using virtual list technology

import React from "react"; export default class App extends React.Component { constructor(props) { super(props); This. state = {complexDOMs: [], start: 0, end: 0}; this.containerRef = React.createRef(); this.onCreateComplexDOMs = this.onCreateComplexDOMs.bind(this); } componentDidMount() { this.calculateRange(); GetOffset = (scrollTop) => {return math.floor (scrollTop / 79); }; GetViewCapacity = (containerHeight) => {return math.ceil (containerHeight / 79); }; // When triggering scroll, real-time update display range calculateRange = () => {const overscan = 10; / / is not in the display area of the buffer value const ele = this. ContainerRef. Current; if (ele) { const offset = this.getOffset(ele.scrollTop); Const viewCapacity = this.getViewCapacity(ele.clientheight); // The number of list items that the display area can hold const from = offset-overscan; // which one to start showing const to = offset + viewCapacity + overscan; This.setstate ({start: from > 0? from : 0, end: to < 5000 ? to : 5000 }); }}; onCreateComplexDOMs = (e) => { e && e.preventDefault(); this.setState({ complexDOMs: Array.from(Array(5000).keys()) }); }; render() { const { start, end, complexDOMs } = this.state; return ( <> <button onClick={this.onCreateComplexDOMs}>add virtualList</button> <div className="container" ref={this.containerRef} onScroll={this.calculateRange} style={{ height: "200px", overflow: "Auto"}} > {/* Estimate the Wrapper height, Margintop Set the wrapper distance to the top */} <div className="wrapper" style={{height: complexDOMs.length * 79 - start * 79, marginTop: Start * 79}} > {/* display visible range list items */} {complexDOMs. Slice (start, complexDOMs) end).map((item) => { return ( <div key={item}> <p>#${item} eligendi voluptatem quisquam</p> <p> Modi autem fugiat maiores. Doloremque est sed quis qui nobis. Accusamus dolorem aspernatur sed rem. </p> </div> ); })} </div> </div> </> ); }}Copy the code

Test it out using Performace



Only 16.7ms was consumed

Reference article: github.com/dwqs/blog/i…