学习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 相关文章推荐
Javascript实例教程(19) 使用HoTMetal(2)
Dec 23 Javascript
关于图片验证码设计的思考
Jan 29 Javascript
前台js调用后台方法示例
Dec 02 Javascript
JQuery的Ajax请求实现局部刷新的简单实例
Feb 11 Javascript
js中一维数组和二位数组中的几个问题示例说明
Jul 17 Javascript
[原创]推荐10款最热门jQuery UI框架
Aug 19 Javascript
javascript记录文本框内文字个数检测文字个数变化
Oct 14 Javascript
Bootstrap每天必学之按钮(Button)插件
Apr 25 Javascript
Angular外部使用js调用Angular控制器中的函数方法或变量用法示例
Aug 05 Javascript
ajax接收后台数据在html页面显示
Feb 19 Javascript
Vue2.0如何发布项目实战
Jul 27 Javascript
Vue作用域插槽实现方法及作用详解
Jul 08 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
利用curl 多线程 模拟 并发的详解
2013/06/14 PHP
使用GD库生成带阴影文字的图片
2015/03/27 PHP
在html文件中也可以执行php语句的方法
2015/04/09 PHP
PHP dirname功能及原理实例解析
2020/10/28 PHP
使用TextRange获取输入框中光标的位
2006/10/14 Javascript
Extjs4中的分页应用结合前后台
2013/12/13 Javascript
javascript版2048小游戏
2015/03/18 Javascript
jquery实现具有收缩功能的垂直导航菜单
2016/02/16 Javascript
JavaScript函数柯里化详解
2016/04/29 Javascript
Ext JS框架程序中阻止键盘触发回退或者刷新页面的代码分享
2016/06/07 Javascript
一个极为简单的requirejs实现方法
2016/10/20 Javascript
JavaScript实现图像模糊化的方法实例
2017/01/15 Javascript
MUI实现上拉加载和下拉刷新效果
2017/06/30 Javascript
jQuery实现全选、反选和不选功能
2017/08/16 jQuery
详解Nodejs内存治理
2018/05/13 NodeJs
微信小程序从注册账号到上架(图文详解)
2019/07/17 Javascript
javascript中undefined的本质解析
2019/07/31 Javascript
React路由鉴权的实现方法
2019/09/05 Javascript
layui自定义工具栏的方法
2019/09/19 Javascript
[39:02]DOTA2亚洲邀请赛 3.31 小组赛 B组 Mineski vs VGJ.T
2018/04/01 DOTA
Python urllib模块urlopen()与urlretrieve()详解
2013/11/01 Python
python+mysql实现简单的web程序
2014/09/11 Python
深入浅析python继承问题
2016/05/29 Python
Django读取Mysql数据并显示在前端的实例
2018/05/27 Python
基于Python List的赋值方法
2018/06/23 Python
Python pymsql模块的使用
2020/09/07 Python
html5教程实现Photoshop渐变色效果
2013/12/04 HTML / CSS
会计系毕业个人自荐信格式
2013/09/23 职场文书
写给老婆的检讨书
2014/02/21 职场文书
党员承诺书内容
2014/03/26 职场文书
党员批评与自我批评发言材料
2014/10/14 职场文书
教师党的群众路线学习心得体会
2014/11/04 职场文书
患者身份识别制度
2015/08/06 职场文书
小学学习委员竞选稿
2015/11/20 职场文书
创业计划之特色精品店
2019/08/12 职场文书
pytorch加载预训练模型与自己模型不匹配的解决方案
2021/05/13 Python