学习javascript文件加载优化


Posted in Javascript onFebruary 19, 2016

在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>

当页面解析完后,他便会开始按照顺序执行 outside1 和 outside2文件。
如果你在IE9以下使用defer的话,可能会遇到 它们两个不是顺序执行的,这里需要一个hack进行处理,即在两个中间加上一个空的script标签

<script src="outside1.js" defer></script>
<script></script> //hack
<script src="outside2.js" defer></script>

ASYNC加载

async是H5新定义的一个script 属性。 他是另外一种js的加载模式。

  • 渲染引擎解析文件,如果遇到script(with async)
  • 继续解析剩下的文件,同时并行加载script的外部资源
  • 当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加载,因为很强的依赖关系。

以上就是本文的全部内容,希望对大家的学习有所帮助。

Javascript 相关文章推荐
基于bootstrap3和jquery的分页插件
Jul 31 Javascript
JavaScript事件处理的方式(三种)
Apr 26 Javascript
jQuery限制图片大小的方法
May 25 Javascript
AngularJS使用ng-Cloak阻止初始化闪烁问题的方法
Nov 03 Javascript
javascript输出AscII码扩展集中的字符方法
Dec 26 Javascript
PHP实现记录代码运行时间封装类实例教程
May 08 Javascript
详解vue-router 路由元信息
Sep 13 Javascript
Vue项目组件化工程开发实践方案
Jan 09 Javascript
解决Vue2.0中使用less给元素添加背景图片出现的问题
Sep 03 Javascript
解决layer.open弹出框不能获取input框的值为空的问题
Sep 10 Javascript
实例分析JS中的相等性判断===、 ==和Object.is()
Nov 17 Javascript
微信小程序自定义tabBar的踩坑实践记录
Nov 06 Javascript
初识angular框架后的所思所想
Feb 19 #Javascript
复杂的javascript窗口分帧解析
Feb 19 #Javascript
javascript轻量级库createjs使用Easel实现拖拽效果
Feb 19 #Javascript
jQuery fancybox在ie浏览器下无法显示关闭按钮的解决办法
Feb 19 #Javascript
谈一谈javascript中继承的多种方式
Feb 19 #Javascript
多种js图片预加载实现方式分享
Feb 19 #Javascript
JS实现1000以内被3或5整除的数字之和
Feb 18 #Javascript
You might like
2019年中国咖啡业现状与发展趋势
2021/03/04 咖啡文化
php下pdo的mysql事务处理用法实例
2014/12/27 PHP
浅析Yii2集成富文本编辑器redactor实例教程
2016/04/25 PHP
PHP读取文件或采集时解决中文乱码
2021/03/09 PHP
Google韩国首页图标动画效果
2007/08/26 Javascript
ajax更新数据后,jquery、jq失效问题
2011/03/16 Javascript
利用js(jquery)操作Cookie的方法说明
2013/12/19 Javascript
jQuery检测返回值的数据类型
2015/07/13 Javascript
如何用js 实现依赖注入的思想,后端框架思想搬到前端来
2015/08/03 Javascript
JSON字符串和对象相互转换实例分析
2016/06/16 Javascript
JS实现图片剪裁并预览效果
2016/08/12 Javascript
jQuery实现 上升、下降、删除、添加一行代码
2017/03/06 Javascript
Vue表单验证插件的制作过程
2017/04/01 Javascript
详解在AngularJS的controller外部直接获取$scope
2017/06/02 Javascript
js实现会跳动的日历效果(完整实例)
2017/10/18 Javascript
JavaScript数组排序小程序实现解析
2020/01/13 Javascript
小程序如何定位所在城市及发起周边搜索
2020/02/11 Javascript
[37:22]DOTA2上海特级锦标赛D组资格赛#2 Liquid VS VP第一局
2016/02/28 DOTA
Python break语句详解
2014/03/11 Python
python django 访问静态文件出现404或500错误
2017/01/20 Python
神经网络python源码分享
2017/12/15 Python
基于Django URL传参 FORM表单传数据 get post的用法实例
2018/05/28 Python
Python 十六进制整数与ASCii编码字符串相互转换方法
2018/07/09 Python
PYTHON EVAL的用法及注意事项解析
2019/09/06 Python
python 使用opencv 把视频分割成图片示例
2019/12/12 Python
selenium学习教程之定位以及切换frame(iframe)
2021/01/04 Python
移动Web—CSS为Retina屏幕替换更高质量的图片
2012/12/24 HTML / CSS
html5通过canvas实现刮刮卡效果示例分享
2014/01/27 HTML / CSS
微信html5页面调用第三方位置导航的示例
2018/03/14 HTML / CSS
XD健身器材:Kevlar球、Crossfit健身球
2019/03/26 全球购物
UNIX特点都有哪些
2016/04/05 面试题
超市总经理岗位职责
2014/02/02 职场文书
中专自我鉴定
2014/02/05 职场文书
文明班集体申报材料
2014/05/23 职场文书
爱牙日活动总结
2014/08/29 职场文书
2016党员入党决心书
2015/09/22 职场文书