使用分时函数解决 页面一次性渲染上万数据导致的浏览器卡死状态

98 阅读1分钟

举个例子,qq列表中有成千上万个好友,如果一个好友用一个节点表示,当我们在页面中渲染这个列表时,就需要一次性在页面中创建成千上万个节点,这就会导致浏览器出现卡顿甚至假死的状态。代码如下:

       var ary = [];
        for (let i = 1; i <= 1000; i++) {
            ary.push(i)
        }
        const renderList = function(data) {
            for(let i = 0, l = data.length; i < l; i++) {
                const div = document.createElement('div')
                div.innerText = i;
                document.body.appendChild(div)
            }
        }
        renderList(ary)

解决方案之一是使用下面的分时函数(timeChunk), timeChunk函数让创建节点的工作分时进行,比如把1秒钟创建1000个节点,改为每隔200毫秒创建8个节点。

        /**
         * @params
         * data: 创建节点时需要的数据
         * fn: 创建节点逻辑的函数
         * count: 每一批创建的节点数量
         */
        const timeChunk = function(data, fn, count) {
            let t = null;
            const start = function() {
                for(let i = 0; i < Math.min(count || 1, data.length); i++) {
                    const obj = data.shift()
                    fn(obj)
                }
            }
            return function() {
                t = setInterval(() => {
                    if (data.length === 0) {
                        clearInterval(t)
                        t = null
                        return false
                    }
                    start()
                }, 200) // 每200ms创建8个节点
            }
        }
        

下面利用timeChunk函数,每一批只往页面创建8个节点

        const ary = [];
        for (let i = 1; i <= 1000; i++) {
            ary.push(i)
        }
        const renderList = timeChunk(ary, function(content) {
            const div = document.createElement('div')
            div.innerText = content;
            document.body.appendChild(div)
        }, 8)
        renderList()