高性能javaScript(六)—— 快速响应的用户界面

2020-12-19  本文已影响0人  晓蟲QwQ

JavaScript和用户界面更新在同一个进程中运行,因此一次只能处理一件事情。这意味着当JavaScript代码正在运行时,用户界面不能响应输入,反之亦然。高效地管理UI线程就是要确保JavaScript不能运行太长时间,以免影响用户体验。最后,请牢记如下几点:

/* 使用定时器分割处理长数组,将线程让给UI
* 使用定时器取代循环必须遵守以下两点:
* 1. 处理过程不必须同步。
* 2. 数据不必须按顺寻处理
*/

//正常迭代
for(var i=0, len=items.length;i<len;i++) {
    process(items[i]);
}

//定时器方式
var todo = items.concat(); //克隆原数组

setTimeout(function(){
    
    //取得数组的下个元素并处理
    process(todo.shift());
    
    //如果还有需要处理的元素,创建另一个定时器
    if(todo.length > 0){
        setTimeout(arguments.callee,25);
    } else {
        callback(items);
    }
},25);

//功能封装
function processArray(items,process,callback) {
    var todo = items.concat(); //克隆
    
    setTimeout(function(){
        process(todo.shift());
        
        if(todo.length > 0) {
            setTimeout(arguments.callee,25);
        } else {
            callback(items);
        }
    },25);
}
//分割任务
function saveDocument(id){
    var tasks = [openDocument,writeText,closeDocument,updateUI];
    
    setTimeout(function(){
        //执行下一个任务
        var task = tasks.shift();
        task(id);
        
        //检查是否还有其他任务
        if(tasks.length > 0){
            setTimeout(arguments.callee,25);
        }
    },25);
}

//封装
function multistep(steps,args,callback) {
    var tasks = steps.concat();
    
    setTimeout(function(){
        //执行下一个任务
        var task = task.shift();
        task.apply(null,args || []);
        
        //检查是否有其他任务
        if(tasks.length > 0){
            setTimeout(arguments.callee,25);
        } else {
            callback();
        }
    },25);
}

其他可用worker的任务:

  • 编码/解码大字符串。
  • 复杂数学运算(包括图像或视频处理)。
  • 大数组排序。
/*
* 当解析json需要长时间时使用worker
*/

var worker = new Worker("jsonparser.js");

//数据就位时,调用事件处理器
worker.onmessage = function(event) {
    
    //JSON 结构被回传回来
    var jsonData = event.data;
    
    //使用JSON结构
    evaluateData(jsonData);
}

//传入要解析的大段JSON字符串
worker.postMessage(jsonText);

//jsonparser.js内部代码

//当JSON数据存在时,该事件处理器会被调用
self.onmessage = function(event) {
    
    //JSON字符串由event.data传入
    var jsonData = JSON.parse(jsonText);
    
    //解析
    var jsonData = JSON.parse(jsonText);
    
    //回传结果
    self.postMessage(jsonData);
}
上一篇下一篇

猜你喜欢

热点阅读