这篇文章主要为大家详细介绍了 javascript 文件加载优化,三种方式实现 js 文件加载优化,感兴趣的小伙伴们可以参考一下
Javascript 是一种由 Netscape 的 LiveScript 发展而来的原型化继承的基于对象的动态类型的区分大小写的客户端脚本语言,主要目的是为了解决服务器端语言,比如 Perl,遗留的速度问题,为客户提供更流畅的浏览效果。
在 js 引擎部分,我们可以了解到,当渲染引擎解析到 script 标签时,会将控制权给 JS 引擎,如果 script 加载的是外部资源,则需要等待下载完后才能执行。 所以,在这里,我们可以对其进行很多优化工作。
放置在 BODY 底部
为了让渲染引擎能够及早的将 DOM 树给渲染出来,我们需要将 script 放在 body 的底部,让页面尽早脱离白屏的现象,即会提早触发 DOMContentLoaded 事件. 但是由于在 IOS Safari, Android browser 以及 IOS webview 里面即使你把 js 脚本放到 body 尾部,结果还是一样, 所以这里需要另外的操作来对 js 文件加载进行优化.
DEFER 加载
这是 html4 中定义的一个 script 属性,它用来表示的是,当渲染引擎遇到 script 的时候,如果 script 引用的是外部资源,则会暂时挂起,并进行加载。 渲染引擎继续解析下面的 HTML 文档,解析完时,则会执行 script 里面的脚本。
- <script src="outside.js" defer>
- </script>
他的支持度是 <=IE9 的.
并且,他的执行顺序,是严格依赖的,即:
- <script src="outside1.js" defer>
- </script>
- <script src="outside2.js" defer>
- </script>
- <script src="outside1.js" defer>
- </script>
- <script>
- </script>
- //hack
- <script src="outside2.js" defer>
- </script>
ASYNC 加载
async 是 H5 新定义的一个 script 属性。 他是另外一种 js 的加载模式。
可以看出 async 也可以解决 阻塞加载 这个问题。不过,async 执行的时候是异步执行,造成的是,执行文件的顺序不一致。即:
- <script src="outside1.js" async>
- </script>
- <script src="outside2.js" async>
- </script>
这时,谁先加载完,就先执行谁。所以,一般依赖文件就不应该使用 async 而应该使用 defer.
defer 的兼容性比较差,为 IE9+, 不过一般是在移动端使用,也就不存在这个 problem 了。
脚本异步
脚本异步是一些异步加载库 (比如 require) 使用的基本加载原理. 直接上代码:
- function asyncAdd(src){
- var script = document.createElement('script');
- script.src = src;
- document.head.appendChild(script);
- }
- //加载js文件
- asyncAdd("test.js");
这时候,可以异步加载文件,不会造成阻塞的效果.
但是,这样加载的 js 文件是无序的,无法正常加载依赖文件。
这时候,我们需要对上述函数进行优化.
- var asyncAdd = (function() {
- var head = document.head,
- script;
- return function(src) {
- script = document.createElement('script');
- script.src = src;
- script.async = false;
- document.head.appendChild(script);
- }
- })();
- //加载文件
- asyncAdd("first.js");
- asyncAdd("second.js");
- //或者简便一点
- ["first.js", "second.js"].forEach((src) = >{
- async(src);
- });
但是,使用脚本一步加载的话,需要等待 CSS 文件加载完后,才开始进行加载,不能充分利用浏览器的并发加载优势。而使用静态文本加载 async 或者 defer 则不会出现这个问题。
使用脚本异步加载时,只能等待 css 加载完后才会加载
使用静态的 async 加载时,css 和 js 会并发一起加载
关于这三种如何取舍,那就主要看 leader 给我们目标是什么,是兼容 IE8,9 还是手机端,还是桌面浏览器,或者两两组合。
但是对于单独使用某一个技能的场景,使用时需要注意一些 tips。
1、js 文件放置位置应该放置到 body 末尾
2、如果使用 async 的话,最后加上 defer 以求向下兼容
- <script src="test.js" async defer>
- </script>
- //如果两者都支持,async会默认覆盖掉defer //如果只支持一个,则执行对应的即可
通常,我们使用的加载都是 defer 加载,因为很强的依赖关系。
来源: http://www.phperz.com/article/17/0218/267078.html