JS性能优化的一些建议

数据存储

在JS中,数据存储的位置会对代码整体性能产生重大的影响(因为作用域的读取顺序)。

数据存储共有4种方式:字面量、变量、数组、对象成员

通过以下策略,你可以显著提升JS的实际性能:
  1. 访问字面量和局部变量的速度最快,相反,访问数组元素和对象成员相对较慢。
  2. 由于局部变量存在于作用域链的起始位置,因此访问局部变量比访问跨作用域变量更快。变量在作用域链的位置越深,访问所需时间就越长。由于全局变量总处于作用域链的最末端,因此访问速度也是最慢。
  3. 嵌套的对象成员会明显影响性能,尽量少用。
  4. 属性或方法在原型链中的位置越深,访问它的速度也越慢。
  5. 通常来说,你可以通过把常用的对象成员、数组元素、跨域变量保存在局部变量中来改善JS性能,因为局部变量访问速度更快。
  6. 避免使用with语句,因为它会改变执行环境作用域链。同样,try-catch语句中的catch子句也有同样的影响,因此也要小心使用。

对DOM的操作

文档对象模型(DOM)是一个独立于语言的,用于操作XML和HTML文档的程序接口(API)。在浏览器中,主要用来与HTML文档打交道,我们可以使用DOM API来访问文档中的数据。浏览器中通常会把DOM和JS独立实现。这对性能意味着什么?简单理解,两个相互独立的功能只要通过接口彼此连接,就会产生消耗。有个贴切的比喻,把DOM和JS(ECMAScript)各自想象为一个岛屿,它们之间用收费桥梁连接。JS每次访问DOM,都要途径这座桥,并交纳“过桥费”。访问DOM的次数越多,费用也就越高。即访问DOM的次数越多,代码的运行速度越慢。因此,通用的经验法则是:减少访问DOM的次数,把运算尽量留在JS这一端处理。一般来说,对于任何类型的DOM访问,需要多次访问同一个DOM属性或方法时,最好使用一个局部变量缓存此成员。当遍历一个集合时,第一优化原则是把集合存储在局部变量中,并把length缓存在循环外部,然后,使用局部变量替代这些需要多次读取的元素。

// 减少对DOM的操作案例
funtcion collectionNodesLoal(){
  var coll = document.getElementsByTagName('div'),
    len = coll.length,
    name = '',
    el = null;

    for (var count = 0; count < len; count++){
      el = coll[count];
      name = el.tagName;
    }

    return name;
}

重排和重绘

为了更好的知道重排和重绘是如何影响性能的,我们先了解一下DOM树和渲染树的区别

DOM树:表示页面结构
渲染树:表示DOM节点如何显示
需要注意:DOM树中的每一个需要显示的节点在渲染树中至少存在一个对应的节点(隐藏的DOM元素在渲染树中没有对应的节点)。渲染树中的节点被称为“盒”,也就是CSS中的盒模型,一个盒子具有padding、margin、border、content、position。一旦DOM和渲染树构建完成,浏览器就开始显示(绘制)页面元素

当DOM的变化影响了元素的几何属性(宽和高),比如改变边框宽度或给段落增加文字导致行数增加等等,浏览器需要重新计算元素的几何属性,同样的,其他元素的几何属性和位置也会因此受到影响。浏览器会使渲染树中受到影响的部分失效,并重新构造渲染树,这个过程称为重排。完成重排后,浏览器会重新绘制受影响的部分到屏幕中,该过程称为重绘。并不是所有的DOM改变都会影响几何属性。例如,改变一个元素的背景颜色并不会影响它的宽和高。在这种情况下,只会发生一次重绘(不需要重排),因为元素的布局并没有改变。重排和重绘操作都是代价 昂贵的操作,它们会导致web应用程序的UI反应迟钝。所以应当尽可能减少这类过程的发生

下述情况会发生重排:
  1. 添加或删除可见的DOM元素
  2. 元素位置改变
  3. 元素尺寸改变(包括:外边距、内边距、边框厚度、宽度、高度等属性改变)
  4. 内容改变(例如:文本改变、图片被另一个不同尺寸的图片替代)
  5. 页面渲染器初始化
  6. 浏览器窗口尺寸改变

需要注意:浏览器会通过队列化修改和批量执行的方式最小化重排次数。但是,当你查询布局信息时,比如获取偏移量、滚动位置等等时,浏览器为了返回最新值,会刷新队列并应用所有变更。最好的做法是尽量减少布局信息的获取次数,获取后把它赋值给局部变量,然后再操作局部变量。

重绘和重排可能代价非常昂贵,因此一个好的提高程序响应速度的策略就是减少此类操作的发生。为了减少发生次数,应该合并多次对DOM样式的修改,然后一次处理掉。

// 合并所有的改变然后一次处理,这样只会修改DOM一次,会高效很多

// 批量修改并覆盖原有的样式
var el = document.getElementById('myDiv');
el.style.cssText = 'padding: 5px; margin: 5px;';

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

推荐阅读更多精彩内容

  • 最近在阅读这本Nicholas C.Zakas(javascript高级程序设计作者)写的最佳实践、性能优化类的书...
    undefinedR阅读 2,140评论 0 30
  • 《高性能Javascript》阅读摘要 加载和执行 脚本位置 放在 中的javascript文件会阻塞页面渲染:一...
    环零弦阅读 248评论 0 2
  • AJax 优化 缓存 Ajax 请求尽量使用GET, 仅取决于cookie数量 Cookie 优化 减少Cooki...
    KeKeMars阅读 9,256评论 5 88
  • 问答题47 /72 常见浏览器兼容性问题与解决方案? 参考答案 (1)浏览器兼容问题一:不同浏览器的标签默认的外补...
    _Yfling阅读 13,630评论 1 92
  • 这个关键词源于昨天萌姐在一直播分享的中心内容。的确,我们中国人是一个注重礼貌礼节的民族。特别是在中国古代,什么人送...
    营养私教西西阅读 234评论 0 0