有效提高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 相关文章推荐
科讯商业版中用到的ajax空间与分页函数
Sep 02 Javascript
JQuery 常用方法基础教程
Feb 06 Javascript
Jquery Ajax 学习实例2 向页面发出请求 返回JSon格式数据
Mar 15 Javascript
IE6 fixed的完美解决方案
Mar 31 Javascript
JavaScript基本编码模式小结
May 23 Javascript
JQuery each()函数如何优化循环DOM结构的性能
Dec 10 Javascript
解决ueditor jquery javascript 取值问题
Dec 30 Javascript
javascript 判断页面访问方式电脑或者移动端
Sep 19 Javascript
Angular.js通过自定义指令directive实现滑块滑动效果
Oct 13 Javascript
微信开发之微信jssdk录音功能开发示例
Oct 22 Javascript
详解jQuery中的getAll()和cleanData()
Apr 15 jQuery
文章或博客自动生成章节目录索引(支持三级)的实现代码
May 10 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
php中将地址生成迅雷快车旋风链接的代码[测试通过]
2011/04/20 PHP
判断PHP数组是否为空的代码
2011/09/08 PHP
php笔记之:数据类型与常量的使用分析
2013/05/14 PHP
PHP采集类snoopy详细介绍(snoopy使用教程)
2014/06/19 PHP
PHP使用PDO创建MySQL数据库、表及插入多条数据操作示例
2019/05/30 PHP
php使用scandir()函数扫描指定目录下所有文件示例
2019/06/08 PHP
jQuery Tools tab(幻灯片)
2012/07/14 Javascript
使用js在页面中绘制表格核心代码
2013/09/16 Javascript
js获取下拉列表的值和元素个数示例
2014/05/07 Javascript
深入理解JavaScript系列(46):代码复用模式(推荐篇)详解
2015/03/04 Javascript
js获取form表单所有数据的简单方法
2016/08/18 Javascript
jQuery中的deferred使用方法
2017/03/27 jQuery
Vue的轮播图组件实现方法
2018/03/03 Javascript
Vue.js 时间转换代码及时间戳转时间字符串
2018/10/16 Javascript
通过实例了解Javascript柯里化流程
2020/03/03 Javascript
JavaScript快速调试的两个技巧
2020/11/04 Javascript
vant中的toast轻提示实现代码
2020/11/04 Javascript
Python 实现 贪吃蛇大作战 代码分享
2016/09/07 Python
对python读写文件去重、RE、set的使用详解
2018/12/11 Python
搭建python django虚拟环境完整步骤详解
2019/07/08 Python
Python列表原理与用法详解【创建、元素增加、删除、访问、计数、切片、遍历等】
2019/10/30 Python
pandas的相关系数与协方差实例
2019/12/27 Python
如何利用Python动态模拟太阳系运转
2020/09/04 Python
韩国三星集团旗下时尚品牌官网:SSF SHOP
2016/08/02 全球购物
迪拜航空官方网站:flydubai
2017/04/20 全球购物
德国专业木制品经销商:Holz-Direkt24
2019/12/26 全球购物
对象的序列化(serialization)类是面向流的,应如何将对象写入到随机存取文件中
2015/06/22 面试题
活动志愿者自荐信
2014/01/27 职场文书
债务纠纷委托书范本
2014/10/14 职场文书
司法局2014法制宣传日活动总结
2014/11/01 职场文书
小学总务工作总结
2015/08/13 职场文书
Java如何实现树的同构?
2021/06/22 Java/Android
Python实现批量自动整理文件
2022/03/16 Python
分析SQL窗口函数之排名窗口函数
2022/04/21 Oracle
SQL使用复合索引实现数据库查询的优化
2022/05/25 SQL Server
python中pd.cut()与pd.qcut()的对比及示例
2022/06/16 Python