前端JS的加载方式?JS的异步加载

  过多js加载会影响页面效率,一旦网速不好,那么整个网站将等待js加载而不进行后续渲染等工作。 有些工具方法需要按需加载,用到再加载,不用不加载。默认正常模式下,JS是同步加载的,即优先加载JS,只有当JS文件下载完,dom和css才开始加载,当某些时候我们需要JS异步加载,我们可以设置异步加载。

不同情况下选取不同方式即可。

一:同步加载

我们平时使用的最多的一种方式。

<script src="http://aaaa.com/script.js"></script>

<script src="http://bbbb.com/script.js"></script>

<script src="xxx/script.js"></script>

<script src="xxx/xxx/script.js"></script>

同步模式,又称阻塞模式,会阻止浏览器的后续处理,停止后续的解析,只有当当前加载完成,才能进行下一步操作。

所以默认同步执行才是安全的。但这样如果js中有输出document内容、修改dom、重定向等行为,就会造成页面堵塞。所以一般建议把<script>标签放在<body>结尾处,这样尽可能减少页面阻塞。

二:异步加载

异步加载又叫非阻塞加载,浏览器在下载执行js的同时,还会继续进行后续页面的处理。

1.async 和 defer 属性

<script type="text/javascript" src="xxx.js" async></script>
<script type="text/javascript" src="xxx.js" defer></script>

defer:

  • defer属性声明这个脚本中将不会有 document.write 或 dom 修改。
  • 浏览器将会并行下载 js 和其它有 defer 属性的script,而不会阻塞页面后续处理。
  • defer属性在IE 4.0中就实现了,它提示浏览器这个 script 不会产生任何文档元素(没有document.write),因此浏览器会继续后续处理和渲染。兼容所有浏览器 。
  • 所有的defer 脚本保证是按顺序依次执行的。

async:

  • async属性是HTML5新增属性,IE9+浏览器支持

  • async属性规定一旦脚本下载完成则尽快使用,会异步执行

  • async属性仅适用于外部脚本

  • 此方法不能保证脚本按顺序执行

  • 它们将在onload事件之前完成

总结:可以同时使用 async 和 defer。

          如果没有 async 属性 但是有 defer 属性,那么script 将在页面parse之后执行。

          如果同时设置了二者,那么 defer 属性主要是为了让不支持 async 属性的老浏览器按照原来的 defer 方式处理。

2.Script DOM Element

(function() {
     var st = document.createElement('script');
     st.type = 'text/javascript';
     st.async = true;
     st.src = 'http://aaaa.com/script.js';
     var x = document.getElementsByTagName('script')[0];
     x.parentNode.insertBefore(st, x);
   //x.insertBefore(st, x.firstChild); 
 })();

缺点:这种加载方式执行完之前会阻止onload事件的触发,而现在很多页面的代码都在onload时还执行额外的渲染工作,所以还是会阻塞部分页面的初始化处理。

3.onload 时的异步加载

(function() {
     function async_load(){
         var s = document.createElement('script');
         s.type = 'text/javascript';
         s.async = true;
         s.src = 'http://xxx/script.js';
         var x = document.getElementsByTagName('script')[0];
         x.parentNode.insertBefore(s, x);
     }
     if (window.attachEvent)
         window.attachEvent('onload', async_load);
     else
         window.addEventListener('load', async_load, false);
 })();

这种方法只是把插入script的方法放在一个函数里面,然后放在window的onload方法里面执行,这样就解决了阻塞onload事件触发的问题。

DOMContentLoaded 与 OnLoad 事件

DOMContentLoaded 页面(document)已经解析完成,页面中的dom元素已经可用。但是页面中的图片,视频,音频等资源未加载完,作用同jQuery中的ready事件
OnLoad 页面的所有资源都加载完毕(包括图片)。浏览器的载入进度在这时才停止。

这两个时间点将页面加载的timeline分成了三个阶段。

 

4.$(document).ready()

  • 需要引入jquery

  • 兼容所有浏览器

    
    $(document).ready(function() {
            alert("JS加载完成!");
          });

5.由于JavaScript的动态性,还有很多异步加载方法:

    XHR Injection、 XHR Eval、 Script In Iframe、 Script defer属性、 document.write(script tag)。



总结:

对于支持HTML5的浏览器,实现JS的异步加载只需要在script元素中加上async属性,为了兼容老版本的IE还需加上defer属性;

对于不支持Html5的浏览器(IE可以用defer实现),可以采用以上几种方法实现。

原理基本上都是向DOM中写入script或者通过eval函数执行JS代码,你可以把它放在匿名函数中执行,也可以在onload中执行,也可以通过XHR注入实现,也可以创建一个iframe元素,然后在iframe中执行插入JS代码。

猜你喜欢

转载自blog.csdn.net/Crazy_Oranges/article/details/82156924