后端返回数万条数据,前端如何高效渲染

本文给出了三种写法,是按照性能和效率由低到高依次改进的,建议按照顺序来一步步加深理解。

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)
}
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值