高性能Javascript笔记

来源:互联网 发布:vb.net select case 编辑:程序博客网 时间:2024/05/16 15:05
developer.yahoo.com/performance雅虎特别性能小组
高性能网站建设
高性能网站建设进阶指南


一、加载和执行
减少Javascript文件大小并限制HTTP请求数
将脚本放在底部
<script>标签加载时会阻塞页面的渲染,所以<script>标签放在<body>标签的底部 


不要把内嵌脚本紧跟在<link>标签后
导致页面阻塞等待样式下载


减少外链脚本的数据
合并脚本,引入一个<script>标签,减少性能消耗,最小化时间延迟
(大脚本不适用,死锁浏览器一大段时间)


window对象的load事件触发后再下载脚本
动态加载JS 类库


二、数据访问
访问全局变量最慢,局部变量和直接量最快
将引用了多次的成员定义成局部变量
属性或方法在原型量的位置越深,访问他的速度越慢(.点操作符>1)
直接量
var myObject = {
name:‘NIcholas’,
count:50
}
优于典型的对象创建和赋值
var myObject = new Object();
myObject.name='NIcholas';
myObject.count=50;
对象和数组的创建直接量是最快的方式
对象属性和数组项的数量越多,使用直接量的好处就越明显


三、DOM编程
用脚本进行DOM操作的代价很昂贵,web应用中的性能瓶颈,应减少对DOM的访问和修改


访问和修改DOM元素
修改DOM元素的样式会导致重绘(repaint)和重排(reflow)


一般的经验做法
减少DOM访问的次数,把运算尽量留在ECMAScript(JavaScript)端处理  
innerHtml对比DOM方法,使用innerHtml属性修改页面区域好于doucment.createElement()
节点克隆,使用element.cloneNode()代替doucment.createElement().先创建需要重复的元素再重复拷贝
HTML集合,遍历一个数组的速度快于遍历一个HTML集合(将HTML声明成数据形式的局部变量,并把length声明在循环外部)


元素节点的使用
属性名(效率高) 被替换的属性名(低)
children childNodes
childElementCount childNodes.length
firstElementChild firstChild
lastElementChild lastChild
nextElementSibling nextSibling相邻元素
previousElementSibling previousSibling


选择器API
原生的CSS选择器API快于jQuery的CSS查询引擎10倍
document.querySelector(className)
document.querySelectorAll(className)
document.matches()
原生方法的效率是最快的


重绘(repaint)与重排(reflow)
浏览器下载完页面中的所有组件--HTML标记、JavaScript、CSS、image后会解析并生成2个内部数据结构
DOM树
  表示页面结构
渲染树
  表示DOM节点如何显示
隐藏的DOM元素在渲染树中没有对应的节点
页面元素为一个具有填充(padding),间距(margin),边框(border)和位置(position)的盒子
一旦DOM树和渲染树构建完成,浏览器就开始显示(绘制paint)页面元素


当DOM的变化影响了元素的几何属性(宽和高)--比如改变边框宽度或给段落增加文字,
导致行数增加--浏览器需要重新计算元素的几何属性,其他元素的几何属性和位置也会受到影响。
浏览器会使渲染树中受到影响的部分失效,重新构造渲染树。这个过程称为重排(reflow)。
完成重排后,浏览器会重新绘制受影响的部分到屏幕中,该过程称为重绘(repaint).


改变元素的颜色并不会影响元素的宽和高,这种情况下只会发生一次重绘(不需要重排),因为元素的布局并没有改变。


重绘和重排操作都是代价昂贵的操作,会导致WEB应用程序的UI反映迟钝。所以,应当尽可能减少这类过程的发生。


重排何时发生
  添加或删除可见的DOM元素
  元素位置改变
  元素尺寸改变(内外边距,边框厚度、宽度、高度等属性改变)
  内容改变(文本改变或图片被另一个不同尺寸的图片代替)
  页面渲染器初始化
  浏览器窗口尺寸改变


根据改变的范围和程度,渲染树中或大或小的对应的部分也需要重新计算。
有些改变会触发整个页面的重排:如,当滚动条出现时


偏移量(offsets) offsetTop,offsetLeft,offsetWidth,offsetHeight
滚动位置(scroll values) scrollTop,scrollLeft,scrollWidth,scrollHeight
clientTop,clientLeft,clientWidth,clientHeight
计算出的样式值(computedstyle values) getComputedStyle()(W3C) or currentStyle (in IE or Opera)
以上属性和方法会引起页面的重排,最好避免使用上面的属性
如果使用时,尽量减少对布局信息的获取次数,获取收把他赋值给局部变量,然后操作局部变量


最小化重绘和重排
合并多次对DOM和样式的修改,然后一次处理掉
改变样式,多次变一次


批量修改DOM,通过以下步骤来减少重绘和重排的次数
  使元素脱离文档流    
  对其应用多重改变
  把元素带回文档中
有3中方法可以使DOM脱离文档
  隐藏元素(display:none),应用改变(change element),重新显示(display:block)
  使用文档片断(document.createDocumentFragment())在当前DOM之外构建一个子树(change element in fragemnt),再把他拷贝回文档(add fragemnt to target element)
  将原始元素拷贝到一个脱离文档的节点中(cloneNode()),修改副本(change clone node),完成后在替换原始元素(replace clone node to old node)
第一和第三步会触发2次重排
第二步会触发一次重排,推荐使用(Fragment)


让元素脱离动画流
使用以下步骤可以避免页面中的大部分重排
  使用绝对位置定位页面上的动画元素,将其脱离文档流
  让元素动起来。但他扩大时,会临时覆盖部分页面,但这只是页面一个小区域的重绘过程,不会产生重排并重绘页面的大部分内容
  当动画结束时恢复定位,从而只会下移一次文档的其他元素


大量元素使用:hover,会降低性能,IE中


事件委托
使用事件代理,只需给外层元素绑定一个处理器,就可以处理在其子元素上触发的所有事件


四、算法和流程控制
倒序循环是变成语言中一种通用的性能优化方法
减少迭代次数(大于1000次,对大迭代进行分割,达夫设备模式)
基于循环的迭代比基于函数的迭代(jQuery.each() or JavaScript forEach())快8倍
if-else适用于判断两个离散值或几个不同的值域。当判断多于2个离散值时switch效率高。
查找表,JavaScript中可以用数组和普通对象来构造查找表,存在键值关系时查找表优于if-else和switch.


五、字符串和正则表达式
concat()慢于+和+=
Array.prototype.join()合并大量字符串


九、构建部署高性能应用
合并
压缩
预处理
Gzip压缩(适用于文本,apache mod_gzip模块)
内容分发网路(CDN 减少网络延时)
缓存静态内容(image,javascript,css),使用时间戳对静态内容进行更新
HTML5离线应用缓存(依赖一个清单文件manifestfile,列出所有待缓存的资源。通过向<html>标签添加一个manifest属性)
<!DOCTYPE HTML>
<HTML manifest=‘demo.manifest’>
参照 e3c.org/tr/html5/offline.html





























































































0 0
原创粉丝点击