学习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 相关文章推荐
关于图片验证码设计的思考
Jan 29 Javascript
JavaScript 异步调用框架 (Part 1 - 问题 &amp; 场景)
Aug 03 Javascript
基于JQuery的访问WebService的代码(可访问Java[Xfire])
Nov 19 Javascript
使用js判断TextBox控件值改变然后出发事件
Mar 07 Javascript
JavaScript实现图片轮播组件代码示例
Nov 22 Javascript
javascript删除html标签函数cIsHTML
Jan 09 Javascript
jquery中绑定事件的异同
Feb 28 Javascript
Vue中render方法的使用详解
Jan 26 Javascript
vue-cli中的babel配置文件.babelrc实例详解
Feb 22 Javascript
JavaScript实现JSON合并操作示例【递归深度合并】
Sep 07 Javascript
jQuery实现数字自动增加或者减少的动画效果示例
Dec 11 jQuery
JavaScript中的执行环境和作用域链
Sep 04 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
自己动手做一个SQL解释器
2006/10/09 PHP
在win7中搭建Linux+PHP 开发环境
2014/10/08 PHP
php实现获取文章内容第一张图片的方法
2014/11/04 PHP
是 WordPress 让 PHP 更流行了 而不是框架
2016/02/03 PHP
PHP简单实现文本计数器的方法
2016/04/28 PHP
浅析PHP开发规范
2018/02/05 PHP
jquery序列化表单去除指定元素示例代码
2014/04/10 Javascript
jquery右下角自动弹出可关闭的广告层
2015/05/08 Javascript
Easyui form combobox省市区三级联动
2016/01/13 Javascript
jQuery实现图片局部放大镜效果
2016/03/17 Javascript
基于BootStrap Metronic开发框架经验小结【七】数据的导入、导出及附件的查看处理
2016/05/12 Javascript
jQuery web 组件 后台日历价格、库存设置的代码
2016/10/14 Javascript
AngularJS中isolate scope的用法分析
2016/11/22 Javascript
基于jQuery实现无缝轮播与左右点击效果
2018/05/13 jQuery
关于TypeScript模块导入的那些事
2018/06/12 Javascript
web.py获取上传文件名的正确方法
2014/08/26 Python
Python转换HTML到Text纯文本的方法
2015/01/15 Python
Python中subprocess模块用法实例详解
2015/05/20 Python
Python解决抛小球问题 求小球下落经历的距离之和示例
2018/02/01 Python
Python装饰器原理与简单用法实例分析
2018/04/29 Python
python清除字符串前后空格函数的方法
2018/10/21 Python
python内存动态分配过程详解
2019/07/15 Python
python日志模块logbook使用方法
2019/09/19 Python
css3动画鼠标放上图片逐渐变大鼠标离开图片逐渐缩小效果
2021/01/27 HTML / CSS
Html5无刷新修改browser Url的方法
2014/01/15 HTML / CSS
html5跳转小程序wx-open-launch-weapp踩坑
2020/12/02 HTML / CSS
大学生毕业自我鉴定
2013/11/06 职场文书
我的求职计划书
2014/01/10 职场文书
火锅店营销方案
2014/02/26 职场文书
赔偿协议书范本
2014/09/12 职场文书
2014最新实习证明模板
2014/10/02 职场文书
2014年乡镇团委工作总结
2014/12/18 职场文书
贷款承诺书
2015/01/20 职场文书
2015年小学辅导员工作总结
2015/05/27 职场文书
python3使用diagrams绘制架构图的步骤
2021/04/08 Python
解决IIS7下无法绑定https主机的问题
2022/04/29 Servers