3

总结了一下《高性能javascript》书中比较核心的点,并补充了一些点。

第一章 DOM标签

  • 将所有 标签放置在页面的底部,紧靠 body 关闭标签的上方。此法可以保证页面在脚本 运行之前完成解析。

  • 将脚本成组打包。页面的 标签越少,页面的加载速度就越快,响应也更加迅速。不论外部脚本 文件还是内联代码都是如此。

  • LazyLoad 还可以下载多个 JavaScript 文件,并保证它们在所有浏览器上都能够按照正确的顺序执行。

  • 了解性能监控的API
    包括window.performance以及W3C Resourcing Timing

第二章 Data Access 数据访问

  • 作用域也关系到性能,但是要理 解速度与作用域的关系。

  • 全局变量总是 处于运行期上下文作用域链的最后一个位置,所以总是最远才能触及的,最慢。

  • 用局部变量存储本地范围之外的变量值,如果它们在函数中的使用多于一次。

 (function(d,$) {
        d.getElementById('test');
        ...
       $('.test').hide();
        ....
    }(document, jQuery))

作用域:

clipboard.png

深入原形链越深,搜索的速度就会越慢。
属性嵌套越深,访问速度越慢。
将它的值存入一个局部变量,消除一次搜索过程。

  • 函数的节流与防反跳

参阅underscore库的throttle函数(节流)与debounce函数(防反跳)。其中,throttle的含义是:每XX秒内只执行一次;debounce的含义是:当连续触发函数调用时,在最后一次触发的XX秒以后才开始一次调用。
如何实现这一机制请看浅谈 Underscore.js 中 _.throttle 和 _.debounce 的差异

第三章 DOM Scripting DOM 编程

  • 减少DOM 操作问题的量化

  • 将数组的 length 属性缓存到一个变量中

  • 浏览器需要重新计算元素的几何属性,而且其他元素的几何属性和位置也会因此改变 受到影响。 元素位置改变,尺寸, 内容, 浏览器窗口改变尺寸

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

  • 将所有改变合并在一起执行,只修改 DOM 一次。可通过使用 cssText 属性实现。

  • 从文档流中摘除该元素; 隐藏元素,进行修改,然后再显示它。 对其应用多重改变; 将元素带回文档中;

Example:
1.页面顶部可以“折叠/展开”的元素称作“动画元素”,用绝对坐标对它进行定位,当它的尺寸改变时,就 不会推移页面中其他元素的位置,而只是覆盖其他元素。
2、展开动作只在“动画元素”上进行。这时其他元素的坐标并没有改变,换句话说,其他元素并没有因为“动 画元素”的扩大而随之下移,而是任由动画元素覆盖。
3、“动画元素”的动画结束时,将其他元素的位置下移到动画元素下方,界面“跳”了一下。

  • 一个简单而优雅的处理 DOM 事件的技术是事件托管。它基于这样一个事实:事件逐层冒泡总能被父元
    素捕获。采用事件托管技术之后,你只需要在一个包装元素上挂接一个句柄,用于处理子元素发生的所有 事件。

第四章 Algorithms and Flow Control 算法和流 程控制

  • 只有一种循环比其他 循环明显要慢:for-in 循环 最慢。 要搜索实例或原形。

  • 减少每次迭代中操作的总数可以大幅度提高循环整体性能。 地将此值存入一 个局部变量中。 倒序循环。

使用递减循环

for (var i=items.length; i--; ){ 
    process(items[i]);
 }

var values = [0,1,2,3,4];
var len = values.length;
for (var i = 0; i--) {
     循环...
}

超过1000次的循环,使用Duff's Device

  var i = items.length % 8;
while(i) {
    process(items[i--]);
}

i = Math.floor(items.length / 8);

while(i) {
     process(items[i--]);
     process(items[i--]);
     process(items[i--]);
     process(items[i--]);
     process(items[i--]);
     process(items[i--]);
     process(items[i--]);
     process(items[i--]);
}

Conditionals 条件表达式

  • 如果条件较少时,if-else 容易阅读,而条件较多时 switch 更容易阅读。

  • 当你使用了太多的递归,超过最大调用栈尺寸时,浏览器会出错并弹出error信息。

  • 任何可以用递归实现的算法都可以用迭代实现。for循环代替递归( 运行的代码总量越大,使用这些策略所带来的性能提升就越明显。)

第五章 Strings and Regular Expressions 字符串 和正则表达式

str += "two";
str = str + "one" + "two";
newStr = strs.join("");
  • 尽量避免一个正则表达式做太多的工作

第六章 Responsive Interfaces 响应接口

  • 如果一个函数运行时间太长,那么查看它是否可以分解成一 系列能够短时间完成的较小的函数。

  • 可通过原生的 Date 对象跟踪代码的运行时间。

  • 当多个重复的定时器被同时创建会产生性能问题。

  • 网页工人线程

第七章 Ajax 异步 JavaScript 和 XML

  • 总的来说越轻量级的格式越好,最好是 JSON jsonp相对慢一点

  • 设置http头设置缓存 expires etag if-none-match if-modified-since

第八章 Programming Practices 编程实践

  1. Lazy Loading 延迟加载 按需加载(事件监听 函数 js文件 css文件 )

  2. JavaScript 引擎提供的原生方法

  3. 原生的 querySelector()和 querySelectorAll()方法查询dom

  4. 合并 JavaScript 文件

  5. 预处理 JavaScript 文件

  6. JavaScript 压缩

  7. JavaScript 紧凑

  8. 开发过程中的编译(预处理)

  9. 缓存 的应用 JavaScript 文件

  10. cdn

  11. 性能分析工具

  12. 只直出首屏页面可视内容,其他在客户端上延迟处理
    13.DNS prefeching

目前三种渲染页面的方式:
1.ajax拉取数据
2.后台直出数据和模版,js模版引擎去渲染(降低白屏)
3.后台直出拼好的页面 (降低白屏)

HTTP2.0性能增强的核心:二进制分帧

  • HTTP2.0 首部压缩

clipboard.png

HTTP 2.0 在客户端和服务器端使用“首部表”来跟踪和存储之前发送的键-值对,所有的HTTP2.0的请求都在一个TCP链接上.HTTP2.0所有通信都是在一个TCP连接上完成。HTTP 2.0 把 HTTP 协议通信的基本单位缩小为一个一个的帧,这些帧对应 着逻辑流中的消息。并行地在同一个 TCP 连接上双向交换消息。就好比,我请求一个页面http://www.qq.com。页面上所有的资源请求都是客户端与服务器上的一条TCP上请求和响应的!

  • HTTP2.0的请求优先级

  • HTTP2.0的服务器推送
    除了对最初请求的响应外,服务器还可以额外向客户端推送资源,而无需客户端明确地请求。

有了HTTP2.0的服务器推送,HTTP1.x时代的内嵌资源的优化手段也变得没有意义了。


wtgzczz
105 声望13 粉丝