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
The installation process of VMwarea will not be d...
The effect of this function is similar to vue的pro...
1. Pull the image docker pull registry.cn-hangzho...
Table of contents Document Object Model (DOM) DOM...
After configuring VIP, the error message that app...
CSS: 1. <link type="text/css" href=&q...
Table of contents What is a trigger Create a trig...
Table of contents Preface text Primitive types Pr...
Table of contents 1. Vue3 component communication...
In this chapter, we will start to operate redis i...
Table of contents 1. Signal List 1.1. Real-time s...
The above article has temporarily concluded my int...
Table of contents mvc mvp mvvm The source of Vue ...
question Recently, when I was completing a practi...
Form validation is one of the most commonly used ...