很早之前读到的一篇IE的 Performance PM Peter Gurevich关于IE下性能优化的好文章,其实大多数的建议也适合其他的浏览器下的优化,很多Tips在Nicholas C. Zakas的《High Performance JavaScript》中也有提到。文章共分为三个部分。
第一部分链接地址:
http://blogs.msdn.com/b/ie/archive/2006/08/28/728654.aspx
第二部分链接地址:
http://blogs.msdn.com/b/ie/archive/2006/11/16/ie-javascript-performance-recommendations-part-2-javascript-code-inefficiencies.aspx
第三部分链接地址:
http://blogs.msdn.com/b/ie/archive/2007/01/04/ie-jscript-performance-recommendations-part-3-javascript-code-inefficiencies.aspx
引用
Symbolic Look-up Recommendations
简单的说就是多用局部变量引用所有查找对象。例如document.forms[0]会先查找document然后在document中查找forms属性,然后在forms里查找第一个元素。如果只用一次当然没有问题,但如果需要反复用到如
check(document.forms[0].elements[0]);
check(document.forms[0].elements[1]);
check(document.forms[0].elements[2]);
...
document.forms[0].submit();
会每次重复查找同样的元素,若使用局部变量引用则变成
var fm = document.forms[0];
var fmEls = fm.elements;
check(fmEls[0]);
check(fmEls[1]);
check(fmEls[2]);
...
fm.submit();
这样只需要查找一次document.forms[0],之后都是在访问局部变量里的引用。
function BuildUI(){
var baseElement = document.getElementById(‘target’);
baseElement.innerHTML = ‘’; // Clear out the previous baseElement.innerHTML += BuildTitle();
baseElement.innerHTML += BuildBody();
baseElement.innerHTML += BuildFooter();
}
function BuildUI(){
var elementText = BuildTitle() + BuildBody() + BuildFooter(); document.getElementById(‘target’).innerHTML = elementText;
}
这个例子有两个主要问题超过了使用局部变量。
第一是问题是反复给innerHTML设值,给元素的innerHTML设置会导致页面元素的重渲染,而渲染页面元素在浏览器中特别是老板的IE中是相当耗时的工作,这个任何了解MVC的人都应该都能理解。
第二个问题是不应该在String上反复的使用+=操作,因为String是不可变的对象,+=会不断的创造很多瞬态对象。在Java中我们用StringBuilder来提高性能,在JavaScript中用Array来达到同样的目的。
function BuildUI(){
var elementText =[];
elementText.push(BuildTitle());
elementText.push(BuildBody());
elementText.push(BuildFooter());
document.getElementById(‘target’).innerHTML = elementText.join('');
}
另外一个关于局部变量缓存常见的问题是在for循环中,以ExtJs中常见的遍历Store为例。
for(var i =0; i < store.getCount(); i++){
var myName = store.getAt(i).get('name');
...
store.getAt(i).set('name', 'other name');
}
在for循环中i < store.getCount()是每次循环都会调用, 这样每循环一次都要调用store的getCount方法。
大多数时候用不用局部变量都不会有太大的性能差别,一般是<1ms.但是在循环中一定要缓存一切可以缓存的东西,因为性能的一点点损失都会被放大N倍,特别是在嵌套循环中这种放大效果更明显。所以在JS性能调优的时候我会习惯先去找for loop,因为这里才是最值得你调优的地方。
上面的例子里还有一个不太明显的问题,就是变量myName。因为JavaScript里变量是没有块级作用域的,所有myName在for循环外面还是可以访问到的。这样用一个不断被复写的变量比每次循环都创建一个新的外部变量要经济的多。
for(var i=0, ilen=store.getCount(), rec, myName; i < ilen; i++){
rec = store.getAt(i);
myName = rec.get('name');
...
rec.set('name', 'other name');
}
引用
Avoid Using the ‘with’ Keyword
能改变局部作用域的"with"除了《JavaScript王者归来》里曾经见过,在实际的项目和开源框架中我还真没见谁用过。这种用于炫技与性能无益的技巧我想还是尽量忘掉好了。去粗取精,这也正是《JavaScript:The Good Parts》中Douglas Crockford所倡导的。
引用
Running Code Using the ‘eval’ Statement is Expensive
Requirements of Eval for JSON Expressions
eval is evil, 但是滥用eval的情况还是比较少见的,因为需要用字符串的形式执行JS的情形并不多见,就算要写一些很generic的动态函数一般也能找到其他的替代方法。下面介绍一下eval的两种用途:
1.解析JSON,一般是Ajax请求的返回值,但也可以用来解析JSP标签的输出
var popupMessage = eval('<c:popupMessage/>');
2.用来动态加载外部JS文件.为什么不用script标签呢?这里存在一个普遍性问题,script标签是异步加载的,出于性能考虑不会等第一份文件加载结束再加载第二份。如果两份JS文件中的代码之间有依赖关系,如第二份文件中的代码调用了第一份文件中定义好的函数,在开发环境因为文件加载的速度很快没有问题,但是在公网环境下就不同了,可能第二份文件比较小,也可能是网络传输的延迟,导致第二份文件比第一份文件先加载完成,这样就会得到一个莫名其妙的variable is undefined的错误,而在开发环境你怎样都重现不了。解决这个问题的方案之一就是用Ajax加载JS文件,因为Ajax的异步是可控的,所以完全可以等到加载完一个以后再加载第二个,对加载返回的字节流则可以调用eval来解释执行。
Ext.Ajax.request({
method: 'GET',
url: scriptUrl,
disableCaching: false,
success: function(response) {
var jsScript = response.responseText;
if (jsScript && jsScript.length > 0) {
if(window.execScript) {
window.execScript(jsScript);
} else {
window.eval(jsScript);
}
}
ScriptLoader.load();
},
fail: function() {
ScriptLoader.load();
}
});
引用
Switch Blocks are Linear Evaluation Tables
这个问题,我想只要switch不是在for循环体中不改是最好的。因为毕竟switch的语法要简洁易读的多。在代码的可读性和性能之间有时也需要作出取舍。
引用
Avoid Closures if Possible
闭包是JS中最有争议的一种技术,因为用得好可以举重若轻的解决很多问题,但用的不好会影响性能,降低代码可读性,最糟糕的还是很多内存泄漏问题的罪魁祸首。
一般来说闭包有三种用途,1.匿名自执行函数,2.缓存,3.封装。
关于闭包的作用百度文库有一篇很好的文章:
http://wenku.baidu.com/view/ada910d4b14e852458fb577e.html
实际项目中闭包的作用还不只这些,完全取决于程序员的想象力,可以用闭包来改变回调函数的参数,如ExtJs的createDelegate,也可以用来创造一个JQuery式的万能对象。
引用
Don’t use Property Accessor Functions
Property Accessor就是常见的getter和setter,JS中一般和闭包结合使用实现前面提到的数据封装。但是显然没有谁会为所有的property设一对getter和setter就像在JavaBean里那样。如果这有人这么做,那只能说Java中毒太深。或者委婉的说思想还不够JavaScript。
分享到:
相关推荐
### JQuery Easy-UI DataGrid性能调优 #### 概述 在使用JQuery Easy-UI DataGrid组件的过程中,用户可能会遇到一系列与性能相关的问题。这些问题不仅会影响用户体验,还可能导致应用程序响应速度下降。本文旨在...
### Web2.0网站性能调优实践:关键知识点解析 #### 一、Web2.0网站性能优化的重要性 Web2.0网站强调交互性和实时性,其核心在于提供快速、稳定的服务体验。对于用户而言,服务速度和稳定性是首要考虑的因素,这...
因此,进行CSS重构和性能调优是提升网站性能的关键步骤。下面我们将深入探讨这一主题。 1. **避免使用内联样式**:内联样式会增加HTML文档的大小,降低可维护性,并使得CSS难以重用。应尽量将样式移至外部样式表中...
在编写JavaScript代码时,应尽量减少DOM操作,合理使用Repaint和Reflow技术,以减少性能损耗;在数据交换和存储时,尽量使用JSON格式来提高数据处理效率。 总之,Web前端性能优化是一个系统工程,需要前端工程师...
这可能包括使用polyfills来弥补老旧浏览器的功能缺失,或者针对特定浏览器版本进行性能调优。 #### 五、持续监控与优化 性能优化是一个持续的过程,随着应用的迭代和业务的发展,需要不断地监控和调整。这包括定期...
#### 二、JavaScript动态生成表格的性能调优 - **批量创建DOM节点**: 相比于单个添加DOM节点,一次性创建多个DOM节点再添加到页面中可以显著提高性能。 - **使用DocumentFragment**: 创建DocumentFragment对象并将...
这种特效要求用户的浏览器支持至少是IE8或更新版本,以及基于Firefox或Chrome内核的现代浏览器,因为这些浏览器提供了更好的JavaScript性能和CSS3支持,可以流畅地呈现复杂的动画效果。 【关键技术点】: 1. **...
【标题】:“一个调试好的页面”意味着我们正在讨论一个经过精心优化和测试的网页,它在各种主流浏览器中都能正常工作...它涉及到HTML、CSS、JavaScript的编写,JSP的服务器端处理,以及全面的浏览器兼容性和性能调优。
在构建基于jQuery的高性能TreeView(ASP.NET)时,我们需要考虑几个关键点,以确保最终的组件能满足特定的需求。...在实际开发中,还需要进行充分的测试和性能调优,确保在不同场景下都能提供流畅的用户体验。
- **性能调优**:通过对性能数据的分析,找到瓶颈并进行针对性的优化。 ### 3. 如何使PHP代理(Agent)工作 - **性能监控**:利用`window.performance` API以及`window.onerror`事件来监控页面加载时间及...
6. **性能监控**:使用性能测试工具对应用在IE中的性能进行监控和调优。 7. **测试报告**:总结测试过程和结果,提供改进建议。 总之,IE测试对于确保应用的全面兼容性和用户体验至关重要。通过系统化的测试方法和...
4. **优化和性能调优**:了解如何处理大数据,以及如何优化图表的加载和渲染速度,确保在各种环境下都能提供良好的用户体验。 5. **社区资源**:参与ECharts的社区讨论,获取最新的开发资讯,与其他开发者交流经验...
前端开发者还需要了解HTTP协议、浏览器工作原理、SEO优化和性能调优等相关知识。 总结来说,这个压缩包提供了一个基本的前端网页开发框架,包括HTML文件用于内容结构,CSS文件控制样式,图片和图片目录增强视觉体验...
除了上述技术,前端培训还会涉及JavaScript(包括ES6及以上的特性)、jQuery、React、Vue、Angular等框架和库的使用,以及响应式设计、用户体验优化、性能调优等相关知识。通过系统的学习和实践,开发者能够掌握构建...
AJAX(Asynchronous JavaScript and XML)是构建Web 2.0应用程序的关键技术,它允许在不重新加载整个网页的情况下更新部分页面内容,提供更流畅、响应更快的用户体验。AJAX 不是一种全新的编程语言,而是通过结合已...
2. **性能优化**:EXTJS 4.2.3对框架进行了性能调优,使得页面加载速度更快,组件渲染更高效。这对于大型、数据密集型的应用来说尤为重要,可以提供更佳的响应时间。 3. **组件增强**:EXTJS中的各个组件,如表格...