高性能的javascript 笔记
博客专区 > -波仔- 的博客 > 博客详情
高性能的javascript 笔记
-波仔- 发表于7个月前
高性能的javascript 笔记
  • 发表于 7个月前
  • 阅读 5
  • 收藏 1
  • 点赞 0
  • 评论 0

腾讯云 新注册用户 域名抢购1元起>>>   

摘要: 待续

第一章:加载和执行

    多数浏览器使用单一进程来处理用户界面(UI)刷新和javascript脚本执行,所以同一时刻只能做一件事。script标签每次出现都霸道的让页面等待脚本的解析和执行。同样的情况也发生在使用src属性加载javascript的过程中,浏览器必须花时间下载外链文件中的代码,然后解析并执行。在这个过程中,页面玄滩和用户交互式完全被 阻塞的。 
    脚本位置
        现在浏览器,支持多个javascript文件并行下载,但是js下载过程会阻塞其他资源的下载,比如图片。
        结论:推荐所有的js文件加载都放到<body>标签的底部。
    组织脚本:
        减少页面中外链脚本文件的数量会改善性能-----策略:将多个js文件合并成一个js文件。
    无阻塞的脚本
        在window对象的load时间触发后再下载脚本。
    动态脚本元素
        script标签被添加到页面时开始下载js文件,无论在何时启动下载,文件的下载执行过程并不会阻塞页面其他进程。
        
    XMLHttpRequest脚本注入
    
        var xhr= new XMLHttpRequest();
        xhr.open("get","fil1.js",true);
        xhr.onreadystatechange = function(){
            if(xhr.readystate == 4){
                if(xhr.status >=200 && xhr.status <= 300 || xhr.status ==304){
                    var script = document.createElement("script");
                    script.type="text/javascript";
                    script.text = xhr.responseText;
                    document.body.appendChild(script);
                }
            }
        }
        局限性:javascript文件必须与所请求的页面处于相同的域,这意味着js文件不嗯给你从CDN下载。
        
    推荐的无阻塞模式
        两步:先动态加载所需的代码,然后加载初始化页面所需的剩下的代码。
            例如:
                <script type="text/javascript" src="loader.js"></script>
                <script type="text/javascript">
                    loadScript("the-rest.js",function(){
                        Application.init();
                    })
                </script>
    
    其他的方式:YUI3的方式,LazyLoad类库,LABjs
    
    小结:
        1、<body>标签闭合之前,将所有<script>标签放在页面底部。这能确保在脚本执行前页面已经完成了渲染。
        2、合并脚本。页面中的<script>标签越少,加载越快,响应月迅速。
        3、有多重无阻塞下载javascript的方法:
            使用<script>标签的defer属性;
            使用动态创建的script元素来下载并执行代码;
            使用XHR对象下载javascript代码并注入到页面中。      
  

第二章:数据存储

javascript中有四种基本的数据存取位置
        字面量:字符串、数字、布尔值、对象、数组、函数、正则表达式、null、undefined
        本地变量:使用var定义的数据存储单元
        数组元素:javascript数组对象内部
        对象成员:对象内部
        
        总的来说,字面量和局部变量的访问速度快于数据和对象成员的访问速度。   
        管理作用域: 在执行环境的作用域链中,一个标识符所在的位置越深,他的读写速度也就越慢。因此,函数中读写局部变量总是最快的,儿读写全局变量通常是最慢的。请记住全局变量(window等)总是存在于执行环境作用域链的最末端,因此也是最远的。
        解决方法:应用一个全局变量之前,将全局变量赋值给一个局部变量。
            例如:function(){
                    var body = document.body;
                }
        
        改变作用域链:
            一般,一个执行环境的作用域链是不会改变的。但是有两个语句可以在执行时临时改变作用域链。
            第一个:with语句
            第二个:try-catch中的catch
            
        闭包、作用域和内存
            脚本中的闭包与非闭包函数相比,需要更多的内存开销(尤其在IE中)。
            解决方法:将常用的跨作用域变量存储在局部变量中,然后直接访问局部变量。
    
    对象成员:
        可以用hasOwnProperty()方法来判断对象是否包含特定的实例成员(传递给防范的参数名即成员的名称),
        要确定对象是否包含特定的属性,可以用in操作符。
        
        搜索实例成员比字面量或局部变量中读取数据代价更高,再加上遍历原型链带来的开销,这让性能问题更严重。


    小结:

        在javascript中,数据存储的位置对代码整体性能产生重大的影响。数据存储共有4种方法:字面量、变量、数组想、对象成员。
            1、访问字面量和局部变量的速度最快,相反,访问数据元素和对象成员相对较慢。
            2、由于局部变量存在于作用域链的起始位置,因此访问局部变量比访问跨作用域变量更快。变量在作用域链中的
                位置越深,访问所需时间越长,由于全局变量总处在作用域链的最末端,因此访问速度也是最慢的。
            3、避免使用with语句,因为它会改变执行环境作用域链。同样,try-catch语句中的catch字句也有同样的影响。
            4、嵌套的对象成员会明显影响性能,尽量少用。
            5、属性或方法在原型链中的位置越深,访问他的速度越慢。
            6、通常来说,你可以通过把常用的对象成员、数组元素、跨域变量保存在局部变量中来改善javascript性能。 

