大数组分时加载算法 timedChunk

Posted chenjy1225

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了大数组分时加载算法 timedChunk相关的知识,希望对你有一定的参考价值。

本篇介绍高性能javascript一书作者NicholasC.Zakas提出的大数组的分时加载算法timedChunk

分时加载

分时加载的意义在于分批加载数据确保在数据加载完成后及时的更新UI界面确保用户体验的流畅性。

chunk()


function chunk(array, process, context){
    
    //克隆数组
    var items = array.concat();   
    
    //延时100ms执行
    setTimeout(function(){
        
        var item = items.shift();
        
        //执行`process`方法
        process.call(context, item);
  
        //如果`items`数组不为空,延迟100ms(提供100ms来更新UI界面)然后回调上方的`setTimeout`函数
        if (items.length > 0){
            setTimeout(arguments.callee, 100);
        }
    }, 100);
}



如果该方法的数组大小为100,执行延时为100ms则总耗时长约为10000ms也就是10s。(忽略process执行的时长)
100ms的延时意味着,你花了大部分时间来进行页面UI的更新而且执行JavaScript的时间甚至可能只是几ms或是不到1ms,而且事实上我们并不需要那么长时间。

经过研究发现延时可以降低至25ms,25ms是避免浏览器setTimeout出现问题(IEsetTimeout最小延时15ms左右,也就是说你延时设为0也会在15ms左右的时候执行)。
但是如果你提供了25ms的延时,你要处理上面的数据仅仅大小为100的数组也需要耗时2500ms 2.5s也是很长的一段时间。

timedChunk()

所以NicholasC.Zakas改进了 chunk()

Jakob Nielsen指出JavaScript代码执行时间如果超过100ms持续执行则不能实时的更新页面UI。

NicholasC.ZakasJakob Nielsen的基础上认为JavaScript代码执行时间不应该连续的超过50ms(可以保证流畅的更新UI界面)。

改进算法


//Copyright 2009 Nicholas C. Zakas. All rights reserved.
//MIT Licensed
function timedChunk(items, process, context, callback){
    
    //克隆数组
    var todo = items.concat(); 

    //延时25ms执行
    setTimeout(function(){

        var start = +new Date();
        
        //执行50ms的`process`方法(前提数组足够大)
        do {
             process.call(context, todo.shift());
        } while (todo.length > 0 && (+new Date() - start < 50));
        
        
        //延迟25ms(提供25ms来更新UI界面)然后回调上方的`setTimeout`方法
        if (todo.length > 0){
            setTimeout(arguments.callee, 25);
        } else {
            callback(items);
        }
    }, 25);
}

所以保证了JavaScript的执行时间的是50ms。
每执行50msJavaScript就为UI界面的更新提供了25ms的时间渲染。

参照:

https://threejs.org/examples/?q=sand#raytracing_sandbox

demo




以上是关于大数组分时加载算法 timedChunk的主要内容,如果未能解决你的问题,请参考以下文章

如何在android中将json数据加载到片段中

算法课-大数专题

算法:平衡树求第k大数 Sm 前段时间刚学会了用快速排序来求一个列中的第 k大数,可是她觉得每次 序列被改变

当片段视图加载是异步任务的一部分时,如何在片段加载之前显示进度条?

用于数据加载的 Android 活动/片段职责

非递归的o(n)的求n个数里面第k大数的算法