总结了一下《高性能javascript》书中比较核心的点,并补充了一些点。
第一章 DOM标签
将所有 标签放置在页面的底部,紧靠 body 关闭标签的上方。此法可以保证页面在脚本 运行之前完成解析。
将脚本成组打包。页面的 标签越少,页面的加载速度就越快,响应也更加迅速。不论外部脚本 文件还是内联代码都是如此。
LazyLoad 还可以下载多个 JavaScript 文件,并保证它们在所有浏览器上都能够按照正确的顺序执行。
了解性能监控的API
包括window.performance
以及W3C Resourcing Timing
第二章 Data Access 数据访问
作用域也关系到性能,但是要理 解速度与作用域的关系。
全局变量总是 处于运行期上下文作用域链的最后一个位置,所以总是最远才能触及的,最慢。
用局部变量存储本地范围之外的变量值,如果它们在函数中的使用多于一次。
(function(d,$) {
d.getElementById('test');
...
$('.test').hide();
....
}(document, jQuery))
作用域:
深入原形链越深,搜索的速度就会越慢。
属性嵌套越深,访问速度越慢。
将它的值存入一个局部变量,消除一次搜索过程。
函数的节流与防反跳
参阅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 编程实践
Lazy Loading 延迟加载 按需加载(事件监听 函数 js文件 css文件 )
JavaScript 引擎提供的原生方法
原生的 querySelector()和 querySelectorAll()方法查询dom
合并 JavaScript 文件
预处理 JavaScript 文件
JavaScript 压缩
JavaScript 紧凑
开发过程中的编译(预处理)
缓存 的应用 JavaScript 文件
cdn
性能分析工具
只直出首屏页面可视内容,其他在客户端上延迟处理
13.DNS prefeching
目前三种渲染页面的方式:
1.ajax拉取数据
2.后台直出数据和模版,js模版引擎去渲染(降低白屏)
3.后台直出拼好的页面 (降低白屏)
HTTP2.0性能增强的核心:二进制分帧
HTTP2.0 首部压缩
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时代的内嵌资源的优化手段也变得没有意义了。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。