第三章:DOM编程

 脚本进行DOM操作的代价很昂贵它是web应用中最常见的性能瓶颈。
    浏览器中的DOM:文档对象模型,是一个独立于语言的,用于操作XML和HTML文档的程序接口(API)。
    简单理解,两个相互独立的功能只要通过接口彼此连接,就会产生消耗。
    DOM访问与修改:减少访问DOM的次数,把运算尽量留在ECMAScript这一端处理。
    在相同的内容和数量下,遍历一个数组的速度明显快与遍历一个HTML集合。
    一般来说,对于任何类型的DOM访问,需要多次访问同一个DOM属性或方法需要多次访问时,最好使用一个局部变量缓存此成员。
    重排和重绘都是代价昂贵的操作,他们会导致web应用程序的UI反应迟钝。所以,应当尽量减少这类过程的发生。 
    重排何时发生:
        添加或者删除可见的DOM元素
        元素位置改变
        元素尺寸发生改变(包括:外边距、内边距、边框厚度、宽度、高度等属性改变)
        内容改变,例如:文本改变或图片被替换
        页面渲染器初始化
        浏览器窗口尺寸改变。

            
    批量修改DOM:
        当需要对DOM元素进行一系列操作时,可以通过以下步骤减少重绘和重排的次数:
            1、使元素脱离文档流;
            2、对其应用多重改变;
            3、把元素带回文档中。   
    缓存布局信息:尽量减少布局信息的获取次数,获取后把它赋值给局部变量,然后在操作局部变量。
    使用以下步骤可以避免页面中的不部分重排:
        1、使用绝对定位,将元素脱离文档流;
        2、让元素动起来,当它扩大时,会临时覆盖部分页面
        3、当动画结束时,恢复定位,从而只会下移一次文档的其他元素。   

 小结:

       访问和操作DOM是现代web应用的重要部分。但每次穿越连接ECMAScript和DOM两个岛屿之间的桥梁,都会被收取“过桥费”
        为了减少DOM编程带来的性能损失,请参照以下几点:
            1、最小化DOM访问次数,尽可能在javascript端处理;
            2、如果需要多次访问某个DOM节点,请使用局部变量存储它的引用;
            3、小心处理HTML集合,因为它实时连接着底层文档。把集合的长度缓存到一个变量中,并在迭代中使用它。
            4、如果可能的话,使用速度更快的API,比如querySelectorAll()和firstElementChild
            5、要留意重绘和重排;批量修改样式时,“离线”操作DOM树,使用缓存,并减少访问布局信息的次数;
            6、动画中使用绝对定位,使用拖放代理;
            7、使用事件委托来减少事件处理器的数量。


第四章:算法和流程控制

小结:    

        javascript和其它编程语言一样,代码的写法和算法会影响运行时间。
        
        1、for、while和do-while循环性能特性相当,并没有一种循环类型快于或者慢于其它类型。
        2、避免使用for-in循环,除非需要遍历一个属性数量未知的对象。
        3、改善循环性能最佳的方式是减少每次迭代的运算量和减少循环迭代次数。
        4、通常来说,switch总是比if-else快,但并不总是最佳解决方案。
        5、在判断条件较多时,使用查找表比if-else和switch更快。
        5、浏览器的调用栈大小限制了递归算法在javascript中的应用;栈溢出错误会导致其他代码中断运行。
        5、如果遇到栈溢出错误,可将方法改为迭代算法,或使用Memoization来避免重复计算
        
未完,待续..............
    
        
        
        

共有 人打赏支持
粉丝 4
博文 52
码字总数 47587
×
-波仔-
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: