有效提高JavaScript执行效率的几点知识


Posted in Javascript onJanuary 31, 2015

为了提供新鲜、别致的用户体验,很多网站都会使用 JavaScript 来改善设计、验证表单、检查浏览器,以及Ajax请求,cookie操作等等,实现无刷新动态效果 。但是,要将大量内容在浏览器呈现,如果处理不好,网站性能将会急剧下降。所以我们有必要了解下,如何提高JavaScript的执行效率。

JavaScript 函数

在JavaScript 中,函数在使用前会预编译。尽管有些时候下可以使用字符串代替函数,但是每次执行这段JavaScript 代码时都会重新解析,影响性能。

1、eval例子

eval('output=(input * input)');

// 建议改成:

eval(new function() { output=(input * input)});

2、setTimeout例子

setTimeout("alert(1)", 1000);

// 建议改成:

setTimeout(function(){alert(1)}, 1000);

使用函数代替字符串作参数确保新方法中的代码能被 JavaScript 编译器优化。

JavaScript作用域

JavaScript作用域链中的每个作用域都包含几个变量。理解作用域链很重要,这样才能利用它。

var localVar = "global"; //全局变量
function test() {
  var localVar = "local"; //局部变量
  //局部变量

  alert(localVar);
  //全局变量

  alert(this.localVar);
  //查找document在局部变量找不到,就查找全局变量

  var pageName = document.getElementById("pageName"); 

}

使用局部变量比使用全局变量快得多,因为在作用域链中越远,解析越慢。下图显示了作用域链结构:

有效提高JavaScript执行效率的几点知识

如果代码中有 with 或 try-catch 语句,作用域链会更复杂,如下图:

有效提高JavaScript执行效率的几点知识

JavaScript字符串

JavaScript中一个非常影响性能的函数是字符串连接,一般情况都是使用 + 号来实现拼接字符串。但是早期浏览器没有对这样的连接方式做优化,导致在连续创建和销毁字符串严重降低JavaScript执行效率。

var txt = "hello" + " " + "world";

建议改成:

var o = [];

o.push("hello");

o.push(" ");

o.push("world");

var txt = o.join();

我们再简单封装一下:

function StringBuffer(str) {

    var arr = [];

    arr.push(str || "");

    this.append = function(str) {

        arr.push(str);

        return this;

    };

    this.toString = function() {

        return arr.join("");

    };

};

然后这样子调用:

var txt = new StringBuffer();

txt.append("Hello");

txt.append(" ");

txt.append("World");

alert(txt.toString());

JavaScript DOM操作

HTML Document Object Model (DOM) 定义了访问和操作 HTML 文档的标准方法。它将 HTML 文档表示成节点树,其中包含元素、属性和文本内容。通过使用 HTML DOM,JavaScript 能访问 HTML 文档中所有节点并操作它们。

DOM重绘

每次修改到页面的DOM对象,都涉及到DOM重绘,浏览器都会重新渲染页面。所以降低DOM对象的修改次数,可以有效地提高JavaScript 的性能。

for (var i = 0; i < 1000; i++ ) {

  var elmt = document.createElement('p');

  elmt.innerHTML = i;

  document.body.appendChild(elmt);

}

建议改成:

var html = [];

for (var i = 0; i < 1000; i++) {

  html.push('<p>' + i + '</p>');

}

document.body.innerHTML = html.join('');

DOM访问

通过DOM可以访问到HTML文档中的每个节点。每次调用getElementById()、getElementsByTagName()等方法,都会重新查找并访问节点。所以将查找到的DOM节点缓存一下,也可以提高JavaScript 的性能。

document.getElementById("p2").style.color = "blue";

document.getElementById("p2").style.fontFamily = "Arial";

document.getElementById("p2").style.fontSize = "larger";

建议改成:

var elmt = document.getElementById("p2");

elmt.style.color = "blue";

elmt.style.fontFamily = "Arial";

elmt.style.fontSize = "larger";

DOM遍历

DOM遍历子元素通常都是按索引循环读取下一个子元素,在早期浏览器下这种读取方式执行效率很低,利用nextSibling方式可以提高js遍历DOM的效率。

var html = [];

var x = document.getElementsByTagName("p");//所有节点

for (var i = 0; i < x.length; i++)  {

  //todo

}

建议改成:

var html = [];

var x = document.getElementById("div");//上级节点

var node = x.firstChild;

while(node != null){

  //todo

  node = node.nextSibling;

}

JavaScript 内存释放

在web应用中,随着DOM对象数量的增加,内存消耗会越来越大。所以应当及时释放对象的引用,让浏览器能够回收这些内存。

