Note On <High Performance JavaScript>
来源:互联网 发布:windows桌面文件丢失 编辑:程序博客网 时间:2024/05/21 22:53
Chapter 8: 实践技巧
避免双重执行
这个部分讨论的是动态执行的JS代码,通过eval(),Function(),setTimeout()和setInterval()所创建的代码都会经过两次执行的过程,而这导致它们慢很多。
作者的建议是,对于eval()和Function()最好是索性直接避免,而后两者setTimeout()和setInterval(),可以传递预先定义的函数。
====================================================================
使用字面定义
这个问题至少David在【Effective JavaScript】里说过。简单讲就是:
//create an objectvar myObject = new Object();myObject.name = "Nicholas";myObject.count = 50;myObject.flag = true;myObject.pointer = null;//create an arrayvar myArray = new Array();myArray[0] = "Nicholas";myArray[1] = 50;myArray[2] = true;myArray[3] = null;
不如下面执行效率高:
//create an objectvar myObject = { name: & quot;Nicholas & quot;, count: 50, flag: true, pointer: null};//create an arrayvar myArray = [ & quot;Nicholas & quot;, 50, true, null];
====================================================================
不要重复执行做过的事情
这个部分的例子很经典,判断浏览器和版本,决定执行怎样的代码,通常的写法可能会是:
function addHandler(target, eventType, handler) { if (target.addEventListener) { //DOM2 Events target.addEventListener(eventType, handler, false); } else { //IE target.attachEvent("on" + eventType, handler); }}function removeHandler(target, eventType, handler) { if (target.removeEventListener) { //DOM2 Events target.removeEventListener(eventType, handler, false); } else { //IE target.detachEvent("on" + eventType, handler); }}
这里判断浏览器的逻辑被重复了。有两个解决方案:
慵懒加载
function addHandler(target, eventType, handler) { //overwrite the existing function if (target.addEventListener) { //DOM2 Events addHandler = function(target, eventType, handler) { target.addEventListener(eventType, handler, false); }; } else { //IE addHandler = function(target, eventType, handler) { target.attachEvent("on" + eventType, handler); }; } //call the new function addHandler(target, eventType, handler);}function removeHandler(target, eventType, handler) { //overwrite the existing function if (target.removeEventListener) { //DOM2 Events removeHandler = function(target, eventType, handler) { target.addEventListener(eventType, handler, false); }; } else { //IE removeHandler = function(target, eventType, handler) { target.detachEvent("on" + eventType, handler); }; } //call the new function removeHandler(target, eventType, handler);}
在一个函数体自身内重新定义该函数,厉害呀!适用于并非在页面加载完成后马上要执行的功能。
条件性预先加载
var addHandler = document.body.addEventListener ? function(target, eventType, handler) { target.addEventListener(eventType, handler, false); } : function(target, eventType, handler) { target.attachEvent("on" + eventType, handler); };var removeHandler = document.body.removeEventListener ? function(target, eventType, handler) { target.removeEventListener(eventType, handler, false); } : function(target, eventType, handler) { target.detachEvent("on" + eventType, handler); };
适用于页面加载后要立即执行的功能。
====================================================================
使用执行效率最高的方法
位操作符
在基于32位二进制表达上进行的位运算是最快的,而且其实JS支持这些位操作符:&, |,^和~,甚至>>,<<和>>>。
比如下面的代码:
for (var i = 0, len = rows.length; i < len; i++) { if (i % 2) { className = "even"; } else { className = "odd"; } //apply class}
换成下面的方案后执行起来会快很多:
for (var i = 0, len = rows.length; i < len; i++) { if (i & 1) { className = "odd"; } else { className = "even"; } //apply class}
另外还有个位掩码(bitmask)的方案也很经典,这个我曾经在SQL的层面用过:
var OPTION_A = 1;var OPTION_B = 2;var OPTION_C = 4;var OPTION_D = 8;var OPTION_E = 16;var options = OPTION_A | OPTION_C | OPTION_D;//is option A in the list?if (options & OPTION_A) { //do something}//is option B in the list?if (options & OPTION_B) { //do something}
原生态方法
就像Math这种內建对象的方法比如Math.acos(x)其实都是在更低的层面上实现的,会快很多。
还有查找DOM元素的两个方法:querySelector()和querySelectorAll()。
Chapter 9: 构建与配置高性能的JavaScript应用程序
这一章讲的东西跟写代码没有直接关系。是在构建大型项目时会用到的构建工具和一些用于优化性能的工具。
这些工具可以做的事情包括:
- 把若干个JS文件整合成一个JS文件;
- 有条件性地插入一些代码,比如根据不同开发阶段插入不同用于调试的代码;
- 修改新版本文件名来解决缓存技术导致的文件更新问题;
- 上传新版文件至远端服务器,类似CDN;
- 等等
作者是以Ant为例子展示这些动能的,不过近年来貌似没有人再用Ant了,完全没有听人讨论过。
其他的相关工具和方法还包括:
- 给JS文件瘦身,用类似YUI Compressor和Packer这样的工具;
- 在服务器端开启压缩功能,使用gzip这样的编码格式传输文件;
- 缓存JS文件,避免多余的HTTP请求,
- 使用CDN这样的分布式工具;
- 等等。
最后作者推荐一个Yahoo自己的工具:smasher,它能完成大多数上面提到的功能。
Chapter 10: 工具
这一章介绍的工具主要用于两个方面,分析JS程序的性能,和分析页面加载过程的瓶颈。
值得注意的是,有些优化性能的方案是受限于浏览器的,它或许反而导致在其他浏览器上效率变差。
分析性能
YUI Profiler
匿名函数
为了配合性能分析工具,最好还是不要使用匿名函数,而且内联呼叫也不如显式地赋值函数再调用。
比如下面的写法:
myNode.onclick = function() { myApp.loadData();};
不如换做:
myApp._onClick = function() { myApp.loadData();};myNode.onclick = myApp._onClick;
寻找被阻滞的脚本文件
Page Speed
依然在发展中。
Fiddler
这个我一直有用。
YSlow
从项目的Git主页来看,最后一次更新是在2014年三月,也就是说它的开发已经被停止三年了,等同于被抛弃的项目。
dynaTrace Ajax Edition
这个工具不是免费的。
顺藤摸瓜找到的一些链接:
15 Website Speed Test Tools for Analyzing Web Performance
Must See JavaScript Dev Tools That Put Other Dev Tools to Shame
- Note On <High Performance JavaScript>
- Note On <High Performance JavaScript>
- Note On <High Performance JavaScript>
- [翻译]High Performance JavaScript(001)
- [翻译]High Performance JavaScript(002)
- [翻译]High Performance JavaScript(003)
- [翻译]High Performance JavaScript(004)
- [翻译]High Performance JavaScript(005)
- [翻译]High Performance JavaScript(006)
- [翻译]High Performance JavaScript(007)
- [翻译]High Performance JavaScript(008)
- [翻译]High Performance JavaScript(009)
- [翻译]High Performance JavaScript(010)
- [翻译]High Performance JavaScript(011)
- [翻译]High Performance JavaScript(012)
- [翻译]High Performance JavaScript(013)
- [翻译]High Performance JavaScript(014)
- [翻译]High Performance JavaScript(015)
- c++操作mysql
- API Guide:APP组件-应用小部件主机
- [BZOJ4801]打牌 博弈搜索
- React-Router4.0路由中文文档api
- 使用Kaptcha进行验证码的生成和验证
- Note On <High Performance JavaScript>
- Android开发之横竖屏任意切换
- 指定查询
- Tex Quotes, UVa 272
- Synopsys dc-2010-sp5-3安装过程(上)
- 归并排序是一种怎么样的体验
- 关于解决多台服务器间的文件实时同步问题
- GDOI第三轮模拟总结
- RecyclerView Prefetch功能探究