学习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中的window.location.search方法简介
Sep 02 Javascript
javascript:window.open弹出窗口的位置问题
Mar 18 Javascript
jQuery插件multiScroll实现全屏鼠标滚动切换页面特效
Apr 12 Javascript
javascript设计简单的秒表计时器
Sep 05 Javascript
jquery validate表单验证插件
Sep 06 Javascript
addEventListener()与removeEventListener()解析
Apr 20 Javascript
JavaScript静态作用域和动态作用域实例详解
Jun 17 Javascript
详解element-ui表格中勾选checkbox,高亮当前行
Sep 02 Javascript
vue使用prop可以渲染但是打印台报错的解决方式
Nov 13 Javascript
Vue组件通信中非父子组件传值知识点总结
Dec 05 Javascript
在JavaScript中实现链式调用的实现
Dec 24 Javascript
详解Vue的options
May 15 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
PHP 出现乱码和Sessions验证问题的解决方法!
2008/12/06 PHP
使用NetBeans + Xdebug调试PHP程序的方法
2011/04/12 PHP
关于php操作mysql执行数据库查询的一些常用操作汇总
2013/06/24 PHP
php不使用copy()函数复制文件的方法
2015/03/13 PHP
CI框架数据库查询缓存优化的方法
2016/11/21 PHP
解决laravel-admin 自己新建页面里 js 需要刷新一次的问题
2019/10/03 PHP
斜45度寻路实现函数
2009/08/20 Javascript
入门基础学习 ExtJS笔记(一)
2010/11/11 Javascript
js 代码优化点滴记录
2012/02/19 Javascript
javaScript arguments 对象使用介绍
2013/10/18 Javascript
利用js读取动态网站从服务器端返回的数据
2014/02/10 Javascript
原生JS和jQuery版实现文件上传功能
2016/04/18 Javascript
jQuery基于函数重载实现自定义Alert函数样式的方法
2016/07/27 Javascript
svg动画之动态描边效果
2017/02/22 Javascript
详解angular2实现ng2-router 路由和嵌套路由
2017/03/24 Javascript
微信小程序实现滑动删除效果
2017/05/19 Javascript
基于AngularJs select绑定数字类型的问题
2018/10/08 Javascript
layui实现二维码弹窗、并下载到本地的方法
2019/09/25 Javascript
Mac OS X10.9安装的Python2.7升级Python3.3步骤详解
2013/12/04 Python
Python 的内置字符串方法小结
2016/03/15 Python
PyTorch读取Cifar数据集并显示图片的实例讲解
2018/07/27 Python
pygame游戏之旅 创建游戏窗口界面
2018/11/20 Python
Python Pandas中根据列的值选取多行数据
2019/07/08 Python
python修改linux中文件(文件夹)的权限属性操作
2020/03/05 Python
Python3自定义http/https请求拦截mitmproxy脚本实例
2020/05/11 Python
CSS3美化表单控件全集
2016/06/29 HTML / CSS
CSS3实现10种Loading效果
2016/07/11 HTML / CSS
如何提高MySql的安全性
2014/06/19 面试题
销售实习自我鉴定
2013/12/07 职场文书
十岁生日同学答谢词
2014/01/19 职场文书
财务会计专业求职信
2014/06/09 职场文书
员工年终自我评价
2014/09/14 职场文书
大学生村官个人对照检查材料(群众路线)
2014/09/26 职场文书
代收款委托书范本
2014/10/01 职场文书
电子商务实训报告总结
2014/11/05 职场文书
2015年统计员个人工作总结
2015/07/23 职场文书