zoukankan      html  css  js  c++  java
  • 高性能 js -- 无阻塞加载脚本

    参考: <<高性能JavaScript>> Nicbolas C. Zakas 著

    javascript代码的下载和执行过程会阻塞浏览器的其他进程, 比如页面的绘制, 遇到<script>标签的时候都必须停下来等待代码的下载并执行. 然后才继续处理其他部分. 

    无阻塞加载javascript代码的推荐方式:

    1 // 将下面的这段加载代码放到</body>的闭合标签之前,这样确保了JS执行过程中不会阻碍页面的其他
    2 // 内容显示, 其次第二个js文件完成下载时, 应用所需要的DOM结构已经创建完成, 并做好了交互的准备,
    3 // 从而可以避免检测 winodw.onload事件.  (注: loader.js中存放的是loadScript()的实现)
    4 <script type="text/javascript" src="loader.js"></script>
    5 <script type="text/javascript">
    6     loadScript("the-rest.js",function(){
    7         app.init();
    8     });
    9 </script>

    也可以将loadScript 直接嵌入页面, 从而避免多产生一次HTTP请求

     1 function loadScript(url,callback){
     2     var script = document.createElement("script");
     3     script.type = "text/javascript";
     4     if(script.readyState){//for IE
     5         script.onreadystatechange = function(){
     6             if(script.readyState == "onload" ||
     7                script.readyState == "complete"){
     8                 script.onreadystatechange = null; //删除事件处理器, 避免重复调用,IE自身的问题
     9                 callback();
    10             }
    11         }
    12     }else{ // for other browser,<script>标签的onload事件.
    13         script.onload = function(){
    14             callback();
    15         };
    16     }
    17     script.src = url;
    18     document.getElementByTagName("head")[0].appendChild(script);
    19 }

    如果需要按照顺序下载js文件,可以这样调用loadScript. 更好的方式是按顺序放到一个文件中, 避免多次HTTP请求.

    1 // load in order, but better way is write all script in one file in order.
    2 loadScript("file1.js",function(){
    3     loadScript("file2.js",function(){
    4         loadScript("file3.js",function(){
    5             console.log("All files are loaded in order!");
    6         });
    7     });
    8 });

    其他无阻塞模式:

    1. 使用defer: 很多浏览器目前不支持(包括chrome)  

      -----  当一个带有defer属性的js文件下载时, 不会阻塞浏览器的其他进程; 无论是内嵌的还是外联的defer的js脚本, 在DOM加载完成之前都不会被执行.

    2. 动态脚本元素: 返回的代码通常会立即执行, 在代码包含其他接口调用时会带来问题(可以跟踪<script>节点的onload或readystatechange事件).

      -----  文件在元素被添加到页面时开始下载; 无论在何时启动下载和执行过程不会阻塞页面其他进程, 推荐 append 到 head 下面.

    1 var script = document.createElement("script");
    2 script.type = "text/javascript";
    3 script.src = "file1.js";
    4 document.getElementByTagName("head")[0].appendChild(script);

    3. 使用XMLHttpRequest

      -----  代码是在<script> 标签之外返回的(xhr的open), 下载之后不会立即执行. 浏览器兼容性好. 但是必须要求js文件与页面处于同一个域中.

    4. 使用第三方库

      -----  LazyLoad:   loadScript()的增强版本

    1 <script type="text/javascript" src="lazyload-min.js"></script>
    2 <script type="text/javascript">
    3     LazyLoad.js(['first-file.js','second-file.js'],function(){
    4         Application.init();
    5     });
    6 </script>

      -----  LABjs  :  提供对加载过程的更精细的控制, 并试图下载尽可能多的代码

    1 <script type="text/javascript" src="lab.js"></script>
    2 <script type="text/javascript">
    3     $LAB.script("first-file.js").wait()   //wait在这里保证按序执行
    4         .script('the-rest-files.js')
    5         .wait(function(){ // 下载完成后执行的函数
    6             Application.init();
    7         });
    8 </script>
  • 相关阅读:
    吴裕雄--天生自然 PHP开发学习:数组
    吴裕雄--天生自然 JAVASCRIPT开发学习:测试 jQuery
    【t065】最敏捷的机器人
    【t079】火星上的加法运算
    【t053】整数去位
    【9604】纪念品分组
    【心情】bjdldrz
    【9601】零件分组
    【9916】编辑距离
    【38.24%】【POJ 1201】Intervals
  • 原文地址:https://www.cnblogs.com/roger9567/p/5082709.html
Copyright © 2011-2022 走看看