Let’s talk about this today. If the backend really returns 100,000 pieces of data to the frontend, how can we display them elegantly on the frontend? Preliminary workDo the preliminary work first, then you can test it later. Backend construction Create a new If // server.js const http = require('http') const port = 8000; http.createServer(function (req, res) { // Enable Cors res.writeHead(200, { //Set the domain name allowed across domains. You can also set * to allow all domain names. 'Access-Control-Allow-Origin': '*', //Cross-domain allowed request methods, you can also set * to allow all methods "Access-Control-Allow-Methods": "DELETE,PUT,POST,GET,OPTIONS", //Allowed header types 'Access-Control-Allow-Headers': 'Content-Type' }) let list = [] let num = 0 // Generate a list of 100,000 records for (let i = 0; i < 1000000; i++) { num++ list.push({ src: 'https://p3-passport.byteacctimg.com/img/user-avatar/d71c38d1682c543b33f8d716b3b734ca~300x300.image', text: `I am guest number ${num} Lin Sanxin`, tid: num }) } res.end(JSON.stringify(list)); }).listen(port, function () { console.log('server is listening on port ' + port); }) Front-end page First create a new // index.html // Style <style> * { padding: 0; margin: 0; } #container { height: 100vh; overflow:auto; } .sunshine { display: flex; padding: 10px; } img { width: 150px; height: 150px; } </style> // html part <body> <div id="container"> </div> <script src="./index.js"></script> </body> Then create a new // index.js // Request function const getList = () => { return new Promise((resolve, reject) => { //Step 1: Create asynchronous object var ajax = new XMLHttpRequest(); //Step 2: Set the request URL parameters. Parameter 1 is the request type, and parameter 2 is the request URL. You can use ajax.open('get', 'http://127.0.0.1:8000'); //Step 3: Send request ajax.send(); //Step 4: Register the onreadystatechange event. When the state changes, ajax.onreadystatechange = function () { if (ajax.readyState == 4 && ajax.status == 200) { //Step 5 If you can get to this point, it means the data is returned perfectly and the requested page exists resolve(JSON.parse(ajax.responseText)) } } }) } // Get the container object const container = document.getElementById('container') Direct Rendering The most direct way is to render it directly, but this approach is definitely not advisable, because rendering const renderList = async () => { console.time('list time') const list = await getList() list.forEach(item => { const div = document.createElement('div') div.className = 'sunshine' div.innerHTML = `<img src="${item.src}" /><span>${item.text}</span>` container.appendChild(div) }) console.timeEnd('list time') } renderList() setTimeout paging rendering This method is to divide const renderList = async () => { console.time('list time') const list = await getList() console.log(list) const total = list.length const page = 0 const limit = 200 const totalPage = Math.ceil(total / limit) const render = (page) => { if (page >= totalPage) return setTimeout(() => { for (let i = page * limit; i < page * limit + limit; i++) { const item = list[i] const div = document.createElement('div') div.className = 'sunshine' div.innerHTML = `<img src="${item.src}" /><span>${item.text}</span>` container.appendChild(div) } render(page + 1) }, 0) } render(page) console.timeEnd('list time') } requestAnimationFrame Using const renderList = async () => { console.time('list time') const list = await getList() console.log(list) const total = list.length const page = 0 const limit = 200 const totalPage = Math.ceil(total / limit) const render = (page) => { if (page >= totalPage) return // Use requestAnimationFrame instead of setTimeout requestAnimationFrame(() => { for (let i = page * limit; i < page * limit + limit; i++) { const item = list[i] const div = document.createElement('div') div.className = 'sunshine' div.innerHTML = `<img src="${item.src}" /><span>${item.text}</span>` container.appendChild(div) } render(page + 1) }, 0) } render(page) console.timeEnd('list time') } Document fragments + requestAnimationFrameBenefits of Document Fragmentation 1. Previously, 2. The page will only render the elements wrapped by the document fragment, but not the document fragment const renderList = async () => { console.time('list time') const list = await getList() console.log(list) const total = list.length const page = 0 const limit = 200 const totalPage = Math.ceil(total / limit) const render = (page) => { if (page >= totalPage) return requestAnimationFrame(() => { // Create a document fragment const fragment = document.createDocumentFragment() for (let i = page * limit; i < page * limit + limit; i++) { const item = list[i] const div = document.createElement('div') div.className = 'sunshine' div.innerHTML = `<img src="${item.src}" /><span>${item.text}</span>` // First insert the document fragment fragment.appendChild(div) } // One-time appendChild container.appendChild(fragment) render(page + 1) }, 0) } render(page) console.timeEnd('list time') } Lazy Loading For a more popular explanation, let's start a In fact, the implementation principle is very simple. Let's show it through a picture. Put an empty node As for how to determine whether <script setup lang="ts"> import { onMounted, ref, computed } from 'vue' const getList = () => { //Same code as above} const container = ref<HTMLElement>() // container node const blank = ref<HTMLElement>() // blank node const list = ref<any>([]) // list const page = ref(1) // current page number const limit = 200 // one page display // maximum number of pages const maxPage = computed(() => Math.ceil(list.value.length / limit)) // The actual displayed list const showList = computed(() => list.value.slice(0, page.value * limit)) const handleScroll = () => { // Comparison of current page number and maximum page number if (page.value > maxPage.value) return const clientHeight = container.value?.clientHeight const blankTop = blank.value?.getBoundingClientRect().top if (clientHeight === blankTop) { // Blank appears in the view, the current page number increases by 1 page.value++ } } onMounted(async () => { const res = await getList() list.value = res }) </script> <template> <div class="container" @scroll="handleScroll" ref="container"> <div class="sunshine" v-for="(item) in showList" :key="item.tid"> <img :src="item.src" /> <span>{{ item.text }}</span> </div> <div ref="blank"></div> </div> </template> The above is the details of how the front-end can better display the 100,000 pieces of data returned by the back-end. For more information about the front-end display of the 100,000 pieces of data returned by the back-end, please pay attention to other related articles on 123WORDPRESS.COM! You may also be interested in:
|
<<: Element with selection table to change the check box in the header into text implementation code
>>: Summary of Textarea line break issues in HTML
There is a requirement to realize the shaking eff...
Table of contents 1. isPrototypeOf() Example 1, O...
background There is a requirement in the project ...
Preface When developing static pages, such as Vue...
I don't expect to be an expert DBA, but when ...
Table of contents Object.prototype.valueOf() Obje...
Currently, most CPUs support floating-point units...
Preface In the database, some data tables and dat...
This article describes the MySQL single table que...
For websites with an architecture like LNMP, they...
Table of contents Slow query basics: optimizing d...
Table of contents 1. Check the status of the serv...
WeChat applet calculator example, for your refere...
In the field of data analysis, database is our go...
We all know that the performance of applications ...