前端性能优化

1.注意作用域

    随着作用域链中的作用域数量的增加,访问当前作用域以外的变量的时间也在增加.访问全局变量总是要比访问局部变量慢,因为要遍历作用域链.  
    1). 避免全局查找   将在一个函数中会多次用到的全局对象存储为局部变量总是没错的.

    2). 避免 with 语句  with会创建自己的作用域,因此会增加其中执行代码的作用域链的长度.

2.选择正确的方法

    1). 避免不必要的属性查找     

        在计算机科学中,算法的复杂度是使用O符号来表示的.最简单,最快捷的算法是常数值,即O(1).之后,算法变得越来越复杂并花更长时间执行.常用的JavaScript算法类型有:

        常数 : 不管有多少值,执行的时间都是恒定的.一般表示简单值和存储在变量的值.

        对数 : 总的执行时间和值的数量相关,但是要完成算法并不一定要获取每个值. 例如:二分查找

        线性 : 总执行时间和值的数量直接相关. 例如 :遍历某个数组中的所有元素

        平方 : 总执行时间和值的数量有关,每个值至少要获取n次.例如:插入排序

        立方:  总执行时间和值的数量有关,每个值至少要获取n的平方次

        使用变量和数组要比访问对象上的属性更有效率.对象上的任何属性的查找都要比访问变量或者数组花更长时间,因为必须在原型链中对拥有该名称的属性进行一次搜索.

        一般来讲,只要能减少算法的复杂度,就要尽可能减少.尽可能多地使用局部变量将属性查找替换为值查找.进一步讲,如果即可以用数字化的数组位置进行访问,也可以使用命名属性(诸如NodeList对象),那么使用数组位置.

    2). 优化循环

        a. 减值迭代   在很多情况下,从最大值开始,在循环中不断减值的迭代器更加高效.
        b. 简化终止条件   由于每次循环过程都会计算终止条件,所以必须保证它尽可能快.
        c. 简化循环体   循环体是执行最多的,所以要确保其被最大限度地优化.确保没有某些可以被很容易移出循环的密集计算.
        d. 使用后测试循环   最常用的for循环和while循环都是前测试循环.而如do-while这种后测试循环,可以避免最初终止条件的计算,因此更快. 

    3). 展开循环

         当循环的次数是确定的,消除循环并使用多次函数调用往往更快.如著名的Duff装置

    4).  其他方法

         原生方法较快--只要有可能,使用原生方法而不是自己用JavaScript重写一个.原生方法是用诸如C/C++之类的编译型语言写出来的,所以要比JavaScript的快很多很多.JavaScript中最容易被忘记的就是可以在Math对象中找到的复杂的数学运算;这些方法要比任何用JavaScript写的同样方法,如正弦,余弦快的多.

        Switch 语句较快--如果有一系复杂的if-else语句,可以转换成单个switch语句则可以得到更快的代码.还可以通过将case语句按最可能的到最不可能在顺序进行组织,来进一步优化switch语句.

        位运算符较快--当进行数学运算的时候,位运算操作要比任何布尔运算或者算数运算快.选择性的用位运算换算数运算可以极大提升复杂计算的性能.诸如取模,逻辑与和逻辑或都可以考虑用位运算来替换.

3 . 最小化语句数

    1). 多个变量声明

        如:

//4个语句---很浪费
var count = 5;
var color = "blue";
var values = [1,2,3];
var now = new Date();

        优化:

var count = 5,
    color = "blue",
    values = [1,2,3],
    noiw = new Date();

    2). 插入迭代值

        如:

var name = values[i];
i++;

        优化:

var name = values[i++];

    3). 使用数组和对象字面量

        如:

        var values = new Array(); --->  var values = [];

       var obj = new Object(); ---> var obj = {};

4. 优化DOM交互

    1). 最小化现场更新

        一旦你需要访问DOM部分是已经显示的页面的一部分,那么你就是在进行一个现场更新.之所以叫现场更新,是因为需要立即(现场)对页面对用户的显示进行更新.不管是插入单个字符,还是移除整个片段,都有一个性能惩罚,因为浏览器要重新计算无数尺寸以进行更新.

       例:

