后端返回大量数据,前端怎么高效渲染

原创
小哥 3年前 (2022-10-20) 阅读数 184 #Web前端
文章标签 渲染高效

本文给出了三种写入方法,从低到高按性能和效率的顺序进行了改进。建议循序渐进地深化认识。

setTimeout分页渲染

通过数据条总数 total ,以及每页的文章数量限制 limit ,计算总页数 totalPage ,通过 setTimeout 单独呈现每个页面,从而缩短呈现时间。

const renderList = async () => {   
    const list = await getList()   
    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.innerHTML = ${item.content}
                container.appendChild(div)
            }
        })
        render(page+1)
    }
    render(page)
}

requestAnimationFrame

window.requestAnimationFrame() 告诉浏览器-您希望执行动画,并要求浏览器在下一次重绘之前调用指定的回调函数来更新动画。该方法需要传入一个回调函数作为参数,该参数在浏览器下一次重新绘制之前执行。

requestAnimationFrame 代替 setTimeout ,可以减少 频繁重排 性能损失。

const renderList2 = async () => {
    const list = await getList()
    const total = list.length
    const page = 0
    const limit = 200
    const totalPage = Math.ceil(total / limit)

    const render = (page) => {
        if (page >= totalPage) return 
        // 使用requestAnimationFrame代替setTimeout
        requestAnimationFrame(() => {
            for (let i = page * limit; i < page * limit + limit; i++) {
                const item = list[i]
                const div = document.createElement(div)
                div.innerHTML = ${item.content}
                container.appendChild(div)
            }
        })
        render(page + 1)
    }
    render(page)
}

文档碎片 + requestAnimationFrame

以前创建的每个 divappendChild 曾经,现在每页的所有内容 div 先填进 Fragment ,再来一次 appendChild 放入容器中,减少 appendChild 提高性能的次数。

const renderList3 = async() => {
    const list = await getList()
    const total = list.length
    const page = 0
    const limit = 200
    const totalPage = Math.ceil(total / limit) 

    const render = (page) => {
        if (page >= totalPage) return
        requestAnimationFrame(() => {
            // 创建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.innerHTML = ${item.content}
                // 先填进fragment
                fragment.appendChild(div)
            } 
            // 再将fragment一次性appendChild
            container.appendChild(fragment)
            render(page + 1)
        })
    }
    render(page)
}
版权声明

所有资源都来源于爬虫采集,如有侵权请联系我们,我们将立即删除

热门