----------------------------------------------------------- 第一章 加载和执行 -------------------------------------
1.脚本位置
    浏览器在遇到<script>标签时会等待脚本下载完并执行完才会继续渲染页面
        因为js代码有可能会改变dom结构,所以需要等待js的执行完成
        遇到<script>标签 -> 下载脚本 -> 执行脚本 -> 继续渲染
        旧浏览器:逐个下载,逐个执行
        新浏览器:并发下载,顺序逐个执行
    so: 脚本尽量放在靠近</body>的底部
        尽可能合并脚本(下载一个比下载多个快)
2.延迟的脚本
    defer:立刻下载,等到onload事件被触发前才执行(仅IE4.0+和Firefox3.5+支持)
    动态创建<script>节点:添加到页面时开始下载,下载完成立刻执行
        * 下载完成的事件:readystatechange(IE)、onload(其他浏览器)
    XHR脚本注入:XMLHttpRequest来获取js文件内容,再动态创建<script>节点
        * 必须处于相同域,不适用大型Web应用
3.推荐的方式
    先添加动态加载所需的代码,然后加载其他代码:
        <script type="text/javascript" src = "loader.js"></script>
        <script type="text/javascript">
            loadScript("the-rest.js"),function(){
                Application.init();
            }
        </script>
        放置</body>闭合标签前,保证DOM结构已经创建完毕,无需其他的时间,例如window.onload来检测页面是否准备好
4.类库
    LazyLoad.js:
        <script type="text/javascript" src = "lazyload-min.js"></script>
        <script type="text/javascript">
            LazyLoad.js(["first.js","second.js"]),function(){
                Application.init();
            }
        </script>
    lab.js:
        <script type="text/javascript" src = "lab.js"></script>
        <script type="text/javascript">
            $LAB.script("first.js").wait()    // 如果需要按序执行则需要加上wait()
                .script("second.js")
                .wait(function(){
                        Application.init();
                });
        </script>
   
--------------------------------第二章 数据访问---------------------------------------
1.作用域链和标识符解析
    内部属性[[Scope]] --- 作用域链  --- 0 --- 活动对象([[Scope]]属性中所包含的对象,即函数范围内的变量)
                                    --- 1 --- 全局对象(this, window, document 等等全局变量)
2.so 尽量把链深处的变量存储到局部变量里,介以提升性能
    * 采用优化过的js引擎不存在这种问题,老版的IE、Firefox和Safari都有问题

3.改变作用域链:
        with(document){...}    //with把document推进了作用域链的第一层,但是导致访问局部变量路径变远了,所以不推荐
        try{}catch(ex){}    //catch里面把异常对象推入了作用域链的头部

4.访问对象也一样,首先在实例中查找,然后再去原型链中查找
    so 如果需要访问多次,那么缓存对象属性可以提升性能
   
--------------------------------第三章 DOM编程---------------------------------------
1.尽量少访问DOM,把运算留在ECMAScript这一端处理

2.innerHTML属性和类似document.createElement()、document.createTextNode()的原生DOM方法性能差不多

3.cloneNode()比createElement要稍快一点

4.HTML集合
    document.getElementsByName();
    document.getElementsByClassName();
    document.getElementsByTagName();
    HTML集合是动态的,类数组,提供一个length属性
    * 访问length属性时会重新执行一次查询的过程
    so,缓存length属性很有必要
   
5.只返回元素节点
    children                    childNodes
    childElementCount            childNodes.length
    firstElementChild            firstChild
    lastElementChild            lastChild
    nextElementSibling            nextSibling
    previousElementSibling        previousSibling
   
6.选择器API
    原生DOM方法:querySelectorAll();
   
7.重绘与重排
    构建DOM树与渲染树 --- 绘制页面元素
    重排:
        添加、删除DOM元素
        元素位置改变
        元素尺寸改变
        内容改变(例如文本改变、图片被另外一个不同尺寸的图片替代)
        页面渲染器初始化
        浏览器窗口尺寸改变
    浏览器通过队列化修改并批量执行来优化重排过程,但以下属性会强制刷新队列:
    offsetTop, offsetLeft, offsetWidth, offsetHeight
    scroll...
    client...
    getComputedStyle()(currentStyle in IE)
    以上属性需要返回最新的布局信息,所以浏览器需要执行队列中的"待处理变化"并触发重排以返回正确的值
    so 以上属性尽量少使用,并且使用这些属性的位置应该在修改布局信息的后面,中间的话会导致多次重排

8.最小化重绘和重排
    ·合并多次所有的改变一次处理
    ·批量修改DOM
        脱离文档流
        应用多重改变
        带回文档
    三种方式:隐藏元素 --- 修改 --- 重新显示
                使用文档片段(document fragment)
                拷贝 --- 修改拷贝 --- 替换原始(replaceChild(new, old))
   
