• javascript性能优化:创建javascript无阻塞脚本


      javaScript 在浏览器中的运行性能,在web2.0时代显得尤为重要,成千上万行javaScript代码无疑会成为性能杀手,

    在较低版本的浏览器执行JavaScript代码的时候,由于浏览器只使用单一进程来处理ui界面刷新和JavaScript脚本执行,

    这意味着在加载javascript文件的时候不能同时做任何其他的事情。   在加载的同时造成了用户交互阻塞;


      理论上来说,把样式与行为有关的脚本放在一起率先加载,这样有利于确保正确的用户体验,例如下面的代码:

    <!DOCTYPE html>
    <html>
    <head>
    	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    	<title>javascript</title>
    	<script src="file.js" type="text/javascript" charset="utf-8"></script>
    	<script src="file1.js" type="text/javascript" charset="utf-8"></script>
    	<link rel="stylesheet" type="text/css" href="file.css"/>
    	<link rel="stylesheet" type="text/css" href="file1.css"/>
    	<link rel="stylesheet" type="text/css" href="file2.css"/>
    </head>
    <body>
    
    </body>
    </html>
    

      这种看似合理的代码其实有着很严重的性能问题:在javascript文件加载并执行完成之前会阻止页面进行渲染,我们的web页面会出现一片空白

    无法与之正常交互,这称之为脚本阻塞

      

      由于脚本会阻塞页面其他资源的加载 我们可以把所有的script标签放在</body>之前  在页面加载的最后来加载javascript文件

    <!DOCTYPE html>
    <html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>javascript</title>
        
        <link rel="stylesheet" type="text/css" href="file.css"/>
        <link rel="stylesheet" type="text/css" href="file1.css"/>
        <link rel="stylesheet" type="text/css" href="file2.css"/>
    </head>
    <body>
        
        <!--推荐所有的js文件位置-->
        <script src="file.js" type="text/javascript" charset="utf-8"></script>
        <script src="file1.js" type="text/javascript" charset="utf-8"></script>
    </body>
    </html>


    -----------优化javascript的首要任务,将js文件放置在页面底部;

       那如何创建一个无阻塞的脚本呢?

    无阻塞脚本的秘诀在于,在页面加载完成之后才开始加载javascript代码。 我们要在window对象的load时间触发后再下载并执行脚本,

    已知有很多种方式可以实现这一效果,这里简单例举一二:

      1.HTML5新特性 

        html5为script标签提供了两个新的属性 一个是defer 另一个是async 它们采用的都是并行下载的方式; 在下载过程中并不会造成页面阻塞

    它们的区别在于 defer表示等待页面加载完成才会执行,async则是它本身加载完成后就自动执行;

    defer目前已被各大主流浏览器所兼容;

      2.创建动态脚本元素;这很容易使页面渲染完成之后再进行脚本加载;

    例如:

      

    <!DOCTYPE html>
    <html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>javascript</title>
        
    </head>
    <body>
        
        <script type="text/javascript">
            var script = document.createElement("script");
            script.src = "ztf.js";
            document.getElementsByTagName("head")[0].appendChild(script);
        </script>
    </body>
    </html>

      我们使用标准的dom方法document.createElement来动态的创建一个script元素并指定它的src;这行成了一个动态的脚本模式;在任意时刻插入任意的javascript代码都会被浏览器执行;(创建的script最好不要插入到body里面;这样可能会引起ie抛出一个‘操作已终止’的错误信息;)

      ff,opera,chrome和safari3以上版本的script标签会在加载完成触发onload事件。

      而在老版本ie下(ie6-10) 它会触发一个readystatechange事件。<script>元素会提供一个readyState属性,它的值在scr加载不同过程产生不同的变化;我们通常会使用到 "loaded" 和 "complete"。

      通过“客户端能力检测” (http://www.jxbh.cn/newshow.asp?id=1434&tag=2) 我们可以创建一个通用的动态加载javascript的函数:    

    function loadScript(url,callback){
                var script = document.createElement("script");
                script.type="text/javascript";
                if(script.readyState){        //客户端能力检测  如果支持readyState则返回的是字符串 反之返回undefined
                    script.onreadystatechange = function(){    //onreadystatechange事件
                        if(script.readyState=="loaden"||script.readyState=="complete"){
                            
                            script.onreadystatechange=null;
                            
                            callback();
                        }
                    }
                }else{
                    script.onload = function(){
                        callback();
                    }
                }
                script.src = url;
                document.getElementsByTagName("head")[0].appendChild(script);
            }

    这个函数接受两个参数;javascript文件的url和完成加载后的回调函数。loadScript()函数的用法如下

    loadScript("ztf.js",function(){
           alert("loadend")
    });

    如果需要的话,你可以尽可能多的加载javascript文件到页面上,但一定要考虑清楚文件的加载顺序,可以不断的使用callback回调函数加载多个javascript脚本;

    另外还有一种,ajax动态请求加载脚本 在这里笔者就不一 一说明 ,大家查阅有关文档;

    部分内容摘自《高性能javascript》

  • 相关阅读:
    sequence——强行推式子+组合意义
    2018-2-25-git-rebase-合并多个提交
    2018-2-25-git-rebase-合并多个提交
    2019-9-2-给博客添加rss订阅
    2019-9-2-给博客添加rss订阅
    2019-10-31-Resharper-去掉注释拼写
    2019-10-31-Resharper-去掉注释拼写
    2018-8-10-win10-sdk-是否向下兼容
    2018-8-10-win10-sdk-是否向下兼容
    2019-8-15-win10-edge-打开闪退问题
  • 原文地址:https://www.cnblogs.com/ztfjs/p/5386625.html
Copyright © 2020-2023  润新知