JS编程中高性能注意点

1. 用局部变量存储本地范围之外的变量值,如果它们在函数中的使用多于一次。

2. 实例成员与原型成员的关系hasOwnProperty

3. 一般来说,将经常使用的对象成员,数组项,和域外变量存入局部变量中。然后访问局部变量的速度会快于那些原始变量;

 

Dom操作:

1. 访问Dom次数越多,代码执行速度越慢。因此一般都是尽量少的查询修改dom元素

2. Dom集合存在length,建议将length值缓存在变量中,然后在循环中使用

3. 如果同一个DOM属性或者方法被访问一次以上,最好使用一个局部变量缓存此DOM成员。

4. 减少重绘重排的次数,应该将多个DOM和风格改变合并到一个批次中一次执行
  1)css类代替内联
  2)使用代码片段或者隐藏显示方式,引发一次重排版---只触发存在DOM一次

 异步请求方面:

1. 浏览器可以支持6个请求并发执行,所以对于异步请求数据,尽量并发执行

2. 对于异步请求的数据,可以进行缓存处理

3. 如果对于大量计算的可以启用webWorker技术

4. 如果WebWorker还不能满足,则加入WebAssimbly技术

编程注意点:

1. 当判断条件较多时,查表法比if-else或者switch更快

function memfactorial(n){
    if(!memfactorial.cache){
        memfactorial.cache = {
            "0": 0,
            "1": 1
        };
    }
    
    if(!memfactorial.cache.hasOwnProperty(n)){
        memfactorial.cache[n] = n * memfactorial(n-1);
    }
    
    return memfactorial.cache[n];
}

function memoize(fundamental, cache){
    cache = cache || {};
    let shell = function(arg){
        if(!cache.hasOwnProperty(arg)){
            cache[arg] = fundamental(arg);
        }
        
        return cache[arg];
    };
    
    return shell;
}

2. 字符串操作

  1)链接字符串的时候避免重复的内存分配和拷贝越来越大的字符串。

  2)使用连接数组连接代替直接字符串的连接操作;

  3)concat的性能不如直接+

 

编程复杂度常识

1. 控制JavaScript任务在100毫秒内完成,如果因为复杂不能在100毫秒内完成,最理想的方式是让出UI线程的控制,使UI更新可以进行。

button.onClick = function(){
    onMethod();
    setTimeout(function(){
        document.getElementById("notice").style.color = "red";
    }, 250);
    anotherMethod();
};

通常一个定时器最小设置为25毫秒

2. 数组中处理定时器

function processArray(items, process, callback){
    let todo = items.concat();
    setTimeout(function(){
        process(todo.shift());
        if(todo.length > 0){
            setTimeout(arguments.callee, 25);
        }else{
            callback(items);
        }
    }, 25);
}

3. 分解任务

function saveDocument(id){
    let tasks = [openDocument, writeText, closeDocument, updateUI];
    setTimeout(function(){
        let task = tasks.shift();
        task(id);
        if(tasks.length > 0){
            setTimeout(arguments.callee, 25);
        }
    }, 25);
}
封装:
function multistep(steps, args, callback){
    let tasks = steps.concat();
    setTimeout(function(){
        let task = tasks.shift();
        task.apply(null, args || []);
        if(tasks.length > 0){
            setTimeout(arguments.callee, 25);
        }else{
            callback();
        }
    }, 25);
}

function saveDocument(id){
    let tasks = [openDocument, writeText, closeDocument, updateUI];
    multistep(tasks, [id], function(){
        console.log("Done");
    });
}
定时器中添加时间检测机制,让每个定时器执行多次处理-----避免将任务分解成过小的碎片
function timeProcessArray(items, process, callback){
    let todo = items.concat();
    setTimeout(function(){
    
        let start = +new Date();
        do{
            process(todo.shift());
        }while(todo.length > 0 && (+new Date() - start) < 50);
        
        if(todo.length > 0){
            setTimeout(arguments.callee, 25);
        }else{
            callback(items);
        }
    }, 25);
}

4. Web Worker

例如:解析一个很大的JSON字符串,至少需要500毫秒

let worker = new Worker("jsonparser.js");
worker.onmessage = function(event){
    let jsonData = event.data;
    evaluateData(jsonData);
};

worker.postMessage(jsonText);

//jsonparser.js
self.onmessage = function(event){
    let jsonText = event.data;
    let jsonData = JSON.parse(jsonText);
    self.postMessage(jsonData);
}

Ajax

1.当使用XHR请求数据时,你可以选择POST或者GET。如果请求不改变服务器状态只是取回数据(又称幂等动作)则使用GET,因为GET请求会被缓存起来。多次请求可以提高性能。
2. 或者URL长度超过2048时使用POST取数据

3. 动态脚本标签插入该技术克服了XHR的最大限制:他可以从不同域的服务器上获取数据

4. 失败重试

function xhrPost(url, params, callback){
    let req = new XHLHttpRequest();
    req.onerror = function(){
        setTimeout(function(){
            xhrPost(url, params, callback);
        }, 1000);
    };
    
    req.onreadystatechange = function(){
        if(req.readyState === 4){
            if(callback && typeof callback === "function"){
                callback();
            }
        }
    };
    
    req.open('POST', url, true);
    req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    req.setRequestHeader('Content-Length', params.length);
    req.send(params.json('&'));
}

灯标技术????

posted @ 2018-10-11 09:47  MakeCoder  阅读(319)  评论(0编辑  收藏  举报