最佳实践

使用常量:

当出现以下几种情况的时候,就可以将值提取出来作为常量:

重复值:任何在多处用到的值都应抽取为一个常量。

用户界面字符串:任何用于显示给用户的字符串都应抽取为一个常量。

URLs:在web应用中,资源位置很容易变更。

任意可能会更改的值:每当你在用到字面量值的时候,你都要问一下自己这个值在未来是不是会变化。字面量就是赋值给变量的右边的值。

性能:

注意作用域:

随着作用域链中作用域的增加,访问当前作用域以外的变量的时间也在增加。访问全局变量总是要比访问局部变量慢,因为需要遍历作用域。

解决方案:将在一个函数中,会用到多次的全局对象存储为局部变量。

对象属性的访问:

对象属性的访问是一个o(n)操作,对象的任何属性查找都要比访问变量或者数组花费更长时间,因为必须在原型链中对拥有该名称的属性进行一次搜索。简而言之,属性查找越多,执行时间就越长。

解决方案:举个例子:

const query = window.location.href.substring(window.location.href.indexOf(‘?’))

这段代码由于两次用到了window.location.href,同样的查找进行了两次,因此效率特别不好。一旦多次用到对象属性,应该将其存储在局部变量中。第一次的访问该值会是o(n),然后后续的访问都会是o(1),就会节省很多。例如,之前的代码可以如下重写:

const url = window.location.href;

const query = url.substring(url.indexOf(‘?’));

优化循环:

简化终止条件:由于每次循环过程都会计算终止条件,所以必须保证它尽可能快。也就是说避免属性查找或其它O(n)的操作。

简化循环体:循环体是执行最多的,所以要确保其被最大限度的优化。确保没有某些可以被很容易移出循环的密集计算。

展开循环:

当循环的次数是确定的,消除循环并使用多次函数调用往往更快。如果循环中的迭代次数不能事先确定,那可以考虑使用一种叫做duff装置的技术。针对大数据集使用展开循环可以节省很多时间。但对于小数据集,额外的开销则可能得不偿失,以下是例子:

function duff(arr, process) {

const len = arr.leng

const iterations = Math.floor(len/8);

const leftover = len%8;

let i = 0;

if (leftover > 0) {

do {

process(arr[i++]);

} while (--leftover > 0);

}

do {

process(arr[i++]);

process(arr[i++]);

process(arr[i++]);

process(arr[i++]);

process(arr[i++]);

process(arr[i++]);

process(arr[i++]);

process(arr[i++]);

} while(--iterations > 0)

}

性能的其它注意事项:

原生方法较快:只要有可能,使用原声方法而不是自己用JavaScript重新一个。原生方法是用诸如C/C++之类的编译型语言写出来的,所以要不JavaScript的快很多很多。

Switch语句较快:如果有一系列if-else可以考虑换成单个Switch则可以得到更快的代码。还可以通过将case语句按照最可能的到最不可能的进一步优化。

位运算符较快:当进行算数运算的时候,位运算操作要比任何布尔运算或者算数运算快。选择性的用位运算替换算数运算可以极大提升复杂计算的性能。诸如取模,逻辑与,逻辑或都可以考虑用位运算来替换。

最小语句数:

JavaScript代码中的语句数量也影响所执行的操作的速度。

多个变量声明:多个变量声明应该尽量合并成一个单个语句声明,例如:

const a=1,

b=2,

c=3;

插入迭代值:当使用迭代值的时候,尽可能合并语句,例如:

const name = arr[i]

i++;

可以合并成:

const name = arr[i++];

使用数组和字面量:当创建数组和对象时,应该尽量使用字面量而不是使用构造函数,因为这样可以消除不必要的语句:

const a = {

name: ‘a’

}

优化DOM交互:

最小化现场更新:对页面已存在的dom进行的操作,不管是插入还是删除,都是一个现场更新,对性能的损耗非常大。现场更新的越多,代码完成执行所花的时间就越长。完成一个操作所需的现场更新越少,代码就越快。

一种方法是将某一部分整个做移除,然后更新,更新完以后再插入回页面。这样子会造成每次的更新页面会有不必要的闪烁。

最佳方案是使用document.createDocumentFragment(),然后将需要加入的新元素用这个返回对象的appendChild()将所有需要添加到页面的元素添加进去。最后再将对象使用appendChild()添加到页面中。

使用innerHTML:innerHTML也比createElement()和appendChild()之类的方法快很多。同样,一次性调用innerHTML也比多次调用快很多,因为一次innerHTML就是一次现场更新。

使用事件代理:大多数Web应用在用户交互上大量用到了事件处理程序。页面上的事件处理程序的数量和页面响应用户交互的速度之间有个负相关。为了减轻这种损耗,最好使用事件代理。也就是通过冒泡的原理,将多个元素的事件绑定到上层元素当中。

注意HTMLCollection:使用它对Web应用的性能而言是巨大的损害。任何时候访问HTMLCollection,不管它是一个属性还是一个方法,都是在文档上进行一个查询,这个查询开销很昂贵。比如可以将一个HTMLCollection对象的循环,将它的length保存一个变量。以下几种情况会返回HTMLCollection对象:

进行了对getElementsByTagName()的调用。

获取了元素的childNodes属性。

获取了元素的attributes属性。

访问了特殊的集合,如document.forms,document.images等。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,287评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,346评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,277评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,132评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,147评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,106评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,019评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,862评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,301评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,521评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,682评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,405评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,996评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,651评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,803评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,674评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,563评论 2 352

推荐阅读更多精彩内容

  • 我想跨过一座座山 趟过一条条河 去看不一样的风景 吃不一样的苦 听着不同的方言 走那崎岖的路 吹凛冽的风 和过去告...
    少年阿火阅读 101评论 0 0
  • 什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都为你做了这...
    Silly_N_Fool阅读 516评论 0 1
  • In the game, you need to control the athletes to kick the...
    Green_Mage阅读 228评论 0 0
  • 《见识》 第九章 好好说话 我就职于市场部,每天的工作就是把公司的产品介绍给客户,达成销售。好好说话对我来说,非常...
    爱晴海的阳光阅读 152评论 0 0
  • 很生动的中心图,思维清晰,线条流畅。关键词提取不错。 建议发散思维训练下的分支还可作进一步的归纳,加油! '思维清...
    丹菡阅读 2,750评论 0 2