通常我们写页面的时候都是将一些需要引入的js包都放到dom的最后【达到延迟加载的目的】,这样可以快速的渲染页面。这样的方式去加载js是同步加载的(dom解析是同步的),何不使用异步的方式去加载js?这样加载时间仅仅取决于最大那个js文件的时间,岂不是更快?
异步加载的重要性【这是因为页面速度成为google搜索算法中排名因素的时代已经到来,和竞争对象相比,你的网站载入速度越快,它在google搜索结果列表中排名就越靠前。如果你的页面上有广告,那么异步加载会扮演重要角色】:
https://www.adglare.com/kb/4/why-is-asynchronous-ad-loading-so-important
如果 async="async":脚本相对于页面的其余部分异步地执行(当页面继续进行解析时,脚本将被执行)【对于jQuery不适合,因为jQuery可能会有dom操作】
如果不使用 async 且 defer="defer":脚本将在页面完成解析时执行
如果既不使用 async 也不使用 defer:在浏览器继续解析页面之前,立即读取并执行脚本
<script src="../static/jquery/jquery-1.9.1.min.js"></script> <img src="images/1.jpg" alt=""> <img src="images/2.jpg" alt=""> <img src="images/3.jpg" alt=""> <img src="images/4.jpg" alt="">
右侧竖直蓝色线表示大约在420ms后DOM就绪,红色竖直线表示大约在458ms所有文件加载就绪。
<script src="../static/jquery/jquery-1.9.1.min.js" async="defer"></script> <img src="images/1.jpg" alt=""> <img src="images/2.jpg" alt=""> <img src="images/3.jpg" alt=""> <img src="images/4.jpg" alt="">
右侧竖直蓝色线表示大约在355ms后DOM就绪,红色竖直线表示大约在568ms所有文件加载就绪。
<script src="../static/jquery/jquery-1.9.1.min.js" async="async"></script> <img src="images/1.jpg" alt=""> <img src="images/2.jpg" alt=""> <img src="images/3.jpg" alt=""> <img src="images/4.jpg" alt="">
右侧竖直蓝色线表示大约在340ms后DOM就绪,红色竖直线表示大约在528ms所有文件加载就绪。
以上三种方式对比可以发现,使用异步的方式明显提高了DOM渲染的速度!
这是在online条件下测试的,如果在网速慢得情况下测试将更明显,你可以把online切换完Slow 3G测试。
bower install script.js --save
<body> <script src="bower_components/script.js/dist/script.js"></script> <script> // 加载单个脚本 $script('bower_components/jquery/dist/jquery.js', function () { // foo.js is ready console.log(jQuery); }) </script> </body>
可见,script.js是在head标签里创建了一个script标签,将load完的脚本引入。
<body> <script src="bower_components/script.js/dist/script.js"></script> <script> // 加载多个脚本 $script([ 'bower_components/angular/angular.js', 'bower_components/angular-route/angular-route.js', 'components/jsonp/jsonpSev.js', 'app.js', ],function () { console.log(angular); }) </script> </body>
由于是异步加载,肯定有先加载完和后加载完,如果先加载完的脚本依赖后加载完的脚本,就像jQuery-plugins.js依赖jQuery.js一样,你要先把jQuery.js放在前面加载,然后才能加载jQuery-plugins.js,不然就会报错!
// 按指定顺序加载多个脚本 $script('bower_components/angular/angular.js', function () { $script('bower_components/angular-route/angular-route.js', function () { $script('components/jsonp/jsonpSev.js', function () { $script('app.js', function () { $script('moviecat/controller.js', function () { console.log(123); }) }) }) }) });
解决办法:使用angular-loader.js,只要引入这个包,它就会帮我们自动的按照依赖顺序加载这些包。
<body ng-app="MyApp"> <script src="bower_components/script.js/dist/script.js"></script> <script src="bower_components/angular-loader/angular-loader.js"></script> </body> <script> // 加载多个脚本 $script([ 'bower_components/angular/angular.js', 'bower_components/angular-route/angular-route.js', 'components/jsonp/jsonpSev.js', 'app.js', 'moviecat_list/controller.js', ],function () { console.log(angular); /*手动引导的方式*/ // angular.bootstrap(document.querySelector("[ng-app='MyApp']"),['MyApp']) }); </script>
github使用文档:https://github.com/muicss/loadjs
<body ng-app="MyApp"> <script src="bower_components/loadjs/dist/loadjs.js"></script> <script> // 加载多个脚本 loadjs([ 'bower_components/angular/angular.js', 'bower_components/angular-route/angular-route.js', 'components/jsonp/jsonpSev.js', 'app.js', 'moviecat_list/controller.js', ],{ success: function() { console.log(123); }, error:function () { console.log(456); }, async: false // 并行获取文件,并串行加载他们 }); </script> </body>