async、defer、动态加载js

Js 中的async属性和defer属性

一、async和defer

async:指外部js文件和当前html页面同时加载(异步加载),在当前js文件加载完成后,执行js代码

defer:指外部js文件和当前html页面同时加载(异步加载),但只在当前页面解析完成之后执行js代码

二、async和defer属性只对外部脚本文件有效:

async、defer、动态加载js

上图表明:这两个属性在内嵌式js中无效

三、当使用async和defer属性时, js 代码中的document.write(…);无法生效。

async、defer、动态加载js

因为当当前页面加载和解析完成之后,文档流已经关闭,所以无法向页面中写入内容了(可以使用DOM方法写入内容)

对“文档”执行“写入”失败:除非显式打开文档,否则无法从异步加载的外部脚本写入文档。

四、外部 js 文件的异步加载和执行

拥有async属性和defer属性的外部js文件属于异步加载,普通外部js文件属于同步加载。

异步加载:指同时加载,即某个js文件加载的同时,其余文件也可以加载

同步加载:指某个js文件加载的同时,其余文件不能加载,

async和defer的区别在于:async在当前页面加载的同时就可以执行js代码(或者说在当前js加载完成后执行)。defer在当前页面加载并解析完成之后才执行js代码。

如async:

async、defer、动态加载js

如defer:

async、defer、动态加载js

五、总结

①async和defer都属于异步加载

②async是当前js文件加载完成后执行js,defer是延迟执行(推迟解释,当前html页面解析完成后执行)js

js 怎么动态加载js文件

  1. 【基本优化】

将所有需要的之前,确保脚本执行之前完成页面渲染,而不会造成页面堵塞问题,这个大家都懂的。

async、defer、动态加载js

  1. 【合并 JS 代码,尽可能少的使用script标签】

最常见的方式就是带代码写入一个js文件中,让页面只使用一次标签来引入

async、defer、动态加载js

  1. 【无堵塞加载 JS

通过给script标签增加 defer属性或者是 async 属性来实现

注解:

async和defer不同之处是:async加载完成后会自动执行脚本,defer加载完成后需要等待页面也加载完成才会执行代码

async、defer、动态加载js

  1. 【动态创建script来加载-推荐】

function loadJS (url, callback) {
  var script = document.createElement('script');
  var fn = callback || function () {};
  script.type = 'text/javascript';

  // IE
  if (script.readyState) {
    script.onreadystatechange = function () {
      if( script.readyState == 'loaded' || script.readyState == 'complete' ){
        script.onreadystatechange = null;
        fn();
      }
    };
  } else {
    //其他浏览器
    script.onload = function () {
      fn();
    };
  }
  script.src = url;
  document.getElementsByTagName('head')[0].appendChild(script);
}
  
// 用法
loadJS('file.js', function () {

  alert('加载成功');
  
});
  

async、defer、动态加载js

  1. 谷歌浏览器运行效果,script被动态创建在head中

async、defer、动态加载js

  1. 建议大家可以封装成类库,单独引入。

该原理实现的也有很多不错的js类库可以使用,如LazyLoad.js支持数组的形式引入,打开浏览器在network中可看到js是同步加载的

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script type="text/javascript" src="js/lazyload.js"></script>
  <script type="text/javascript">
    (function () {
      LazyLoad.js(['js/jquery-1.11.min.js', 'js/jquery.flexslider-min.js', 'js/app.js'], function () {
        App.init();
      });
    })();
  </script>
</body>
</html>
  1. 【XHR加载】

// 使用ajax方式加载,代码如下:

var xhr = new XMLHttpRequest;
xhr.open('get', 'file.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);
    }
  }
};

xhr.send(null);
  1. 总结

最好的方式还是使用动态创建script的方式加载,当动态创建script,浏览器会分配一个线程去下载src指向的资源,多个script也是同步下载的

原文链接:https://juejin.cn/post/7236383034559905849 作者:yuqifang

(0)
上一篇 2023年5月23日 上午10:15
下一篇 2023年5月24日 上午10:05

相关推荐

发表回复

登录后才能评论