释放DOM占用的内存

document.getElementById("test").innerHTML = "";

将DOM元素的innerHTML设置为空字符串,可以释放其子元素占用的内存。

释放javascript对象

//对象:

obj = null

//对象属性:

delete obj.property

//数组元素:

arr.splice(0,3);//删除前3个元素
Javascript 相关文章推荐
比较全面的event对像在IE与FF中的区别 推荐
Sep 21 Javascript
js字母大小写转换实现方法总结
Nov 13 Javascript
JQuery异步加载无限下拉框级联功能实现示例
Feb 19 Javascript
深入理解javascript作用域和闭包
Sep 23 Javascript
jQuery结合CSS制作漂亮的select下拉菜单
May 03 Javascript
js实现select跳转菜单新窗口效果代码分享(超简单)
Aug 21 Javascript
学习javascript面向对象 实例讲解面向对象选项卡
Jan 04 Javascript
jQuery实现在新增加的元素上添加事件方法案例分析
Feb 09 Javascript
详解vue.js之绑定class和style的示例代码
Aug 24 Javascript
微信小程序中使用 async/await的方法实例分析
May 06 Javascript
解决vant的Toast组件时提示not defined的问题
Nov 11 Javascript
Javascript实现单选框效果
Dec 09 Javascript
JavaScript日期时间与时间戳的转换函数分享
Jan 31 #Javascript
JavaScript监听和禁用浏览器回车事件实例
Jan 31 #Javascript
JavaScript编程中容易出BUG的几点小知识
Jan 31 #Javascript
JavaScript实现的双向跨域插件分享
Jan 31 #Javascript
JavaScript判断变量是否为空的自定义函数分享
Jan 31 #Javascript
分享两个手机访问pc网站自动跳转手机端网站代码
Dec 24 #Javascript
js判断登录与否并确定跳转页面的方法
Jan 30 #Javascript
You might like
织梦模板标记简介
2007/03/11 PHP
php数组函数序列之array_combine() - 数组合并函数使用说明
2011/10/29 PHP
浅析get与post的一些特殊情况
2014/07/28 PHP
解决php表单重复提交实现方法
2015/09/29 PHP
PHP递归实现快速排序的方法示例
2017/12/18 PHP
解决php用mysql方式连接数据库出现Deprecated报错问题
2019/12/25 PHP
JS面向对象、prototype、call()、apply()
2009/05/14 Javascript
Extjs TriggerField在弹出窗口显示不出问题的解决方法
2010/01/08 Javascript
AJAX的跨域与JSONP(为文章自动添加短址的功能)
2010/01/17 Javascript
基于jquery的给文章加入关键字链接
2010/10/26 Javascript
js获取网页高度(详细整理)
2012/12/28 Javascript
jQuery中each()方法用法实例
2014/12/27 Javascript
javascript 兼容各个浏览器的事件
2015/02/04 Javascript
JS+CSS实现仿雅虎另类滑动门切换效果
2015/10/13 Javascript
JS函数的几种定义方式分析
2015/12/17 Javascript
js将滚动条滚动到指定位置的简单实现方法
2016/06/25 Javascript
浅谈Node.js:Buffer模块
2016/12/05 Javascript
node.js通过axios实现网络请求的方法
2018/03/05 Javascript
vue打包之后生成一个配置文件修改接口的方法
2018/12/09 Javascript
你不知道的Vue技巧之--开发一个可以通过方法调用的组件(推荐)
2019/04/15 Javascript
解决layui数据表格Date日期格式的回显Object的问题
2019/09/19 Javascript
微信小程序iOS下拉白屏晃动问题解决方案
2019/10/12 Javascript
Vue程序化的事件监听器(实例方案详解)
2020/01/07 Javascript
[22:20]初生之犊-TI4第5名LGD战队纪录片
2014/08/13 DOTA
[53:15]Newbee vs Pain 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
python实现跨文件全局变量的方法
2014/07/07 Python
python中星号变量的几种特殊用法
2016/09/07 Python
python计算两个数的百分比方法
2018/06/29 Python
Python模块汇总(常用第三方库)
2019/10/07 Python
计算Python Numpy向量之间的欧氏距离实例
2020/05/22 Python
CSS3 制作旋转的大风车(充满童年回忆)
2013/01/30 HTML / CSS
H5离线存储Manifest原理及使用
2020/04/28 HTML / CSS
大学生自助营养快餐店创业计划书
2014/01/13 职场文书
《冬阳童年骆驼队》教学反思
2014/04/15 职场文书
2019邀请函格式及范文
2019/05/20 职场文书
CSS3实现的侧滑菜单
2021/04/27 HTML / CSS