var list = document.getElementById("myList");
for(var i = 0;i < 10;i++){
    var item = document.createElement("li");
    list.appendChild(item);
    item.appendChild(document.createTextNode("Item "+i));
}

        这样添加10个项目,这个操作总共要完成20个现场更新.  下面用创建文档碎片的方法改进:

var list = document.getElementById("myList");
var fragment = document.createDocumentFragment();  //创建文档碎片
for(var i = 0; i < 10;i++){
    var item = document.createElement("li");
    fragment.appendChild(item);
    item.appendChild(document.createTextNode("Item "+i));
}
list.append(fragment);

        在这个例子中只有一次现场更新,它发生在所有项目都创建好之后.文档碎片用作一个临时的占位符,放置新创建的项目.然后使用appendChild()将所有项目添加到列表用.记住,当给appendChild()传入文档碎片时,只有碎片中的子节点被添加到目标,碎片本身不会被添加的.

        一旦需要更新DOM,请考虑使用文档碎片来构建DOM结构,然后将其添加到现存的文档中.

    2). 使用innerHTML

        有两种在页面上创建DOM节点的方法:使用诸如createElement(),appendChild()之类的DOM方法,以及使用innerHTML对于小的DOM更改而言,两种方法效率都差不多.而对于大的DOM更改,使用innerHTML要比使用标准DOM方法创建同样的DOM结构快很多.同样,一次使用innerHTML比多次使用innerHTML也要快相当多.

     3). 注意NodeList

        最小化访问NodeList的次数可以极大的改进脚本的性能.

        发生以下情况时会返回NodeList对象:

            a. 进行了对getElementsByTagName()的调用
            b. 获取了元素的childNodes属性
            c. 获取了元素的attributes属性
            d. 访问了特殊的集合,如document.forms  ,  document.images等等

            要了解当使用NodeList对象时,合理使用会极大提升代码执行速度.

5.函数节流 

6.减小js的体积

    对于javascript进行压缩,减少代码体积也是提升javascript性能的有效途径。

7.减少Dom的重绘重排版

//修改前
var el = document.getElementById("div");
el.style.borderLeft = "1px"; //1次重排版
el.style.borderRight = "2px"; //1次重排版
el.style.padding = "5px"; //还有1次重排版
el.style.background = 'red';
//修改后
var el = document.getElementById("div");
el.style.cssText = "border-left:1px;border-right:2px;padding:5px;background: red;"; //1次重排版

8.循环的优化

//修改前
var i = 0;
for(;i<arr.lengthli++){ //每次循环都需要获取数组arrlength
    console.log(arr[i]);
}
//修改后
var i = 0;
var len = arr.length; //获取一次数组arrlength 
for(;i<len;i++){
    console.log(arr[i]);
}
//or
var i = arr.length;;
for(;i;i--){
    console.log(arr[i]);
}


前端性能优化指南









    

通过短时倒谱(Cepstrogram)计算进行时-倒频分析研究(Matlab代码实现)内容概要:本文主要介绍了一项关于短时倒谱(Cepstrogram)计算在时-倒频分析中的研究,并提供了相应的Matlab代码实现。通过短时倒谱分析方法,能够有效提取信号在时间与倒频率域的特征,适用于语音、机械振动、生物医学等领域的信号处理与故障诊断。文中阐述了倒谱分析的基本原理、短时倒谱的计算流程及其在实际工程中的应用价值,展示了如何利用Matlab进行时-倒频图的可视化与分析,帮助研究人员深入理解非平稳信号的周期性成分与谐波结构。; 适合人群:具备一定信号处理基础,熟悉Matlab编程,从事电子信息、机械工程、生物医学或通信等相关领域科研工作的研究生、工程师及科研人员。; 使用场景及目标:①掌握倒谱分析与短时倒谱的基本理论及其与傅里叶变换的关系;②学习如何用Matlab实现Cepstrogram并应用于实际信号的周期性特征提取与故障诊断;③为语音识别、机械设备状态监测、振动信号分析等研究提供技术支持与方法参考; 阅读建议:建议读者结合提供的Matlab代码进行实践操作,先理解倒谱的基本概念再逐步实现短时倒谱分析,注意参数设置如窗、重叠率等对结果的影响,同时可将该方法与其他时频分析方法(如STFT、小波变换)进行对比,以提升对信号特征的理解能力。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值