基于js文件加载优化(详解)


Posted in Javascript onJanuary 03, 2018

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

js文件放置位置应该放置到body末尾

如果使用async的话,最后加上defer以求向下兼容

<script src="test.js" async defer></script> //如果两者都支持,async会默认覆盖掉defer
//如果只支持一个,则执行对应的即可

通常,我们使用的加载都是defer加载(因为很强的依赖关系).

以上这篇基于js文件加载优化(详解)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
分享20多个很棒的jQuery 文件上传插件或教程
Sep 04 Javascript
node.js开机自启动脚本文件
Dec 24 Javascript
JavaScript中setMonth()方法的使用详解
Jun 11 Javascript
RequireJS入门一之实现第一个例子
Sep 30 Javascript
JSON对象 详解及实例代码
Oct 18 Javascript
AngularJS 获取ng-repeat动态生成的ng-model值实例详解
Nov 29 Javascript
Bootstrap Scrollspy源码学习
Mar 02 Javascript
详解基于Node.js的微信JS-SDK后端接口实现代码
Jul 15 Javascript
jQuery实现数字自动增加或者减少的动画效果示例
Dec 11 jQuery
微信小程序网络层封装的实现(promise, 登录锁)
May 08 Javascript
jQuery使用ajax传递json对象到服务端及contentType的用法示例
Mar 12 jQuery
vue/cli 配置动态代理无需重启服务的方法
May 20 Vue.js
jQuery 实现左右两侧菜单添加、移除功能
Jan 02 #jQuery
js 取消页面可以选中文字的功能方法
Jan 02 #Javascript
js阻止默认右键的下拉菜单方法
Jan 02 #Javascript
webpack实用小功能介绍
Jan 02 #Javascript
js最简单的双向绑定实例讲解
Jan 02 #Javascript
js 将canvas生成图片保存,或直接保存一张图片的实现方法
Jan 02 #Javascript
js原生方法被覆盖,从新赋值原生的方法
Jan 02 #Javascript
You might like
PHP 中的批处理的实现
2007/06/14 PHP
PHP中的use关键字及文件的加载详解
2016/11/28 PHP
PHP实现从上往下打印二叉树的方法
2018/01/18 PHP
js Event对象的5种坐标
2011/09/12 Javascript
EASYUI TREEGRID异步加载数据实现方法
2012/08/22 Javascript
select多选 multiple的使用示例
2014/06/16 Javascript
Underscore.js常用方法总结
2015/02/28 Javascript
JavaScript从数组的indexOf()深入之Object的Property机制
2016/05/11 Javascript
jQuery Easyui 下拉树组件combotree
2016/12/16 Javascript
JS正则子匹配实例分析
2016/12/22 Javascript
详解通过JSON数据使用VUE.JS
2017/05/26 Javascript
Angular4集成ng2-file-upload的上传组件
2018/03/14 Javascript
对TypeScript库进行单元测试的方法
2019/07/18 Javascript
vue实现表单录入小案例
2019/09/27 Javascript
windows如何把已安装的nodejs高版本降级为低版本(图文教程)
2020/12/14 NodeJs
python 异常处理总结
2016/10/18 Python
python中copy()与deepcopy()的区别小结
2018/08/03 Python
Python 实现异步调用函数的示例讲解
2018/10/14 Python
对python中的 os.mkdir和os.mkdirs详解
2018/10/16 Python
解决pycharm安装第三方库失败的问题
2020/05/09 Python
python如何安装下载后的模块
2020/07/03 Python
CSS3 制作旋转的大风车(充满童年回忆)
2013/01/30 HTML / CSS
css3实现可拖动的魔方3d效果
2019/05/07 HTML / CSS
硕士研究生自我鉴定范文
2013/12/27 职场文书
创业计划书的内容步骤和要领
2014/01/04 职场文书
小学数学课题方案
2014/06/15 职场文书
学习党的群众路线实践活动思想汇报
2014/09/12 职场文书
于丹论语心得观后感
2015/06/15 职场文书
工商局调档介绍信
2015/10/22 职场文书
2016年七夕爱情寄语
2015/12/04 职场文书
公司要求试用期员工提交“述职报告”,该怎么写?
2019/07/17 职场文书
详解JavaScript中Arguments对象用途
2021/08/30 Javascript
详解Oracle块修改跟踪功能
2021/11/07 Oracle
win11怎么用快捷键锁屏? windows11锁屏的几种方法
2021/11/21 数码科技
InterProcessMutex实现zookeeper分布式锁原理
2022/03/21 Java/Android
pd.DataFrame中的几种索引变换的实现
2022/06/16 Python