9.缓存布局信息

10.让元素脱离动画流
    绝对定位页面上的动画元素,将其脱离文档流
    让元素动起来,只重绘了该元素,会临时覆盖部分页面
    动画结束时恢复定位,只下移一次文档的其他元素

11.元素很多时应避免使用:hover这个CSS伪选择器

12.事件委托
    只绑定最外围的元素点击事件,判断来源是否是目标

--------------------------------第四章 算法和流程控制---------------------------------------
1.for-in循环的性能只有其他循环的1/7,
    so 尽量不要使用for-in来遍历对象的属性名

2.少量条件用if-else, 大量条件用switch-case

3.列表查找比循环查找要快
    so, 数据放置一个Array中, 通过位置来查找
   
4.尽量减少循环

5.存在重复的计算结果时,可以使用缓存

--------------------------------第五章 字符串和正则表达式---------------------------------------
1.字符串连接
    把基础字符串及放置左边可以提升性能
    * 因为除IE外,其他浏览器会尝试为左侧的字符串分配更多的内存,然后简单地将第二个字符串拷贝至它的末尾
   
2.Array.prototype.join();
    String.prototype.concat();    //concat比普通的+和+=以及join慢一点

3.正则表达式的编译很快,只需要注意别在循环中重复编译正则表达式就行
    while(/regex1/.test(str1))
   
4.只是检测位置不适用正则表达式
    例如检测是否以;结尾:
        /;$/ --- str.charAt(str.length-1)== ";";
    其他函数有slice、substr、substring、indexOf和lastIndexOf
   
5.去除首尾空格
    用两个子表达式综合效率要高一些,尤其是在处理长字符串时
    str.replace(/^\s+/,"").replace(/\s+$/,"");
    * 其他有一次性处理完的,但多少有各方面的性能问题
        比方说/^\s+|\s+$/,每个字符串都会去匹配这两个分支条件

--------------------------------第六章 快速响应的用户界面---------------------------------------
1.js的执行不应超过100毫秒(用户体验中能忍受的页面阻塞时间最大值)

2.定时器的推荐最小值为25毫秒
    * windows系统的最小识别为15毫秒,设置一个小于15毫秒的定时值,IE会锁定
    * 在小于10毫秒时,各浏览器各系统均会有不同的表现
   
3.可以通过定时器来依次执行多个任务
    * 将一个任务分割成多个任务,用定时器来执行
   
4.Web Workers
    Worker没有绑定UI线程,适用于纯数据处理,与网页代码通过事件接口进行通信
    网页代码:
        var worker = new Worker("code.js");
        worker.onmessage = faunction(event){
            // ...
        }
        worker.postMessage("Thyiad");
    worker代码(code.js):
        importScripts("file1.js", "file2.js");
        self.onmessage = function(event){
            self.postMessage("Hello, " + event.data + "!");
        }
       
--------------------------------第七章 AJAX---------------------------------------
1.常用的三种技术是:XHR、动态脚本注入和multipart XHR

2.XHR
    readyState的值
        3    正在与服务器交互
        4    整个响应已接收完毕,可进行操作
    * GET常用来请求数据,POST则用来发送数据
        一个GET请求只会发送一次数据包,而一个POST请求会发送两次数据包(一个装载头一个装载正文)
        应该在参数接近或超过2048个字符时,才应该使用POST获取数据,因为IE限制URL长度
    * 不能跨域请求数据

3.动态脚本注入
    动态创建一个script元素,设置src属性为不同域的URL
    * 返回的响应消息必须是可执行的JavaScript代码
   
4.Multipart XHR
    一次请求多个资源,从readyState值为3时开始设定一个定时器监听处理数据(需要自己定义数据格式并处理)
    * 这种方式资源不会被缓存
    * IE6、7不支持readyState为3的状态和data:URL

5.Beancons - 信标
    通过创建一个Image,设定src来回传数据
        var beacon = new Image();
        beacon.src=url+'?'+params.join('&');
        beancon.onload = function(){    // 通过监听image的load事件来处理简单返回时间
            if(this.width === 1){        // 如果不需要返回数据,那么响应中应该发送一个 204 No Content 状态码(即:不带消息正文)
            }                            // 以阻止客户端继续等待永远不会到来的消息正文
            else{}
        }
       
6.数据格式
    XML        不推荐,数据量大解析又慢
    JSON    推荐,数据轻便解析又快
    JSON-P    返回的文本作为js代码直接执行(用eval直接调用)
    HTML    不推荐,既缓慢又臃肿
    自定义    同JSON,适用的情景下速度还会比JSON更快点
   
