首页 > jQuery的`append`操作不能即时渲染

jQuery的`append`操作不能即时渲染

放在for循环内的append操作,本来应该是for循环执行一次就append一次,但是现在变成了整个for循环完成后才一次性append生成的元素到DOM中去。查了下说这个是因为重绘DOM耗费资源所以缓存掉了。想问下有办法解决么?
问题核心代码:

    for (var i = 0; i < testTimes; i++) {
        for (var j = 0; j < allFunc.length; j++) {
            var currentResult=$('.result').eq(j);
            var gapTime=test(times,allFunc[j]);
            var testTime=currentResult.find('span').length+1;
            if(!resultMatrix[testTime-1]){
                resultMatrix[testTime-1]=[];
            }
            console.log('1');
            var result="<span>第"+testTime+'次实验结果:耗时'+gapTime+'ms</span>';
            currentResult.append(result);//append不是一条一条加,而是全部结果出来后才加上去
            /* 这是后来改成原生appendChild的代码,但是依旧不起作用
            var result=document.createElement('span');
            result.innerHTML='第'+testTime+'次实验结果:耗时'+gapTime+'ms';
            currentResult.get(0).appendChild(result);
            */
            resultMatrix[testTime-1][j]=gapTime;
        };
    };

DEMO:
http://codepen.io/chitanda/full/NqeZag/

期望效果:
实验结果那里的数据每次计算完成后都即时更新,而不是全部计算完成后一次性更新上去。

PS
chrome下还有个很有趣的现象就是开发者工具的Elements面板里显示span已经加上去了,但是页面中没有任何反应。而IE和FF中则没有这种情况。不知道能否顺带解答下。


在浏览器里面DOM树的管理和渲染页面分开的吧,浏览器还有一个用来控制渲染的渲染树的数据结构,除了隐藏的节点,DOM树上所有节点都在渲染树上有一个对应节点,浏览器会将渲染树上的节点按照他的逻辑渲染到视口中,就形成了用户所见的页面。
然而,渲染是一种性能消耗不小的事情,所以大部分浏览器都有他们自己对渲染的优化,其中就包括了批量渲染(chrome有的),就是对于DOM树的修改并不似立刻产生渲染逻辑,而是一定时间间隔内将所有的DOM操作对应的所需要改变的渲染逻辑批量完成渲染。所以你就看到了span已经加上去了,但是页面上没有任何反应。
想让浏览器立刻执行渲染逻辑,你需要访问诸如offsetWidth等一系列需要即时获得的信息,这列操作会使浏览器刷新渲染树并执行相应的渲染操作,因为offset里面存储的总应该是最新的。

同时,由于每次访问offset都会刷新渲染树,相比其他可用的坐标属性,访问offset的性能消耗会大一些。所以如果不需要访问那些即时数据就可以完成任务,尽量不用。
说起offset,废话略多了。。不过做CSS动画是你可以offset获取到任何时刻处于动画中的元素坐标,然后就可以干好多好多事,很6的。。。。。
额,扯远了,算了,大概就是这样子吧。


楼上两位大神已经说的挺清楚了,其实就是浏览器做的性能优化,你试试看使用 setTimeout能不能规避这种优化


JS在执行的过程中,UI渲染过程是不能够介入的
只能等到所在的JS代码执行完毕,UI线程才开始执行页面渲染工作
另外 append后 DOM结构树已经生成了,要显示出来需要UI渲染线程参与

【热门文章】
【热门文章】