高性能的JavaScript -- 读书笔记

高性能的JavaScriptjavascript

1、      加载和运行java

  1. 将脚本放在底部

脚本下载解析执行时,页面已经加载完成并显示在用户面前正则表达式

  1. 成组脚本

减小外部脚本文件数量,整合成一个文件算法

  1. 延迟脚本
  2. 动态脚本元素

非阻塞方式编程

  1. XMLHttpRequest

var xhr = new XMLHttpRequest();数组

xhr.open(“get”, “file.js", true);浏览器

xhr.onreadystatechange = function() {缓存

    if(xhr.readyState == 4) {闭包

        if ….app

          var script = document.createElement(“script”);

          script.type = “text/javascript”;

          script.text = xhr.responseText;

          document.body.appendChild(script);

    }

}

优势:可下载不当即执行的JavaScript代码

限制:JavaScript文件必须与页面放置在同一个域内

  1. 推荐的非阻塞模式

2、      数据访问

  1. 四种基本的数据访问方式:

直接量、变量、数组项、对象成员

  1. 管理做用域

每一个JavaScript函数中都有一个仅供JavaScript引擎使用的内部属性为[[Scope]]。该属性包含了函数被建立的做用域链中对象的集合。

 

运行期上下文的做用域链中,一个标识符位置越深,它的读写速度就越慢。因此,函数中局部变量的访问速度老是最快的,而全局变量一般是最慢的。

  1. 改变做用域链

with表达式:做用域链前段插入了一个新的对象,局部变量的访问速度变慢。最好不要用。

try-catch表达式:catch子句执行完毕,做用域链返回原来的状态。

  1. 闭包,做用域,和内存

当闭包被运行时,一个运行期上下文将被建立,它的做用域链与[[Scope]]中引用的两个相同的做用域同时被初始化,而后一个新的激活对象为闭包自身被建立。

脚本中最好当心地使用闭包。

  1. 对象成员

对象成员比直接量和局部变量访问速度慢,在某些浏览器上比访问数组项还要慢。

因此可能的话避免使用它们,只在必要状况下使用对象成员。

  1. 总结:

提升性能:将常用的对象成员,数组项,和域外变量存入局部变量中。而后,访问局部变量的速度会快于那些原始变量。

3、      DOM编程

DOM操做代价昂贵

三类问题:

l  访问和修改DOM元素

l  修改DOM元素的样式,形成重绘和从新排版

l  经过DOM事件处理用户响应

  1. DOM访问和修改

轻轻地触摸DOM,并尽可能保持在ECMAScript范围内。

不标准却被良好支持innerHTML和纯DOM方法如document.createElement()的性能差异不大。旧的浏览器上innerHTML快,新浏览器上DOM方法更快。

  1. 节点克隆

克隆节点更有效率,但提升不太多。

  1. HTML 集合对象

遍历数组比遍历集合快。

每次迭代过程访问集合length属性,性能低。应将length属性缓存到一个变量中,而后在循环判断条件中使用这个变量。

  1. 若是浏览器支持document.querySelectAll(),最好使用它
  2. 重绘和重排版

浏览器下载完全部页面HTML标记,JavaScript,CSS,图片后,它解析文件并建立两个内部数据

l  一棵DOM树:表示页面结构

l  一棵渲染树:表示DOM节点如何显示

 

当布局和几何改变时须要重排版:

l  添加或删除可见的DOM元素

l  元素位置改变

l  元素尺寸改变

l  内容改变

l  最初的页面渲染

l  浏览器窗口改变尺寸

 

  1. 最小化重绘和重排版

由于代价昂贵,因此好的策略是减小此类操做发生机会。将多个DOM和风格改变合并到一个批次中一次性执行。

l  隐藏元素,进行修改,而后再显示它。

display = none; 修改;display = block;

l  在已存DOM以外建立一个子树,而后拷贝到文档。

createDocumentFragment();append();

l  拷贝原始元素,修改副本,覆盖原始元素。

cloneNode();replaceChild();

第二种文档片断最优

 

  1. 缓冲布局信息
  2. 将元素提出动画流

使用如下步骤能够避免对大部分页面进行重排版

l  绝对坐标定位页面动画元素,使它位于页面布局流以外

尺寸改变时只会覆盖其余元素

l  启动元素动画

l  当动画结束时,从新定位,只一次下移文档其余元素位置

  1. 事件托管

事件逐层冒泡总被父元素捕获;

只需在一个包装元素上挂接一个句柄,用于处理子元素发生的全部事件;

 

DOM标准,每一个事件有三个阶段:

捕获,到达目标,冒泡

10. 总结

为减小DOM编程中的性能损失,注意如下几点:

l  最小化DOM访问,在JavaScript端作尽量多的事情

l  在反复访问的地方使用局部变量存放DOM引用

l  当心处理HTML集合,将length属性缓存到一个变量中

l  使用速度更快的API,如querySelectorAll()和firstElementChild

l  注意重绘和重排版;批量修改风格,离线操做DOM树,缓存并减小对布局信息的访问

l  动画中使用绝对坐标,使用拖放代理

l  使用时间托管技术最小化事件句柄数量

 

4、      算法和流程控制

代码总体结构是执行速度的决定因素之一

  1. 循环

for-in循环比其余普通循环明显要慢;

由于每次迭代操做要搜索实例或原形的属性。

减小迭代次数;

达夫设备:

var iterations = Math.floor(items.length/8);

startAt = items.length % 8;

i = 0;

do {

    switch(startAt) {

        case 0 : process(items[i++]);

        case 7 : process(items[i++]);

        case 6 : process(items[i++]);

        case 5 : process(items[i++]);

        case 4 : process(items[i++]);

        case 3 : process(items[i++]);

        case 2 : process(items[i++]);

        case 1 : process(items[i++]);

}

startAt = 0;

} while(-- iterations);

  1. 基于函数的迭代

forEach()

比基于循环的迭代要慢:每一个数组项要关联额外的函数调用;

关注执行时间的状况下它并非一个合适的方法;

  1. 条件表达式

大多数状况下,switch比if-else更快,但只有当条件体数量很大时才明显;

二者区别:条件体增长时,if-else性能负担增长程度比switch多;

优化if-else:

条件体应当老是按照从最大几率到最小几率的顺序排列,保证理论运行速度更你快;

嵌套使用;

 

  1. 查表法

最经常使用于一个键和一个值造成逻辑映射领域

 

  1. 递归

递归函数会遇到浏览器调用栈大小的限制

 

5、      字符串和正则表达式

  1. 优化字符串链接

“+”,

“+=”,

Array.join(),

String.concat(),

 

str = str + “one” + “two”;

避免了使用临时字符串

  1. 数组联结
  2. 正则表达式优化

工做原理:

第一步:编译

第二步:设置起始位置

第三步:匹配每一个正则表达式的字元

第四步:匹配成功或失败

6、      响应接口

  1. 浏览器UI线程

JavaScript和UI更新共享的进程被称为浏览器UI进程;

浏览器在JavaScript运行时间上采起了限制:

调用栈尺寸限制和长时间脚本限制;

  1. 用定时器让出时间片

setTimeout()和setInterval()

第二个参数指出是么时候应当将任务添加到UI队列之中,并非说那时代码被执行;

  1. 分解任务
  2. 限时运行代码
  3. Web Work

不绑定UI线程,不能访问许多浏览器资源。

7、Ajax异步JavaScript和XML

相关文章
相关标签/搜索