Whether in the real project development or in the interview, the optimization processing method of the front-end is very important. How to render the real long list and thousands of data lists?
First of all, the most common is the front-end and back-end paging. If there are 1000 pieces of data, the front end needs to add the total number of pages and the current number of pages after using ajax to send some necessary data. At this time, if the agreement is 10 pages, then the front end only obtains the 10 pieces of data of the current page. After jumping to different pages, get 10 pieces of data on different pages. This is the simplest processing method, but this method also has its obvious disadvantages. If you want to search for data across pages, you need to open up new storage space for storage. In the actual situation, there are even cases where paging is not possible. How to optimize this?
First, a time slicing method is introduced,
The core idea of time slicing is that if there is a long task that cannot be completed within 50ms (loading and rendering of 100000 data), in order not to block the main thread, the task should give up the control of the main thread so that the browser can handle other tasks. Giving up control means stopping the execution of the current task, letting the browser execute other tasks, and then coming back to continue the unfinished tasks.
//Containers to be inserted let ul = document.getElementById('container'); // Insert 100000 data let total = 100000; // Insert 20 at a time let once = 20; //PageCount let page = total/once //Index of each record let index = 0; //Cyclic loading data function loop(curTotal,curIndex){ if(curTotal <= 0){ return false; } //How many articles per page let pageCount = Math.min(curTotal , once); setTimeout(()=>{ for(let i = 0; i < pageCount; i++){ let li = document.createElement('li'); li.innerText = curIndex + i + ' : ' + ~~(Math.random() * total) ul.appendChild(li) } loop(curTotal - pageCount,curIndex + pageCount) },0) } loop(total,index);
As shown in the above code, we use setTimeout to load 20 pieces of data at a time. Each setTimeout is a macro task. In the browser's execution mechanism, rendering will be performed after a round of macro tasks is not performed. In this way, rendering can be realized after every 20 pieces of data are loaded, without causing the main thread to be occupied all the time.
The second method is virtual list
The core idea of this method is to get all the data now, but only render the visible part of the window. I don't want to say much. Above
There are 1000 pieces of data in total, and we only render 10 of them visible at a time. As shown in the figure, 0-9 is displayed. As the scroll wheel moves down, we will render the 10 pieces of data that can be seen on the screen at that time. That is to say, only 10 pieces of data are displayed at the same time, which reduces the dom operation and optimizes the performance.
Let's analyze the code
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <style type="text/css" rel="stylesheet"> //Analyze css part .content{ background-color: orangered; overflow:auto; //This is for the roller to appear width: 50vw; height: 500px; //One piece of data is 50px high, and the visual window is 500px. One page can put 10 pieces of data margin-left: 25vw; } .target{ height: 50000px; //The length that the whole pulley can roll, that is, it can store 1000 pieces of data box-sizing: border-box; //Here, you need to adjust the box model, and then set the offset with the padding top attribute. } </style> </head> <body> <div class="content" > <!-- div The label is a visual window --> <ul class ="target"> <!-- ul The label is the total sliding length --> <!-- li The label is placed in it to store the singleton data --> </ul> </div> </body> <script> let datalength = 10; //Display data per page let data = []; //A total of 1000 pieces of data are stored in an array let showdata = []; //10 pieces of data to be rendered, array storage let topdistance = 0; //Record offset let first; //Index of the first data let end; //Tail bar data index for(let i = 0;i<1000;i++){ data.push(i); } let div = document.querySelector('.content'); let ul = document.querySelector('ul'); myscroll() //First screen rendering data div.onscroll = myscroll function myscroll(e){ ul.innerHTML = ''; //Empty content before each rendering topdistance = e?e.target.scrollTop:0; //Manually set offset ul.style.paddingTop = topdistance+'px'; //Assign the offset to paddingTop. Note that if the above css box model is not set, the roller will slide all the time, and the height of ul will be infinitely elongated let index = Math.floor(topdistance/50); //Judge where to intercept according to the offset first = index; end =index+datalength; showdata = data.slice(first,end); //Intercept native data const dom = document.createDocumentFragment(); let li = null; //The dom node is operated to render showdata.map((item)=>{ li = document.createElement('li'); li.style.height = '50px'; li.innerHTML = item; dom.appendChild(li); }) ul.appendChild(dom); } </script> </html>