Performance comparison of large data load page rendering

A, preparation,

Let’s code the address first

The code address

1. Create a folder mkdir bigdata 2. CD BigData Go to the folder 3. Initialize package.json

npm init -y
Copy the code

{
  "name": "bigdata"."version": "1.0.0"."description": ""."main": "index.js"."scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": []."author": ""."license": "ISC"
}

Copy the code

Two, back-end simulation 20W data

1. Create server.js file

// server.js

const http = require('http')
const port = 8000;

http.createServer(function (req, res) {
  / / open Cors
// res.writeHead(200,{'Content-Type':'text/css; charset=UFT8'})
  res.writeHead(200, {
    * Allow all domain names
    'Access-Control-Allow-Origin': The '*'.// Allow request methods across domains, or * allow all methods
    "Access-Control-Allow-Methods": "DELETE,PUT,POST,GET,OPTIONS".// The allowed header type
    'Access-Control-Allow-Headers': 'Content-Type'.'charset':'UFT8'
  })
  let list = []
  let num = 0

  // Generate a list of 100,000 entries
  for (let i = 0; i < 200000; i++) {
    num++
    list.push({
      src: 'https://p3-passport.byteacctimg.com/img/user-avatar/d71c38d1682c543b33f8d716b3b734ca~300x300.image'.text: `I am the ${num} number  man `.tid: num
    })
  }
  res.end(JSON.stringify(list));
}).listen(port, function () {
  console.log('server is listening on port ' + port);
})
Copy the code

Two, the front page

1. Index.html file

<! DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta < span style> * {padding: 0; background-repeat: initial; background-repeat: initial; margin: 0; } #container { height: 100vh; overflow: auto; } .sunshine { display: flex; padding: 10px; } img { width: 150px; height: 150px; } </style> </head> <body> <div id="container"></div> <script src="./index.js"></script> </body> </html>Copy the code

Here’s how to load it without performance optimization

Notice that we switched rendering methods here, inside renderList ()


// request function
const getList = () = > {
    return new Promise((resolve, reject) = > {
        // Step 1: Create an asynchronous object
        var ajax = new XMLHttpRequest();
        // Step 2: Set the request URL parameters. Parameter 1 is the request type, parameter 2 is the request URL, can take parameters
        ajax.open('get'.'http://127.0.0.1:8000');
        // Step 3: Send the request
        ajax.send();
        // Step 4: Register the event onreadyStatechange to be called when the status changes
        ajax.onreadystatechange = function () {
            if (ajax.readyState == 4 && ajax.status == 200) {
                // Step 5 If the judgment can be reached, the data returned perfectly, and the requested page exists
                resolve(JSON.parse(ajax.responseText))
            }
        }
    })
}

// Render directly
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()

// Get the Container object
const container = document.getElementById('container')
Copy the code

Perform back-end services and start the front end

1. Add the command to start the file in package.json before starting

“start”: “node server.js”

{
  "name": "bigata"."version": "1.0.0"."description": ""."main": "index.js"."scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"."start": "node server.js"
  },
  "keywords": []."author": ""."license": "ISC"
}

Copy the code

2. Run the command to start the background service

npm run start
Copy the code
  • Start-up success

3. Front-end start

  • Right-click to launch the default browser

  • Direct start rendering data is too large, the page directly stuck, images can not load out

Perform render performance comparisons

RenderList () is used instead of index.js. After switching the method, refresh the browser to feel the loading experience

1. SetTimeout timer paging rendering

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')}Copy the code

Use the requestAnimationFrame method

Official documentation is a better tool

window.requestAnimationFrame


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)
        })
    }
    render(page)
    console.timeEnd('List time')}Copy the code

Use the document fragment + requestAnimationFrame method

What is the Document fragments, DOM manipulation is an API, see below: Document. CreateDocumentFragment ()


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>`
                // Insert the document fragment first
                fragment.appendChild(div)
            }
            // appendChild
            container.appendChild(fragment)
            render(page + 1)
        })
    }
    render(page)
    console.timeEnd('List time')}Copy the code

5. Lazy route loading

Understand before you use…

A bit of understanding of the routing lazy loading principle

Refer to the article