目录结构
1.加载和执行
2.数据存取
3.DOM编程
4.算法和流程控制
5.字符串和正则表达式
6.快速响应的用户界面
7.Ajax
8.编程实践
9.构建并部署高性能javascript应用
学习总结:
1.加载和执行
javascript动态添加 :
1、执行script,阻塞其他资源下载,需等待js执行完毕,script放在body最后
2、延迟脚本:
<script>扩展属性:defer 指明本元素所含的脚本不会修改DOM
IE4+/firefox3.5+ 支持
此种<script>可放在任何页面任何位置,解析到script下载但不执行直到DOM加载完成 onload被触发前
3、动态添加<script>: 最通用无阻塞加载解决方案
文件在该元素被添加到页面时开始下载
重点:无论何时启动下载,文件的下载和执行过程不会阻塞页面其他进程,放在head好于body
4、XMLHttpRequest脚本注入:另一种无阻塞加载解决方案
http请求成功后,从后台请求到js内容,再动态添加js
优点:下载后不会立即执行;一套代码兼容所有主流浏览器
局限:js文件必须与所请求页面同域,js不能从CDN下载,大型Web应用通常不会采用XHR脚本注入技术
2.数据存取
数据存取方式(4):字面量、变量 (访问最快)
数组项、对象成员(相对较慢)
变量里最快的是:非跨域的的局部变量
变量里最慢的是:全部变量
1、闭包 跨作用域标识符(变量等)造成性能损失
解决:常用的跨越作域变量存储为局部变量 function aa(){ var a=0; return function(){ a=10; }}
2、对象成员嵌套越深,读取速度越慢
读取速度:location.href > window.location.href > window.location.href.toString()
3、不要在函数里多次查找同一对象成员,除非它的值变了
多次获取同一对象属性时,尽量改为1次请求,局部变量保存此值,局部变量的请求快于对象属性,特别是嵌套属性
eg:var a = obj.attr;
3.DOM编程
1、减少访问DOM的次数,把运算尽量留在ECMAScript这边
for(){ele.innerhtml += 'a'} ==> for(){counter += 'a'}; ele.innerhtml = counter;
2、更新页面方法:3种
innerHtml -- 最快
克隆:element.cloneNode()
标准的DOM方法:document.creatElement() -- 最慢
3、在相同的内容和数量下,遍历数组 > 遍历HTML集合
toArray() : 通用的集合转数组方法
4、读取HTML集合属性length会引发集合进行更新,有性能问题
优化:属性length值存在一个局部变量中:length = html.length
5、浏览器下载完所有的组件(HTML标记、javascript、css、图片),解析生成2个内部数据结构
DOM树:表示页面结构
渲染树:表示DOM节点如何显示
6、减少重排、重绘:合并多次对DOM和样式的修改,一次处理掉
重排:页面布局(元素位置、渲染器初始化、浏览器窗口)和几何属性(宽、高、边距、内容)改变时发生
重绘:
4.算法和流程控制 递归优化:
1、循环性能 for、for in(最慢)、while、do while
循环类型的选择应该基于需求而不是类型
循环类型参考因素:每次迭代处理的事物、迭代次数
优化:①较少对象属性查询次数,局部变量使用 eg: len提前声明 for(var i=0,len=obj.length; i<len;i++){}
②倒叙排列 for(var l = obj.length; i--; ){} 与0的简单比较
③减少迭代次数
④基于循环的迭代比基于函数的迭代快8倍
⑤大量if-else、switch判断改为使用数组、对象直接量
var arr = [1,2,3]; var obj = {"arg":"123"};
2、判断性能
条件数量少 if-else : 最可能条件在前、嵌套、
条件数量多 switch
非常大量 查询表: 数组取值形式 eg: arr=[1,2,3];return arr[i];
3、递归:
递归的实现方式:调用自身(直接递归模式)、2个函数相互调用(隐伏模式)
调用栈溢出问题: 存在调用栈溢出问题的脚本不应该发布
调用栈溢出最常见原因:不正确终止条件、算法中包含太多层递归
调用栈溢出优化: 迭代(常用:合并排序算法)、Memeozition(缓存前一个值)、合并排序算法+Memeozition
5.字符串和正则表达式
6.快速响应的用户界面
1、浏览器UI线程
2、浏览器限制:调用栈大小限制、长时间运行脚本限制(记录脚本执行语句数量、记录脚本执行总时长)
3、定时器 (延时最少25ms)
定时器在函数调用时开始计时
定时器会重置浏览器限制,包括长时间脚本运行时间、调用栈大小重置为0
定时器是否取代循环决定因素:处理过程不要求同步、数据不要求按顺序处理
缺点:处理数组总时长增加;
优势:这一特性使得定时器成为解决长时间运行js、跨浏览器的解决方案 可忽略缺点
4、Web WorkerS :独立线程,不占用浏览器UI线程
var worker = new Worker("xx.js");
代码执行,将为这个xx.js创建一个新的线程、新的Worker运行环境;
该文件会异步下载,知道下载完成并执行才启动此Worker
发送接收:postMessage()、onmessage()
引入文件:importScripts("file1.js","file2.js"...); -- 阻塞式:所有文件加载完 运行
适用:处理纯数据、与浏览器UI无关的长时间运行脚本(>100ms)、编码解码大字符串、复杂数学运算、大数组排序
1、请求数据方法
XHR、动态脚本注入、multipart XHR -- 常用
Comet、iframes -- 不常用 极端情况
2、缓存
服务端:设置HTTP请求头以确保相应会被浏览器缓存 -- 简单,好维护 GET+Expires(缓存时间)
客户端:本地存储,避免再次请求 -- 最大的控制权
8.编程实践
9.构建并部署高性能javascript应用
1、自动化构建工具
2、合并多个javascript文件,压缩代码
代码压缩式写法:局部引用存储在对象/值中、闭包封装代码、常量代替重复值、避免eval/function、
with关键字、JScript有条件注释等
3、内容分发网络CDN: 在互联网上上按照地理位置分布计算机网络
8.编程实践
9.构建并部署高性能javascript应用
1、自动化构建工具
2、合并多个javascript文件,压缩代码
代码压缩式写法:局部引用存储在对象/值中、闭包封装代码、常量代替重复值、避免eval/function、
with关键字、JScript有条件注释等
3、内容分发网络CDN: 在互联网上上按照地理位置分布计算机网络