数据大时渲染优化

分片加载

通过setTimeout进行分片渲染

    <ul>
    </ul>
    <script>
        const ul = document.querySelector('ul')
        const list = []
        for (let i = 0; i < 100000; i++) {
            list.push(i)
        }

        let num = 0
        const size = 100
        const count = Math.ceil(list.length / size)
        const render = () => {
            if (num >= count) return
            setTimeout(() => {
                for (let i = num * size; i < (num + 1) * size; i++) {
                    const li = document.createElement('li')
                    li.innerHTML = list[i]
                    ul.appendChild(li)
                }
                render(num++)
            }, 0)

        }
        render(num)
    </script>

文档碎片

通过document.createDocumentFragment()创建文档碎片的方式,将创建的元素塞进文档碎片,在添加到页面上,文档碎片参考:https://developer.mozilla.org/zh-CN/docs/Web/API/Document/createDocumentFragment

    <ul>
    </ul>
    <script>
        const ul = document.querySelector('ul')
        const bottom = document.querySelector('.bottom')
        const list = []
        for (let i = 0; i < 100000; i++) {
            list.push(i)
        }

        let num = 0
        const size = 100
        const count = Math.ceil(list.length / size)
        const render = () => {
            if (num >= count) return
            setTimeout(() => {
                const fragment = document.createDocumentFragment()
                for (let i = num * size; i < (num + 1) * size; i++) {
                    const li = document.createElement('li')
                    li.innerHTML = list[i]
                    fragment.appendChild(li)
                }
                ul.appendChild(fragment)
                render(num++)
            }, 0)
        }
        render(num)

懒加载

通过IntersectionObserver方法判断给定元素是否出现在可是区域内,出现的话在进行追加数据

    <ul>
        <li class="bottom"></li>
    </ul>
    <script>
        const ul = document.querySelector('ul')
        const bottom = document.querySelector('.bottom')
        const list = []
        for (let i = 0; i < 100000; i++) {
            list.push(i + 1)
        }

        let num = 0
        const size = 100
        const count = Math.ceil(list.length / size)
        const render = () => {
            if (num >= count) return
            setTimeout(() => {
                const fragment = document.createDocumentFragment()
                for (let i = num * size; i < (num + 1) * size; i++) {
                    const li = document.createElement('li')
                    li.innerHTML = list[i]
                    fragment.appendChild(li)
                }
                ul.insertBefore(fragment, bottom)
            }, 0)
        }
        const intersectionObserver = new IntersectionObserver((entries) => {
            if (entries[0].isIntersecting) {
                render(num++)
            }
        })
        intersectionObserver.observe(bottom)
        render(num)
    </script>

上拉加载

通过监听是否触底(滚动条距离顶部高度 + 可视区内容高度 >= 实际内容的高度)来进行数据加载

    <div class="container">
        <ul>
        </ul>
    </div>
    <script>
        const container = document.querySelector('.container')
        const ul = document.querySelector('ul')
        const list = []
        for (let i = 0; i < 100000; i++) {
            list.push(i + 1)
        }
        let num = 0
        const size = 100
        const count = Math.ceil(list.length / size)
        const handleScroll = () => {
            // 滚动条距离顶部高度 + 可视区内容高度 >= 实际内容的高度 
            if (container.scrollTop + container.clientHeight >= ul.clientHeight) {
                num++
                if (num >= count) {
                    container.removeEventListener('scroll', handleScroll)
                    return
                }
                createLi(num)
            }
        }

        const createLi = (num) => {
            for (let i = num * size; i < (num + 1) * size; i++) {
                const li = document.createElement('li')
                li.innerHTML = list[i]
                ul.appendChild(li)
            }
        }
        createLi(num)
        // 节流函数
        const debounce = (fn, delay) => {
            let timer = null
            return () => {
                if (timer) clearTimeout(timer)
                timer = setTimeout(fn, delay)
            }
        }
        const debounceScroll = debounce(handleScroll, 300)
        container.addEventListener('scroll', debounceScroll)
    </script>
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容