JavaScript中的无阻塞加载性能优化方案(2)

但诸如大型网页有大量的Js代码,保持源码短小并不总是一种最佳选择。So,非阻塞脚本应运而生,我们需要的是向页面中逐步添加javascript,某种程度上而言不会阻塞浏览器。

而非阻塞脚本的关键在于,等页面完成加载之后,再加载Javascript源码,这意味着在window的load事件发出之后开始下载代码。

相关解释:

window 的load事件只会在页面载入完毕后触发一次且仅一次。
window.onload=function(){}必须等待网页中所有的内容加载完毕后 ( 包括元素的所有关联文件,例如图片 ) 才能执行,即Javascript此时才可以访问页面中的任何元素。

如下述几种方法:

Deferred Scripts 延期脚本

Html4为<script>标签定义了一个扩展属性:defer。

这个defer属性指明元素中所包含的脚本不打算修改DOM,因此代码可以稍后执行。defer属性只被Internet Explorer 4+和Firefox 3.5+支持,它不是一个理想的跨浏览器解决方案。在其他浏览器上,defer属性将被忽略。所以,<script>标签会按照正常默认方式处理,即是会造成阻塞。如果得到各个主流浏览器的支持,这仍是一种有效的解决方式。

复制代码 代码如下:


<script type="text/javascript" src="https://www.jb51.net/file1.js" defer></script>

一个带有defer属性的<script>标签可以放置在文档的任何位置,它会在被解析时启动下载,直到DOM加载完成(在onload事件句柄被调用之前)。当一个defer的Javascript文件被下载时,它不会阻塞浏览器的其他处理过程,所以这些文件可以与其他资源一起并行下载。

可以使用下述代码测试浏览器是否支持defer属性:

复制代码 代码如下:


 <html>
   <head>
     <title>Script Defer Example</title>
   </head>
 
   <body>
     <script defer> alert("defer");</script>
     <script> alert("script"); </script>
     <script> window.onload = function(){ alert("load");}; </script>
   </body>
 </html>

如果浏览器不支持defer,那么弹出的对话框的顺序是“defer”,“script”,“load”。

如果浏览器支持defer,那么弹出的对话框的顺序是“script”,“load”,“defer”。

Dynamic Script Elements 动态脚本元素

DOM允许我们使用Javascript动态创建HTML的几乎所有文档内容,一个新的<script>元素可以非常容易的通过标准DOM创建:

复制代码 代码如下:


1 var script = document.createElement ("script");
2 script.type = "text/javascript";
3 script.src = "https://www.jb51.net/file1.js";
4 document.body.appendChild(script);

新的<script>元素加载file1.js源文件。此文件当元素添加到页面后立刻开始下载。此技术的重点在于:无论在何处启动下载,文件的下载和运行都不会阻塞其他页面处理过程。

当文件使用动态脚本节点下载时,返回的代码通常立即执行(除了Firefox和Opera,它们将等待此前的所有动态脚本节点执行完毕)。

大多数情况下,我们希望调用一个函数就可以实现Javascript文件的动态下载。下面的函数封装实现了标准实现和IE实现:

复制代码 代码如下:


  function loadScript(url, callback){
     var script = document.createElement ("script") ;
    script.type = "text/javascript";
     
     if (script.readyState){ //IE
        script.onreadystatechange = function(){
          if (script.readyState == "loaded" || script.readyState == "complete"){
            script.onreadystatechange = null;
            callback();
           }
        };
      }
      else { //Others
        script.onload = function(){ callback();
      };
    }
    script.src = url;
    document.getElementsByTagName("head")[0].appendChild(script);
  }
 
 loadScript("https://www.jb51.net/file1.js", function(){  //调用
     alert("File is loaded!");
 });

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wgsdsd.html