- 浏览: 466535 次
- 性别:
- 来自: 潘多拉
文章分类
最新评论
-
lijunwyf:
代码好像不完整,后端没串起来的感觉
Json-RPC for java首次尝试 -
jerry.chen:
我用这种方式去,貌似没啥效果,楼主!
Xfire开发的webservice客户端超时问题解决 -
漫步邃思:
这个问题常遇到,老是想不起来解决方法,记住了
resin3.1.0无法解析EL表达式问题解决 -
dampce032:
在不删掉integratedSecurity=true;的情况 ...
JDBC 连接SQLServer数据库(Failed to load the sqljdbc_auth.dll) -
kill_e680:
取CPU号和取硬盘号,在linux下可以用吗?
sigar使用:在web中应用sigar取得系统信息
一.执行效率
1. DOM
1.1 使用DocumentFragment优化多次append
说明:添加多个dom元素时,先将元素append到DocumentFragment中,最后统一将DocumentFragment添加到页面。
该做法可以减少页面渲染dom元素的次数。经IE和Fx下测试,在append1000个元素时,效率能提高10%-30%,Fx下提升较为明显。
1.2 通过模板元素clone,替代createElement
说明:通过一个模板dom对象cloneNode,效率比直接创建element高。
性能提高不明显,约为10%左右。在低于100个元素create和append操作时,没有优势。
1.3 使用一次innerHTML赋值代替构建dom元素
说明:根据数据构建列表样式的时候,使用设置列表容器innerHTML的方式,比构建dom元素并append到页面中的方式,效率有数量级上的提高。
1.4 使用firstChild和nextSibling代替childNodes遍历dom元素
说明:约能获得30%-50%的性能提高。逆向遍历时使用lastChild和previousSibling。
2. 字符串
2.1 使用Array做为StringBuffer,代替字符串拼接的操作
说明:IE在对字符串拼接的时候,会创建临时的String对象;经测试,在IE下,当拼接的字符串越来越大时,运行效率会急剧下降。Fx和Opera都 对字符串拼接操作进行了优化;经测试,在Fx下,使用Array的join方式执行时间约为直接字符串拼接的1.4倍。
3. 循环语句
3.1 将循环控制量保存到局部变量
说明:对数组和列表对象的遍历时,提前将length保存到局部变量中,避免在循环的每一步重复取值。
3.2 顺序无关的遍历时,用while替代for
说明:该方法可以减少局部变量的使用。比起效率优化,更能直接看到的是字符数量的优化。该做法有程序员强迫症的嫌疑。
4. 条件分支
4.1 将条件分支,按可能性顺序从高到低排列
说明:可以减少解释器对条件的探测次数。
4.2 在同一条件子的多(>2)条件分支时,使用switch优于if
说明:switch分支选择的效率高于if,在IE下尤为明显。4分支的测试,IE下switch的执行时间约为if的一半。
4.3 使用三目运算符替代条件分支
使用前:
if (a > b) {
num = a;
} else {
num = b;
}
使用后:
num = a > b ? a : b;
5. 定时器
5.1 需要不断执行的时候,优先考虑使用setInterval
说明:setTimeout每一次都会初始化一个定时器。setInterval只会在开始的时候初始化一个定时器
5.2 使用function而不是string
说明:如果把字符串作为setTimeout和setInterval的参数,浏览器会先用这个字符串构建一个function。
6. 其他
6.1 尽量不使用动态语法元素
说明:eval、Function、execScript等语句会再次使用javascript解析引擎进行解析,需要消耗大量的执行时间。
6.2 重复使用的调用结果,事先保存到局部变量
说明:避免多次取值的调用开销。
6.3 使用直接量
说明:
6.4 避免使用with
说明: with虽然可以缩短代码量,但是会在运行时构造一个新的scope。
OperaDev上还有这样的解释,使用with语句会使得解释器无法在语法解析阶段对代码进行优化。对此说法,无法验证。
6.5 巧用||和&&布尔运算符
重要程度:★★★
6.6 类型转换
说明:
1). 数字转换成字符串,应用"" + 1,性能上:("" +) > String() > .toString() > new String();
2). 浮点数转换成整型,不使用parseInt(), parseInt()是用于将字符串转换成数字,而不是浮点数和整型之间的转换,建议使用Math.floor()或者Math.round()
3). 对于自定义的对象,推荐显式调用toString()。内部操作在尝试所有可能性之后,会尝试对象的toString()方法尝试能否转化为String。
二.内存管理
2.1 循环引用
说明:如果循环引用中包含DOM对象或者ActiveX对象,那么就会发生内存泄露。内存泄露的后果是在浏览器关闭前,即使是刷新页面,这部分内存不会被浏览器释放。
简单的循环引用:
但是通常不会出现这种情况。通常循环引用发生在为dom元素添加闭包作为expendo的时候。
如:
init在执行的时候,当前上下文我们叫做context。这个时候,context引用了el,el引用了function,function引用了context。这时候形成了一个循环引用。
下面2种方法可以解决循环引用:
1) 置空dom对象
将el置空,context中不包含对dom对象的引用,从而打断循环应用。
如果我们需要将dom对象返回,可以用如下方法:
2) 构造新的context
把function抽到新的context中,这样,function的context就不包含对el的引用,从而打断循环引用。
2.2 通过javascript创建的dom对象,必须append到页面中
说明:IE下,脚本创建的dom对象,如果没有append到页面中,刷新页面,这部分内存是不会回收的!
示例代码:
2.3 释放dom元素占用的内存
说明:
将dom元素的innerHTML设置为空字符串,可以释放其子元素占用的内存。
在rich应用中,用户也许会在一个页面上停留很长时间,可以使用该方法释放积累得越来越多的dom元素使用的内存。
2.4 释放javascript对象
说明:在rich应用中,随着实例化对象数量的增加,内存消耗会越来越大。所以应当及时释放对对象的引用,让GC能够回收这些内存控件。
对象:obj = null
对象属性:delete obj.myproperty
数组item:使用数组的splice方法释放数组中不用的item
2.5 避免string的隐式装箱
说明:对string的方法调用,比如'xxx'.length,浏览器会进行一个隐式的装箱操作,将字符串先转换成一个String对象。推荐对声明有可能使用String实例方法的字符串时,采用如下写法:
var myString = new String('Hello World');
1. DOM
1.1 使用DocumentFragment优化多次append
说明:添加多个dom元素时,先将元素append到DocumentFragment中,最后统一将DocumentFragment添加到页面。
该做法可以减少页面渲染dom元素的次数。经IE和Fx下测试,在append1000个元素时,效率能提高10%-30%,Fx下提升较为明显。
使用前: for (var i = 0; i < 1000; i++) { var el = document.createElement('p'); el.innerHTML = i; document.body.appendChild(el); } 使用后: var frag = document.createDocumentFragment(); for (var i = 0; i < 1000; i++) { var el = document.createElement('p'); el.innerHTML = i; frag.appendChild(el); } document.body.appendChild(frag);
1.2 通过模板元素clone,替代createElement
说明:通过一个模板dom对象cloneNode,效率比直接创建element高。
性能提高不明显,约为10%左右。在低于100个元素create和append操作时,没有优势。
使用前: var frag = document.createDocumentFragment(); for (var i = 0; i < 1000; i++) { var el = document.createElement('p'); el.innerHTML = i; frag.appendChild(el); } document.body.appendChild(frag); 使用后: var frag = document.createDocumentFragment(); var pEl = document.getElementsByTagName('p')[0]; for (var i = 0; i < 1000; i++) { var el = pEl.cloneNode(false); el.innerHTML = i; frag.appendChild(el); } document.body.appendChild(frag);
1.3 使用一次innerHTML赋值代替构建dom元素
说明:根据数据构建列表样式的时候,使用设置列表容器innerHTML的方式,比构建dom元素并append到页面中的方式,效率有数量级上的提高。
使用前: var frag = document.createDocumentFragment(); for (var i = 0; i < 1000; i++) { var el = document.createElement('p'); el.innerHTML = i; frag.appendChild(el); } document.body.appendChild(frag); 使用后: var html = []; for (var i = 0; i < 1000; i++) { html.push('<p>' + i + '</p>'); } document.body.innerHTML = html.join('');
1.4 使用firstChild和nextSibling代替childNodes遍历dom元素
说明:约能获得30%-50%的性能提高。逆向遍历时使用lastChild和previousSibling。
使用前: var nodes = element.childNodes; for (var i = 0, l = nodes.length; i < l; i++) { var node = nodes[i]; …… } 使用后: var node = element.firstChild; while (node) { …… node = node.nextSibling; }
2. 字符串
2.1 使用Array做为StringBuffer,代替字符串拼接的操作
说明:IE在对字符串拼接的时候,会创建临时的String对象;经测试,在IE下,当拼接的字符串越来越大时,运行效率会急剧下降。Fx和Opera都 对字符串拼接操作进行了优化;经测试,在Fx下,使用Array的join方式执行时间约为直接字符串拼接的1.4倍。
使用前: var now = new Date(); var str = ''; for (var i = 0; i < 10000; i++) { str += '123456789123456789'; } alert(new Date() - now); 使用后: var now = new Date(); var strBuffer = []; for (var i = 0; i < 10000; i++) { strBuffer.push('123456789123456789'); } var str = strBuffer.join(''); alert(new Date() - now);
3. 循环语句
3.1 将循环控制量保存到局部变量
说明:对数组和列表对象的遍历时,提前将length保存到局部变量中,避免在循环的每一步重复取值。
使用前: var list = document.getElementsByTagName('p'); for (var i = 0; i < list.length; i++) { …… } 使用后: var list = document.getElementsByTagName('p'); for (var i = 0, l = list.length; i < l; i++) { …… }
3.2 顺序无关的遍历时,用while替代for
说明:该方法可以减少局部变量的使用。比起效率优化,更能直接看到的是字符数量的优化。该做法有程序员强迫症的嫌疑。
使用前: var arr = [1,2,3,4,5,6,7]; var sum = 0; for (var i = 0, l = arr.length; i < l; i++) { sum += arr[i]; } 使用后: var arr = [1,2,3,4,5,6,7]; var sum = 0, l = arr.length; while (l--) { sum += arr[l]; }
4. 条件分支
4.1 将条件分支,按可能性顺序从高到低排列
说明:可以减少解释器对条件的探测次数。
4.2 在同一条件子的多(>2)条件分支时,使用switch优于if
说明:switch分支选择的效率高于if,在IE下尤为明显。4分支的测试,IE下switch的执行时间约为if的一半。
4.3 使用三目运算符替代条件分支
使用前:
if (a > b) {
num = a;
} else {
num = b;
}
使用后:
num = a > b ? a : b;
5. 定时器
5.1 需要不断执行的时候,优先考虑使用setInterval
说明:setTimeout每一次都会初始化一个定时器。setInterval只会在开始的时候初始化一个定时器
使用前: var timeoutTimes = 0; function timeout () { timeoutTimes++; if (timeoutTimes < 10) { setTimeout(timeout, 10); } } timeout(); 使用后: var intervalTimes = 0; function interval () { intervalTimes++; if (intervalTimes >= 10) { clearInterval(interv); } } var interv = setInterval(interval, 10);
5.2 使用function而不是string
说明:如果把字符串作为setTimeout和setInterval的参数,浏览器会先用这个字符串构建一个function。
使用前: var num = 0; setTimeout('num++', 10); 使用后: var num = 0; function addNum () { num++; } setTimeout(addNum, 10);
6. 其他
6.1 尽量不使用动态语法元素
说明:eval、Function、execScript等语句会再次使用javascript解析引擎进行解析,需要消耗大量的执行时间。
6.2 重复使用的调用结果,事先保存到局部变量
说明:避免多次取值的调用开销。
使用前: var h1 = element1.clientHeight + num1; var h2 = element1.clientHeight + num2; 使用后: var eleHeight = element1.clientHeight; var h1 = eleHeight + num1; var h2 = eleHeight + num2;
6.3 使用直接量
说明:
var a = new Array(param,param,...) -> var a = [] var foo = new Object() -> var foo = {} var reg = new RegExp() -> var reg = /.../
6.4 避免使用with
说明: with虽然可以缩短代码量,但是会在运行时构造一个新的scope。
OperaDev上还有这样的解释,使用with语句会使得解释器无法在语法解析阶段对代码进行优化。对此说法,无法验证。
使用前: with (a.b.c.d) { property1 = 1; property2 = 2; } 使用后: var obj = a.b.c.d; obj.property1 = 1; obj.property2 = 2;
6.5 巧用||和&&布尔运算符
重要程度:★★★
使用前: function eventHandler (e) { if(!e) e = window.event; } 使用后: function eventHandler (e) { e = e || window.event; } 使用前: if (myobj) { doSomething(myobj); } 使用后: myobj && doSomething(myobj);
6.6 类型转换
说明:
1). 数字转换成字符串,应用"" + 1,性能上:("" +) > String() > .toString() > new String();
2). 浮点数转换成整型,不使用parseInt(), parseInt()是用于将字符串转换成数字,而不是浮点数和整型之间的转换,建议使用Math.floor()或者Math.round()
3). 对于自定义的对象,推荐显式调用toString()。内部操作在尝试所有可能性之后,会尝试对象的toString()方法尝试能否转化为String。
二.内存管理
2.1 循环引用
说明:如果循环引用中包含DOM对象或者ActiveX对象,那么就会发生内存泄露。内存泄露的后果是在浏览器关闭前,即使是刷新页面,这部分内存不会被浏览器释放。
简单的循环引用:
var el = document.getElementById('MyElement'); var func = function () {…} el.func = func; func.element = el;
但是通常不会出现这种情况。通常循环引用发生在为dom元素添加闭包作为expendo的时候。
如:
function init() { var el = document.getElementById('MyElement'); el.onclick = function () {……} } init();
init在执行的时候,当前上下文我们叫做context。这个时候,context引用了el,el引用了function,function引用了context。这时候形成了一个循环引用。
下面2种方法可以解决循环引用:
1) 置空dom对象
使用前: function init() { var el = document.getElementById('MyElement'); el.onclick = function () {……} } init(); 使用后: function init() { var el = document.getElementById('MyElement'); el.onclick = function () {……} el = null; } init();
将el置空,context中不包含对dom对象的引用,从而打断循环应用。
如果我们需要将dom对象返回,可以用如下方法:
使用前: function init() { var el = document.getElementById('MyElement'); el.onclick = function () {……} return el; } init(); 使用后: function init() { var el = document.getElementById('MyElement'); el.onclick = function () {……} try{ return el; } finally { el = null; } } init();
2) 构造新的context
使用前: function init() { var el = document.getElementById('MyElement'); el.onclick = function () {……} } init(); 使用后: function elClickHandler() {……} function init() { var el = document.getElementById('MyElement'); el.onclick = elClickHandler; } init();
把function抽到新的context中,这样,function的context就不包含对el的引用,从而打断循环引用。
2.2 通过javascript创建的dom对象,必须append到页面中
说明:IE下,脚本创建的dom对象,如果没有append到页面中,刷新页面,这部分内存是不会回收的!
示例代码:
function create () { var gc = document.getElementById('GC'); for (var i = 0; i < 5000 ; i++) { var el = document.createElement('div'); el.innerHTML = "test"; //下面这句可以注释掉,看看浏览器在任务管理器中,点击按钮然后刷新后的内存变化 gc.appendChild(el); } }
2.3 释放dom元素占用的内存
说明:
将dom元素的innerHTML设置为空字符串,可以释放其子元素占用的内存。
在rich应用中,用户也许会在一个页面上停留很长时间,可以使用该方法释放积累得越来越多的dom元素使用的内存。
2.4 释放javascript对象
说明:在rich应用中,随着实例化对象数量的增加,内存消耗会越来越大。所以应当及时释放对对象的引用,让GC能够回收这些内存控件。
对象:obj = null
对象属性:delete obj.myproperty
数组item:使用数组的splice方法释放数组中不用的item
2.5 避免string的隐式装箱
说明:对string的方法调用,比如'xxx'.length,浏览器会进行一个隐式的装箱操作,将字符串先转换成一个String对象。推荐对声明有可能使用String实例方法的字符串时,采用如下写法:
var myString = new String('Hello World');
发表评论
-
一个PHPRPC的JAVA例程
2011-10-17 08:10 2625PHPRPC 最大的一个亮点就是它支持在浏览器环境中通过 Ja ... -
Jquery获取表单里text,areatext,checkbox等的值
2011-07-30 09:28 4417jquery取得text,areatext,radio,ch ... -
比较全的JS checkbox全选、删除功能代码
2011-07-29 15:24 1462<script language="jav ... -
通过js进行页面跳转
2011-07-27 10:46 1137window.parent.window.location ... -
javascript 取table中内容
2011-07-16 09:50 10001,有如下表格,我们要取第2行第2列的值 <tabl ... -
JavaScript密码强度检测源代码
2011-07-16 09:49 9381.Body代码部分 <body> ... -
让图片自动适应大小
2011-07-16 09:41 1153function imgadapter(obj,width ... -
在b/s开发中经常用到的javaScript技术
2011-07-16 09:39 1148在b/s开发中经常用到的javaScript技术 一、验证类 ... -
使用JS提交表单,该表action
2011-07-16 09:29 841<script> function repl ... -
JavaScript开发工具 共享
2011-07-15 09:26 1很不错的一个JavaScript开发工具,安装完文件大小不到1 ... -
firfox下div、span等对象的onkeydown、onkeyup不起作用问题解决
2011-07-15 09:11 1344firfox下div、span等对象的onkeydown、on ... -
js获取action的返回值
2011-07-15 09:02 15645今天遇到这样一个问题我需要获得一个action执行方法后的一个 ... -
超级实用且不花哨的js代码大全
2011-07-15 08:59 2049事件源对象 event.srcElement.tagNa ... -
javascript 控制 html元素 显示/隐藏
2011-07-14 18:01 11141。编写js函数 <script type=&qu ... -
javascript 取table中内容
2011-07-14 17:54 10631,有如下表格,我们要取第2行第2列的值 <table ... -
HTML可输可选下拉框实现的JavaScript脚本
2011-07-13 11:51 1417HTML可输可选下拉框实现的JavaScript脚本 关键字: ... -
JS正则表达式详解
2011-07-13 11:17 1152JS的正则表达式 正则表达式常用元字符介绍 先看看 ...
相关推荐
【编写高性能JavaScript】文档主要关注的是如何优化JavaScript代码,尤其是涉及到DOM操作和字符串处理的部分,以提高代码执行效率。以下是对这些知识点的详细说明: 1. **DOM操作优化** - **DocumentFragment**:...
在深入探讨如何编写高性能JavaScript代码之前,我们首先要明确,虽然JavaScript引擎,尤其是Google的V8引擎在执行大型JavaScript应用时表现出色,但不同浏览器或平台上的JavaScript引擎存在差异。因此,编写的代码应...
编写高性能JavaScript代码是前端开发中不可忽视的一个环节。随着硬件性能的不断提升,部分开发者可能会认为性能优化不再重要,但实际上,在用户层面,性能问题仍然会对网页的执行效率和用户体验产生直接影响。以下是...
本文总结了编写高性能JavaScript代码的最佳实践,讨论了JavaScript代码性能问题的几种设计模式对性能的影响,并提供了一些技巧来提高JavaScript代码的性能。 在研究JavaScript代码性能问题时,需要注意到设计模式对...
- 第八章 Programming Practices 编程实践:此章节可能强调了编写高性能JavaScript代码所需遵循的最佳实践。 - 第九章 Building and Deploying High-Performance JavaScript Applications 构建和部署高性能...
这一章提供了编写高性能JavaScript代码的最佳实践,包括代码组织、错误处理、调试技巧,以及如何利用性能分析工具来识别和修复性能问题。 第九章 “构建和部署高性能JavaScript应用”: 本章专注于构建流程和部署...
《高性能JavaScript》揭示的技术和策略能帮助你在开发过程中消除性能瓶颈。你将会了解如何提升各方面的性能,包括代码的加载、运行、DOM交互、页面生存周期等。雅虎的前端工程师Nicholas C. Zakas和其他五位...
本文将深入探讨标题和描述中提及的两本书籍《JavaScript语言精粹》和《高性能JavaScript》所涵盖的知识点。 首先,我们来关注《JavaScript语言精粹》。这本书主要侧重于JavaScript的核心概念和最佳实践,旨在帮助...
《Effective JavaScript:编写高质量JavaScript代码的68个有效方法》是David Herman撰写的一本JavaScript编程指南,该书基于作者在Ecma的JavaScript标准化委员会的工作经验,深入探讨了JavaScript的内部工作机制、...
在JavaScript的世界里,性能优化是开发者...对于提供的文档“提高AJAX客户端响应速度.doc”和“编写高性能JavaScript.doc”,它们很可能会深入探讨这些话题,通过阅读这些文档,开发者可以获取更多实用技巧和最佳实践。
《高性能JavaScript 2015》是由知名前端开发者Nicolas C. Zakas撰写的一本经典著作,专注于探讨如何优化JavaScript代码以实现更高效的应用程序。这本书面向的是中级到高级的JavaScript开发者,旨在帮助他们理解并...
《高性能JavaScript》是一本深入探讨JavaScript编程技巧与优化策略的专业书籍。它主要针对那些希望提升JavaScript应用程序性能的开发者,无论是前端网页开发还是后端Node.js应用,都能从中受益。本书全面覆盖了...
《高性能JavaScript》是由尼古拉斯·泽卡斯(Nicholas C. Zakas)撰写的一本经典著作,专注于探讨如何在JavaScript环境中实现最佳性能。这本书深入浅出地讲解了JavaScript编程中的许多关键概念和技术,旨在帮助...
编写高质量的JavaScript代码对于确保软件的可维护性、性能和用户体验至关重要。以下是对"编写高质量JavaScript代码的68方法"的一些关键知识点的详细阐述: 1. **变量声明**:始终使用`let`、`const`而非`var`来声明...
通过学习《高性能JavaScript》,开发者不仅可以提升JavaScript编程的技能,还能培养出一种性能至上的编程思维,从而在实际项目中编写出更快、更稳定的代码。这本书对于任何想要提升JavaScript编程水平的开发者来说,...