preface

Hot stock list has more than 4000, rendering the page in the plate is updated in real time, if the interface and paging, when you get pulled dozens of pages of the page will be more and more CARDS and also updated in real time, the final approach is to first data from the ws passed, we only need to pass the start and end the subscript subscript, We only generate a few tags on the page. Greatly reduced rendering stress.

What is a virtual list?



Just render the tabs in the viewable area, constantly switching the start and end subscripts as you scroll to update the view, while calculating the offset.

Effect of the demo

The preparatory work

  • Calculate how many lists can be displayed on a screen.
  • The height of the box.
  • Start position in scroll.
  • End position in scroll.
  • Roll offset.

Screen height & box height

In the applet we can use wx.createSelectorQuery to get the height of the screen and the height of the box.

getEleInfo( ele ) {
    return new Promise( ( resolve, reject ) = > {
        const query = wx.createSelectorQuery().in(this);
        query.select( ele ).boundingClientRect();
        query.selectViewport().scrollOffset();
        query.exec( res= >{ resolve( res ); })})},this.getEleInfo('.stock').then( res= > {
    if(! res[0]) retuen;
    / / screen
    this.screenHeight = res[1].scrollHeight;
    // Box height
    this.boxhigh = res[0].height;
})
Copy the code

Start & end & offset

onPageScroll(e) {
    let { scrollTop } = e;
    this.start = Math.floor(scrollTop / this.boxhigh);
    this.end = this.start + this.visibleCount;
    this.offsetY = this.start * this.boxhigh; 
}
Copy the code

ScrollTop can be understood as how many boxes have been rolled from the top/box height = start subscript start + How many boxes can be displayed in the page viewable area = end start * box height = offset

computed: {
    visibleData() {
        return this.data.slice(this.start, Math.min(this.end, this.data.length))
    },
}
Copy the code

We use slice(this.start,this.end) to change data when start and end change, so that the tag’s contents can be replaced in time.

To optimize the

  1. The reason why there’s a blank area at the bottom when we scroll fast is because the data hasn’t been loaded yet, so we can do thatThree screen renderingTo ensure that the slide data load more timely.
prevCount() {
    return Math.min(this.start, this.visibleCount);
},
nextCount() {
    return Math.min(this.visibleCount, this.data.length - this.end);
},
visibleData() {
    let start = this.start - this.prevCount,
        end = this.end + this.nextCount;
    return this.data.slice(start, Math.min(end, this.data.length))
},
Copy the code

Box-high = this.start * this.boxHigh – this.boxHigh * this.prevCount

  1. Sliding timestart,end,offsetYIt’s changing all the time. It’s calling a lotsetData, it is likely to cause the small program memory out of flash back, here we do a throttling when sliding, dilutionsetDataFrequency of execution.
    mounted() {
        this.deliquate = this.throttle(this.changeDeliquate, 130)},methods: {
        throttle(fn, time) {
            var previous = 0;
            return function(scrollTop) {
                let now = Date.now();
                if( now - previous > time ) { fn(scrollTop) previous = now; }}},changeDeliquate(scrollTop) {
            this.start = Math.floor(scrollTop / this.boxhigh);
            this.end = this.start + this.visibleCount;
            this.offsetY = this.start * this.boxhigh; 
            console.log('execution setData')}},onPageScroll(e) {
	let { scrollTop } = e;
        console.log('scroll = = = = = = = = = = = = = = = = > > > > > > >')
        this.deliquate(scrollTop);
    }

Copy the code

As you can see from the figure above, almost every scroll reduces setData by at least two writes.

The article prepares the demo here, has the need can carry on the reference.