学习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 相关文章推荐
打印json对象的内容及JSON.stringify函数应用
Mar 29 Javascript
js+html5操作sqlite数据库的方法
Feb 02 Javascript
深入理解JavaScript内置函数
Jun 03 Javascript
jQuery3.0中的buildFragment私有函数详解
Aug 16 Javascript
EasyUI折叠表格层次显示detailview详解及实例
Dec 28 Javascript
Vue中添加手机验证码组件功能操作方法
Dec 07 Javascript
浅谈Vue下使用百度地图的简易方法
Mar 23 Javascript
vue富文本编辑器组件vue-quill-edit使用教程
Sep 21 Javascript
jQuery实现购物车的总价计算和总价传值功能
Nov 28 jQuery
优雅的将ElementUI表格变身成树形表格的方法步骤
Apr 11 Javascript
微信小程序实现图片选择并预览功能
Jul 25 Javascript
layui扩展上传组件模拟进度条的方法
Sep 23 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
人族 TERRAN 概述
2020/03/14 星际争霸
从C/C++迁移到PHP——判断字符类型的函数
2006/10/09 PHP
php数字转汉字代码(算法)
2011/10/08 PHP
仿Aspnetpager的一个PHP分页类代码 附源码下载
2012/10/08 PHP
PHP中trim()函数简单使用指南
2015/04/16 PHP
php基于curl扩展制作跨平台的restfule 接口
2015/05/11 PHP
php中smarty变量修饰用法实例分析
2015/06/11 PHP
微信红包随机生成算法php版
2016/07/21 PHP
php 提交表单 关闭layer弹窗iframe的实例讲解
2018/08/20 PHP
JS 显示当前日期与时间的代码
2010/03/24 Javascript
js css实现垂直方向自适应的三角提示菜单
2016/06/26 Javascript
微信小程序 实战实例开发流程详细介绍
2017/01/05 Javascript
javascript实现简易计算器
2017/02/01 Javascript
Vue.js上传图片到阿里云OSS存储的方法示例
2018/12/13 Javascript
详解Vue路由自动注入实践
2019/04/17 Javascript
vue实现多条件和模糊搜索功能
2019/05/28 Javascript
基于javascript实现贪吃蛇小游戏
2019/11/25 Javascript
[00:31]DOTA2上海特级锦标赛 Fnatic战队宣传片
2016/03/04 DOTA
python里大整数相乘相关技巧指南
2014/09/12 Python
基于进程内通讯的python聊天室实现方法
2015/06/28 Python
解决PySide+Python子线程更新UI线程的问题
2019/01/11 Python
Python实现个人微信号自动监控告警的示例
2019/07/03 Python
python获取网络图片方法及整理过程详解
2019/12/20 Python
GDAL 矢量属性数据修改方式(python)
2020/03/10 Python
python3 自动打印出最新版本执行的mysql2redis实例
2020/04/09 Python
鼠标滚轮事件和Mac触控板双指事件
2019/12/23 HTML / CSS
Mio Skincare美国官网:身体紧致及孕期身体护理
2017/03/05 全球购物
数据员岗位职责
2013/11/19 职场文书
入学生会自荐书范文
2014/02/05 职场文书
校园文明倡议书
2014/05/16 职场文书
班级文化建设标语
2014/06/23 职场文书
航海技术专业毕业生推荐信
2014/07/09 职场文书
学校师德师风自我剖析材料
2014/09/29 职场文书
2014教师评职称工作总结
2014/11/10 职场文书
德生TECSUN S-2000使用手册文字版
2022/05/10 无线电
flex布局中使用flex-wrap实现换行的项目实践
2022/06/21 HTML / CSS