学习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 相关文章推荐
关于取不到由location.href提交而来的上级页面地址的解决办法
Jul 30 Javascript
JavaScript Event学习第七章 事件属性
Feb 07 Javascript
javaScript中的this示例学习详解及工作原理
Jan 13 Javascript
js通过更改按钮的显示样式实现按钮的滑动效果
Apr 23 Javascript
JavaScript函数模式详解
Nov 07 Javascript
JavaScript如何自定义trim方法
Jul 28 Javascript
js 动态添加元素(div、li、img等)及设置属性的方法
Jul 19 Javascript
浅谈原生JS中的延迟脚本和异步脚本
Jul 12 Javascript
新手vue构建单页面应用实例代码
Sep 18 Javascript
谈谈vue中mixin的一点理解
Dec 12 Javascript
JavaScript ES6 Class类实现原理详解
May 08 Javascript
vue 中this.$set 动态绑定数据的案例讲解
Jan 29 Vue.js
初识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
Laravel5.5 视图 - 创建视图和数据传递示例
2019/10/21 PHP
基于jquery的拖动布局插件
2011/11/25 Javascript
在javascript中执行任意html代码的方法示例解读
2013/12/25 Javascript
手机端页面rem宽度自适应脚本
2015/05/20 Javascript
JS模拟键盘打字效果的方法
2015/08/05 Javascript
JS实现的仿东京商城菜单、仿Win右键菜单及仿淘宝TAB特效合集
2015/09/28 Javascript
BootstrapTable与KnockoutJS相结合实现增删改查功能【二】
2016/05/10 Javascript
JavaScript的字符串方法汇总
2016/07/31 Javascript
基于jquery实现的鼠标悬停提示案例
2016/12/11 Javascript
JQueryEasyUI框架下的combobox的取值和绑定的方法
2017/01/22 Javascript
获取url中用&amp;隔开的参数实例(分享)
2017/05/28 Javascript
node.js中axios使用心得总结
2017/11/29 Javascript
js实现敏感词过滤算法及实现逻辑
2018/07/24 Javascript
javascript中函数的写法实例代码详解
2018/10/28 Javascript
javascript移动端 电子书 翻页效果实现代码
2019/09/07 Javascript
解决微信授权成功后点击按返回键出现空白页和报错的问题
2020/06/08 Javascript
JS如何监听div的resize事件详解
2020/12/03 Javascript
Python 时间操作例子和时间格式化参数小结
2014/04/24 Python
Python 稀疏矩阵-sparse 存储和转换
2017/05/27 Python
浅谈python中的__init__、__new__和__call__方法
2017/07/18 Python
python 打印直角三角形,等边三角形,菱形,正方形的代码
2017/11/21 Python
python中set()函数简介及实例解析
2018/01/09 Python
利用python库在局域网内传输文件的方法
2018/06/04 Python
浅谈Python接口对json串的处理方法
2018/12/19 Python
Python编写通讯录通过数据库存储实现模糊查询功能
2019/07/18 Python
opencv3/C++ 平面对象识别&amp;透视变换方式
2019/12/11 Python
python UIAutomator2使用超详细教程
2021/02/19 Python
Tostadora意大利:定制T恤
2019/04/08 全球购物
Linux常见面试题
2013/03/18 面试题
中学教师岗位职责
2013/11/26 职场文书
简历自我评价模版
2014/01/31 职场文书
主要领导对照检查材料
2014/08/26 职场文书
支部书记四风对照材料
2014/08/28 职场文书
遗嘱范文
2015/08/07 职场文书
合理缓解职场压力,让你随时保持最佳状态!
2019/06/21 职场文书
2022年显卡天梯图(6月更新)
2022/06/17 数码科技