7.缓存数据
    用GET请求数据、响应中发送 Expires 头信息:Expires: Mon, 28 Jul 2015 23:30:00 GMT    // 告诉浏览器缓存此响应到7月
    本地数据存储:使用对象的属性存储缓存(键存url,值存返回数据)
    * 本地存储最适用移动设备,大多移动设备的浏览器都很小或没有缓存
   
--------------------------------第八章 编程实践---------------------------------------
1.避免双重求值
    尽量不使用eval和Function构造函数,以避免双重求值带来的性能消耗
    同样的,应该给setTimeout()和setInterval()传入函数而不是字符串作为参数
   
2.使用直接量创建对象和数组 - 效率更高

3.不要重复工作
    当需要检测浏览器时,可使用延迟加载或条件预加载
    延迟加载:
        function addHandler(target, eventType, handler){
            if(target.addEventListener){
                addHandler = function(target, eventType, handler){
                    target.addEventListener(eventType, handler, false);
                }
            }
            else{
                addHandler = function(target, eventType, handler){
                    target.attachEvent("on"+eventType, handler);
                }
            }
           
            addHandler(target, eventType, handler);
        }
    条件预加载:
        var addHandler = document.body.addEventListener ?
            function(target, eventType, handler){
                    target.addEventListener(eventType, handler, false);
                } :
            function(target, eventType, handler){
                    target.attachEvent("on"+eventType, handler);
                };

4.使用速度快的部分
    位操作
        toString()方法把数字转换为二进制形式的字符串:
            var num = 25;
            alert(num.toString(2));        //"11001"
        是否为2的整数:
            var num = 25;
            if(num & 1){    // 奇数&1 => 1
            }
            else{}            // 偶数
        位掩码:
            var OPTION_A = 1, OPTION_B = 2, OPTION_C = 4, OPTION_D = 8, OPTION_E = 16;
            var options = OPTION_A | OPTION_C | OPTION_D;
            if(options & OPTION_A){    //选项A是否在列表中
                // ...
            }
           
5.原生方法
    尽量使用原生方法,比如数学计算(Math)和CSS选择器(querySelector()、querySelectorAll())
   
--------------------------------第九章 构建并部署高性能JavaScript应用---------------------------------------
1.Apache Ant

2.合并多个JavaScript文件

