目录结构 正巧看到在送书,于是乎找了找自己博客上记录过的一些东西来及其无耻的蹭书了~~~ 小广告:更多内容可以看我的博客 以下内容均来自《高性能JavaScript》 JavaScript文件加载管理浏览器中的JavaScript代码是一个棘手的问题,因为代码执行会阻塞浏览器,比如界面绘制。每次遇到 将JS文件放在页面底部将所有 将JS文件打包将JS文件打包,页面的 使用非阻塞方式下载
数据访问四种访问方式在JavaScript中,数据存储位置可以对代码整体性能产生重要影响,有四种数据访问类型:直接量,变量,数组项,对象成员,这些访问方式性能不同 直接量和局部变量访问速度很快,而数组项和对象成员需要更长的时间 作用域链和闭包的访问速度在函数内部访问变量时,会顺着作用域链向上查找,直到找到为止,这也意味着作用域链越长,平均的查找时间也就越长。而像with和try-catch会增加作用域链的长度,所以也会降低性能。由此可以得知,访问全局变量很慢,因为他们在作用域链的最后一环 原型链访问访问对象的属性的时候,我们有时候会需要遍历原型链,这也意味着原型链越长,查找元素的平均效率就越低,变量所在的原型在原型链中越深,访问越慢 DOM当浏览器下载完所有的HTML、JavaScript、CSS、图片之后,它会解析文件并创建两个内部数据结构:一棵DOM树和一棵渲染树 每个需要被显示的DOM树节点在渲染树中至少有一个节点(隐藏的DOM节点自然在渲染树中没有节点),渲染树上的点被称为框或者盒,根据CSS模型定义,将页面元素看做一个具有填充、边距、边框和位置的盒。一旦DOM树和渲染树构造完毕,浏览器就可以绘制页面上的元素了。 当DOM改变影响到元素的几何属性(宽和高),浏览器就需要重新计算元素的几何属性。如果这个元素的改变影响到其他元素,浏览器会使渲染树上收到影响的部分失效,然后重构渲染树。这就是回流(也叫重排版)。重排版完成时,浏览器在一个重绘进程中重新绘制屏幕上受影响的部分 当然并不是所有DOM改变都会影响到几何属性,比如改变背景颜色之类的,这种情况下就只会触发重绘 回流和重绘都是负担很重的操作,会导致浏览器阻塞,所以需要尽可能避免 何时触发回流
查询并刷新渲染树的改变因为计算量与每次回流有关,大多数浏览器会通过一个渲染队列来进行优化。但是用JavaScript获取一些DOM属性时,会(不由自主地)强迫队列中的所有渲染事件前不完成。比如获取如下属性: 为了让这些属性返回正确的值,浏览器不得不运行渲染队列中所有的渲染事件,这样才能保证值的正确。所以尽量减少这些属性的访问 判断if-else多个if-else执行的时候,其会顺序检索每一个条件,直到所有条件检索完或检索到匹配的条件。所以我们可以通过树的形式组织if语句,如下面代码:
这段代码就会依次判断con是否等于1,2,3,4,5,6,7,8,9,如果是9的话,就会判断9次,我们可以将其改为:
这样我们通过三叉树的形式,就可以减少查找次数了,比如这里查找9次,分别判断 0~3,3~6,6~9,7,8,9,只需要6次 if-else除了通过这种树形组织编码以外,还有一个优化的地方。由于其顺序判断的逻辑,我们可以根据概率来,将概率比较大的判断放在前面,概率较小的放在后面,这样也可以减少平均查找长度 switch事实证明,大多数情况下switch比if-else更快,但是只有条件题数量很大的时候,才能明显更快。if-else在条件增加时,所带来的性能负担要高于switch,因此建议使用switch。不过switch只是用来判断几个不同的离散值,并没有if-else能判断离散值或值域那样的灵活性 打表法可以使用打表的形式来做,把所有的处理函数放在一个数组中,然后将条件作为键,这种方法比switch和if-else都要快,而且在新增条件时,不会带来额外的性能开销 递归很多算法都是递归实现,由于递归会多次触发函数调用,而函数调用也是需要开销的(比如创建运行期上下文、压运行期栈、创建AO、复制作用域链、销毁AO、弾栈等等),所以尽量将递归转变为循环。而运行期栈在很多浏览器中也有深度限制,当到达运行期栈的最大深度时,浏览器有各自的处理方式,但都是按照错误进行处理 字符串不同的拼接方法字符串拼接有很多不同的方法: 使用加号拼接使用
实际上会执行如下步骤: 而如果改成如下这样:
这样就可以避免创建临时字符串,可一定程度加快性能 或者使用如下方式:
但是如果使用下面这种方式:
则无法确定是否有优化。不同的浏览器分配内存方式不一样,IE以外的浏览器,会尝试扩展表达式左端字符串的内存,然后简单的将第二个字符串拷到它的尾部,这样就会创建一个临时字符串存放 浏览器优化很多浏览器会在编译时对连续相加的字符串进行拼接,以此来对运行时优化,比如:
会被优化成
IE7-中的字符串连接IE7-中使用 String.concat这种方法很慢,尽量不要使用 正则表达式优化正则表达式的工作原理正则表达式处理经过如下几个步骤: 正则表达式实现中,回溯是基本组成部分。它代价昂贵,且容易失控。回溯是正则表达式性能的唯一因素 正则表达式在匹配时,会在一个有多个分支的地方建立标记点,然后从左到右遍历所有的分支,如果分支符合,就会前进道下一个标记点,如果所有分支都不符合,就会回溯到上一个标记点,尝试上一标记点的其他分支。在尝试上一标记点的其它分支时,这一标记点如果需要,还会全部重新尝试 回溯失控当一个正则表达式占用浏览器上秒,或者更长时间,很有肯那个就是回溯失控了,原因很有可能是出现了 此类问题的解决办法是尽可能具体地指出分隔符之间的字符匹配形式,或者使用前瞻表达式 嵌套量词导致性能下降嵌套量词可能极大的加大分支的数量,比如一个正则表达式 一些建议
UI线程相关建议的一次JavaScript执行时间不超过100ms(最好在50ms)以内,可以通过setTimeout和setInterval来将任务进行分解,加入到UI线程中。其实这个思想和JavaScript引擎的垃圾回收器的迭代处理相似 AJAXAJAX获取数据时,可以使用POST或者GET方法 如果请求不改变服务器状态指示返回数据,应该使用GET。GET请求会被缓存,如果多次提取相同的数据会提高性能 而当URL和请求的参数长度超过2048个字符的时候才使用POST提取数据 多部分XHR(MXHR)多部分XHR允许使用一个HTTP请求获取多个资源,我们可以将资源打包成一个特定分隔符定界的大字符串,从服务器发送到客户端,JavaScript处理这些大字符串,然后根据它自身的类型和信息解析出每个资源 需要注意的是AJAX不会在浏览器中进行缓存,自然使用MXHR也不会缓存,在一些静态资源上使用这种方式其实并不太好。但是如果每次都确实需要去获取,分多个请求发送会更慢。 IMG灯标我们可以通过创建一个Image对象,将src设为一个脚本文件的URL,img元素我们并不需要插入到DOM中,这种形式称为IMG灯标 这种方式适用于GET请求,且服务器获得数据后不必返回数据给浏览器的情况 同时我们可以在Image的load事件中监听服务端是否成功接受了数据 数据格式
其他
|
|