有效提高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 相关文章推荐
Google AJAX 搜索 API实现代码
Nov 17 Javascript
node.js下when.js 的异步编程实践
Dec 03 Javascript
node.js中RPC(远程过程调用)的实现原理介绍
Dec 05 Javascript
jquery实现滑动特效代码
Aug 10 Javascript
JS定时器用法分析【时钟与菜单中的应用】
Dec 21 Javascript
jQuery点击弹出层弹出模态框点击模态框消失代码分享
Jan 21 Javascript
js实现城市级联菜单的2种方法
Jun 23 Javascript
vue中改变选中当前项的显示隐藏或者状态的实现方法
Feb 08 Javascript
vue 使用html2canvas将DOM转化为图片的方法
Sep 11 Javascript
Node.js折腾记一:读指定文件夹,输出该文件夹的文件树详解
Apr 20 Javascript
解决vue数据不实时更新的问题(数据更改了,但数据不实时更新)
Oct 27 Javascript
Vue-Element-Admin集成自己的接口实现登录跳转
Jun 23 Vue.js
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分页函数示例代码分享
2014/02/24 PHP
PHP验证终端类型是否为手机的简单实例
2017/02/07 PHP
php设计模式之备忘模式分析【星际争霸游戏案例】
2020/03/24 PHP
PHP 计算至少是其他数字两倍的最大数的实现代码
2020/05/26 PHP
PHP字符串和十六进制如何实现互相转换
2020/07/16 PHP
js获取浏览器的可视区域尺寸的实现代码
2011/11/30 Javascript
window.onload和$(function(){})的区别介绍
2013/10/30 Javascript
getAsDataURL在Firefox7.0下无法预览本地图片的解决方法
2013/11/15 Javascript
使用forever管理nodejs应用教程
2014/06/03 NodeJs
jQuery焦点控制图层展示延迟隐藏的方法
2015/03/09 Javascript
jquery实现兼容IE8的异步上传文件
2015/06/15 Javascript
Javascript中构造函数要注意的一些坑
2017/01/23 Javascript
Vue路由切换时的左滑和右滑效果示例
2018/05/29 Javascript
解决vue 界面在苹果手机上滑动点击事件等卡顿问题
2018/11/27 Javascript
element实现合并单元格通用方法
2019/11/13 Javascript
[52:20]DOTA2-DPC中国联赛正赛 SAG vs XGBO3 第一场 3月5日
2021/03/11 DOTA
利用pyinstaller或virtualenv将python程序打包详解
2017/03/22 Python
Python编程实现粒子群算法(PSO)详解
2017/11/13 Python
Python实现简单求解给定整数的质因数算法示例
2018/03/25 Python
python对离散变量的one-hot编码方法
2018/07/11 Python
python的pytest框架之命令行参数详解(下)
2019/06/27 Python
使用python实现滑动验证码功能
2019/08/05 Python
Spring Boot中使用IntelliJ IDEA插件EasyCode一键生成代码详细方法
2020/03/20 Python
Clarks鞋法国官方网站:英国其乐鞋品牌
2018/02/11 全球购物
澳洲CFL商城:CHEMIST FOR LESS(中文)
2021/02/28 全球购物
医学生个人求职信范文
2013/09/24 职场文书
在职人员函授期间自我评价分享
2013/11/08 职场文书
师范学院毕业生求职信范文
2013/12/26 职场文书
物理教师自荐信范文
2013/12/28 职场文书
教师现实表现材料
2014/02/14 职场文书
教师节促销方案
2014/03/22 职场文书
会计专业毕业生自荐书
2014/06/25 职场文书
幼儿教师小班个人总结
2015/02/05 职场文书
教师节领导致辞
2015/07/29 职场文书
2016年毕业实习心得体会范文
2015/10/09 职场文书
2016应届毕业生实习评语
2015/12/01 职场文书