3.预处理JavaScript文件
    在js代码中添加宏定义(#define, #undef)和条件编译(#if, #ifdef, #ifndef)

4.JavaScript压缩
    JSMin                http://www.crockford.com/javascript/jsmin.html
    YUI Compressor        http://developer.yahoo.com/yui/compressor
    Closure Compiler    http://code.google.com/closure/compiler/
    Packer                http://dean.edwards.name/packer/

5.JavaScript的HTTP压缩
    Accept-Encoding HTTP头:值为gzip、compress、deflate和identity
        服务器会选择最合适的编码方法,通过Content-Encoding HTTP头来告知浏览器
       
6.缓存JavaScript文件
    * Expires HTTP 响应头
    * 客户端存储机制(js自己控制)
    * HTML5 离线应用缓存(manifest属性,mime type为text/cache-manifest)
   
7.处理缓存问题
    推荐使用时间戳后缀
   
8.CDN
   
--------------------------------第十章 工具---------------------------------------
1.原生分析
    new Date();    //通过Date相减
   
2.YUI Profiler
   
3.FireBug

4.Console API
    profile()、profileEnd()
        console.profile("regexTest");
        regexTest();
        console.profileEnd();
        * profileEnd()会阻塞后续执行,所以可以将profileEnd()调用封装在setTimeout中
       
5.Page Speed
    对如何重构进行分析建议,比如哪些脚本在load之前没有用到过,可以延迟加载
    * FireBug插件
   
6.Fiddler
    HTTP调试代理工具,整个网络过程的Timeline进行分析,哪块占用时间多需要优化
   
7.YSlow
    分析后的优化建议工具 
    * FireBug插件
       
8.dynatrace Ajax Edition
    同Fiddler的作用,可以监控整个过程的时间,更能深入到特定的事件

高性能javascript笔记的更多相关文章

  1. 高性能JavaScript笔记三(编程实践)

    避免双重求值 有四个标准函数可以允许你传入代码的字符串,然后它才你动态执行.它们分别是:eval.Function.setTimeout.setInterval 事实上当你在javascript代码中 ...

  2. 高性能JavaScript笔记二(算法和流程控制、快速响应用户界面、Ajax)

    循环 在javaScript中的四种循环中(for.for-in.while.do-while),只有for-in循环比其它几种明显要慢,另外三种速度区别不大 有一点需要注意的是,javascript ...

  3. 高性能JavaScript笔记一(加载和执行、数据访问、DOM编程)

    写在前面 好的书,可能你第一遍并不能领会里面的精魂,当再次细细品评的时候,发现领悟的又是一层新的含义 (这段时间,工作上也不会像从前一样做起来毫不费力,开始有了新的挑战,现在的老大让我既佩服又嫉妒,但 ...

  4. 关于高性能javascript 笔记

    最近买了本新书,准备自己吃 狗粮的同时也吃点精神食粮.笔记总结,从现在开始,看我啥时候能看完这本酥,就酱紫, begin:

  5. 高性能javascript学习笔记系列(1) -js的加载和执行

    这篇笔记的内容主要涉及js的脚本位置,如何加载js脚本和脚本文件执行的问题,按照自己的理解结合高性能JavaScript整理出来的 javascript是解释性代码,解释性代码需要经历转化成计算机指令 ...

  6. 高性能javascript学习笔记系列(6) -ajax

    参考 高性能javascript javascript高级程序设计 ajax基础  ajax技术的核心是XMLHttpRequest对象(XHR),通过XHR我们就可以实现无需刷新页面就能从服务器端读 ...

  7. 高性能javascript学习笔记系列(5) -快速响应的用户界面和编程实践

    参考高性能javascript 理解浏览器UI线程  用于执行javascript和更新用户界面的进程通常被称为浏览器UI线程  UI线程的工作机制可以理解为一个简单的队列系统,队列中的任务按顺序执行 ...

  8. 高性能javascript学习笔记系列(4) -算法和流程控制

    参考高性能javascript for in 循环  使用它可以遍历对象的属性名,但是每次的操作都会搜索实例或者原型的属性 导致使用for in 进行遍历会产生更多的开销 书中提到不要使用for in ...

  9. 高性能javascript学习笔记系列(3) -DOM编程

    参考 高性能javascript 文档对象模型(DOM)是独立于语言的,用于操作XML和HTML文档的程序接口API,在浏览器中主要通过DOM提供的API与HTML进行交互,浏览器通常会把DOM和ja ...

随机推荐

  1. maven 阿里云仓库配置

    <!-- 设定主仓库,按设定顺序进行查找. --> <repositories> <repository> <id>nexus-aliyun</i ...

  2. 详细介绍关联规则Apriori算法及实现

    看了很多博客,关于关联规则的介绍想做一个详细的汇总:  一.概念                                                                     ...

  3. linux_软件安装策略和升级策略

    运维3大原则:可靠.稳定.简单 尝试新的软件,一切都是未知的,也就是说不可靠,不可预测也就意味的不稳定,解决问题,通过百度和谷歌工具有可能找不到解决方法,只能通过官方文档来解决问题,大大增加了排错时间 ...

  4. python_如何让字典保持有序?

    案例: 某编程竞赛系统,对参赛选手编程解题进行计时,选手完成题目后,把该选手解题用时记录到字典中,以便赛后按选手名查询成绩(答题时间越短,成绩越优秀) {'lili':(1,43),'yuyu':(2 ...

  5. Asp.net Core 入门实战

    Asp.Net Core 是开源,跨平台,模块化,快速而简单的Web框架. Asp.net Core官网的一个合集,方便一次性Clone 目录 快速入门 安装 一个最小的应用 项目模板 路由 静态文件 ...

  6. GIT工程迁移方法总结

    Git工程迁移方法总结 Git最近准备迁移一下位置,这里采用命令行的方式,做如下操作. 1.git init  初始化git仓库,这个时候发现本地文件夹多了个.git的文件夹. 2.git remot ...

  7. JAVA中实现让程序等待一段时间的方法

    JAVA中想让代码等待一段时间再继续执行,可以通过让当前线程睡眠一段时间的方式. 方法一:通过线程的sleep方法. Thread.currentThread().sleep(1000); 在需要程序 ...

  8. word中正文分栏重新换页问题

    小论文常需要正文分栏,但是标题.摘要不分栏的编排格式. 1.在摘要后面加入分隔符来将内容分为摘要和正文两个部分.选择 插入→分隔符→分节符(连续). 2.然后进行分栏.选择 格式→分栏. 3.此时如果 ...

  9. linux下^M问题

    ^M的原因 Dos.Windows 格式的文件,用 0D 0A (CR+LF)作为换行符 而Unix 的则是以0A(LF) 作为换行符 所以dos 底下的文本文件到了unix的话,换行符就会多出来一个 ...

  10. openvpn的搭建

    openvpn搭建 原创不易,转载请注明 openvpn简介 1.1 openvpn原理 OpenVpn的技术核心是虚拟网卡,其次是SSL协议实现 虚拟网卡是使用网络底层编程技术实现的一个驱动软件,安 ...