有效提高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 相关文章推荐
JS 判断代码全收集
Apr 28 Javascript
js 判断一个元素是否在页面中存在
Dec 27 Javascript
单击浏览器右上角的X关闭窗口弹出提示的小例子
Jun 12 Javascript
js操作label给label赋值及取label的值示例
Nov 07 Javascript
JS两种定义方式的区别、内部原理
Nov 21 Javascript
使用百度地图api实现根据地址查询经纬度
Dec 11 Javascript
深入理解事件冒泡(Bubble)和事件捕捉(capture)
May 28 Javascript
基于Bootstrap和jQuery构建前端分页工具实例代码
Nov 23 Javascript
Vue匿名插槽与作用域插槽的合并和覆盖行为
Apr 22 Javascript
微信小程序 动态修改页面数据及参数传递过程详解
Sep 27 Javascript
p5.js码绘“跳动的小正方形”的实现代码
Oct 22 Javascript
vue2.0 watch里面的 deep和immediate用法说明
Oct 30 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
SWFUpload与CI不能正确上传识别文件MIME类型解决方法分享
2011/04/18 PHP
PHP接口类(interface)的定义、特点和应用示例
2020/05/18 PHP
js定时器(执行一次、重复执行)
2014/03/07 Javascript
jquery中$each()方法的使用指南
2015/04/30 Javascript
jquery实现九宫格大转盘抽奖
2015/11/13 Javascript
通用无限极下拉菜单的实现代码
2016/05/31 Javascript
基于jQuery ligerUI实现分页样式
2016/09/18 Javascript
JS使用正则截取两个字符串之间的字符串实现方法详解
2017/01/06 Javascript
js字符串处理之绝妙的代码
2019/04/05 Javascript
vue下axios拦截器token刷新机制的实例代码
2020/01/17 Javascript
《javascript设计模式》学习笔记七:Javascript面向对象程序设计组合模式详解
2020/04/08 Javascript
vue父子组件间引用之$parent、$children
2020/05/20 Javascript
JQuery基于FormData异步提交数据文件
2020/09/01 jQuery
react-intl实现React国际化多语言的方法
2020/09/27 Javascript
如何基于viewport vm适配移动端页面
2020/11/13 Javascript
[39:52]2018DOTA2亚洲邀请赛 4.3 突围赛 EG vs Newbee 第一场
2018/04/04 DOTA
Python的Flask开发框架简单上手笔记
2015/11/16 Python
Python连接SQLServer2000的方法详解
2017/04/19 Python
Python中单例模式总结
2018/02/20 Python
Python3爬取英雄联盟英雄皮肤大图实例代码
2018/11/14 Python
pycharm在调试python时执行其他语句的方法
2018/11/29 Python
python 将有序数组转换为二叉树的方法
2019/03/26 Python
python中bs4.BeautifulSoup的基本用法
2019/07/27 Python
python Django里CSRF 对应策略详解
2019/08/05 Python
用Python实现校园通知更新提醒功能
2019/11/23 Python
Python之变量类型和if判断方式
2020/05/05 Python
Javascript 高级手势使用介绍
2013/04/21 HTML / CSS
使用spring mvc+localResizeIMG实现HTML5端图片压缩上传的功能
2016/12/16 HTML / CSS
美国在线家装零售商:Build.com
2016/09/02 全球购物
西班牙Polo衫品牌:Polo Club
2020/08/09 全球购物
无私奉献演讲稿
2014/09/04 职场文书
成都人事代理协议书
2014/10/25 职场文书
人身损害赔偿协议书格式
2014/11/01 职场文书
你喜欢篮球吗?Python实现篮球游戏
2021/06/11 Python
Windows11插耳机没反应怎么办? win11耳机没声音的多种解决办法
2021/11/21 数码科技
Python如何让字典保持有序排列
2022/04/29 Python