学习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 相关文章推荐
利用js跨页面保存变量做菜单的方法
Jan 17 Javascript
file模式访问网页时iframe高度自适应解决方案
Jan 16 Javascript
HTML5 js实现拖拉上传文件功能
Nov 20 Javascript
原生js实现中奖信息无间隙滚动效果
Jan 18 Javascript
bootstrap css样式之表单
Jan 19 Javascript
Angular 2父子组件数据传递之@ViewChild获取子组件详解
Jul 04 Javascript
二维码图片生成器QRCode.js简单介绍
Aug 18 Javascript
vue生命周期的探索
Apr 03 Javascript
使用react context 实现vue插槽slot功能
Jul 18 Javascript
微信小程序如何通过用户授权获取手机号(getPhoneNumber)
Jan 21 Javascript
js实现小星星游戏
Mar 23 Javascript
javascript设计模式 ? 策略模式原理与用法实例分析
Apr 21 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
php 5.3.5安装memcache注意事项小结
2011/04/12 PHP
PHP实现定时执行任务的方法
2014/10/05 PHP
PHP常用的排序和查找算法
2015/08/06 PHP
php图片添加文字水印实现代码
2016/03/15 PHP
PHP使用SOAP扩展实现WebService的方法
2016/04/01 PHP
PHP实现蛇形矩阵,回环矩阵及数字螺旋矩阵的方法分析
2017/05/29 PHP
PHP使用反向Ajax技术实现在线客服系统详解
2019/07/01 PHP
laravel批量生成假数据的方法
2019/10/09 PHP
js对table的td进行相同内容合并示例详解
2013/12/27 Javascript
JS日期加减,日期运算代码
2015/11/05 Javascript
浅谈jQuery中ajaxPrefilter的应用
2016/08/01 Javascript
Vue.js系列之vue-router(上)(3)
2017/01/03 Javascript
浅析JavaScript中var that=this
2017/02/17 Javascript
浅谈Node.js ORM框架Sequlize之表间关系
2017/07/24 Javascript
JavaScript实现离开页面前提示功能【附jQuery实现方法】
2017/09/26 jQuery
AngularJS2 与 D3.js集成实现自定义可视化的方法
2017/12/01 Javascript
Javascript通过控制类名更改样式
2019/05/24 Javascript
vue用ant design中table表格,点击某行时触发的事件操作
2020/10/28 Javascript
python+PyQT实现系统桌面时钟
2020/06/16 Python
python实现爬山算法的思路详解
2019/04/09 Python
Django RBAC权限管理设计过程详解
2019/08/06 Python
python创建与遍历List二维列表的方法
2019/08/16 Python
Python实现二叉树的最小深度的两种方法
2019/09/30 Python
Django Form and ModelForm的区别与使用
2019/12/06 Python
如何使用Python发送HTML格式的邮件
2020/02/11 Python
用python按照图像灰度值统计并筛选图片的操作(PIL,shutil,os)
2020/06/04 Python
详解pandas获取Dataframe元素值的几种方法
2020/06/14 Python
纯css3(无图片/js)制作的几个社交媒体网站的图标
2013/03/21 HTML / CSS
Stefania Mode美国:奢华设计师和时尚服装
2018/01/07 全球购物
如何通过jdbc调用存储过程
2012/04/19 面试题
家庭教育先进个人事迹材料
2014/01/24 职场文书
安全协议书
2014/04/23 职场文书
2014办公室副主任四风对照检查材料思想汇报
2014/09/20 职场文书
2014年会计工作总结
2014/11/27 职场文书
2015年学生会工作总结范文
2015/03/31 职场文书
SQL SERVER中常用日期函数的具体使用
2021/04/08 SQL Server