基于js文件加载优化(详解)


Posted in Javascript onJanuary 03, 2018

在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。

js文件放置位置应该放置到body末尾

如果使用async的话,最后加上defer以求向下兼容

<script src="test.js" async defer></script> //如果两者都支持,async会默认覆盖掉defer
//如果只支持一个,则执行对应的即可

通常,我们使用的加载都是defer加载(因为很强的依赖关系).

以上这篇基于js文件加载优化(详解)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
一实用的实现table排序的Javascript类库
Sep 12 Javascript
js简单实现删除记录时的提示效果
Dec 05 Javascript
jQuery选择id属性带有点符号元素的方法
Mar 17 Javascript
通过javascript进行UTF-8编码的实现方法
Jun 27 Javascript
对js中回调函数的一些看法
Aug 29 Javascript
Mac下使用charles遇到的问题以及解决办法
Jan 10 Javascript
利用Javascript实现简单的转盘抽奖
Feb 13 Javascript
Vue.js搭建移动端购物车界面
Jun 28 Javascript
基于openlayers4实现点的扩散效果
Aug 17 Javascript
微信小程序仿美团城市选择
Jun 06 Javascript
vue与原生app的对接交互的方法(混合开发)
Nov 28 Javascript
three.js 利用uv和ThreeBSP制作一个快递柜功能
Aug 18 Javascript
jQuery 实现左右两侧菜单添加、移除功能
Jan 02 #jQuery
js 取消页面可以选中文字的功能方法
Jan 02 #Javascript
js阻止默认右键的下拉菜单方法
Jan 02 #Javascript
webpack实用小功能介绍
Jan 02 #Javascript
js最简单的双向绑定实例讲解
Jan 02 #Javascript
js 将canvas生成图片保存,或直接保存一张图片的实现方法
Jan 02 #Javascript
js原生方法被覆盖,从新赋值原生的方法
Jan 02 #Javascript
You might like
Bo-Blog专用的给Windows服务器的IIS Rewrite程序
2007/08/26 PHP
新安装的MySQL数据库需要注意的安全知识
2008/07/30 PHP
PHPMailer 中文使用说明小结
2010/01/22 PHP
用PHP书写安全的脚本代码
2012/02/05 PHP
PHP入门经历和学习过程分享
2014/04/11 PHP
php+mysql大量用户登录解决方案分析
2014/12/29 PHP
phpStorm2020 注册码
2020/09/17 PHP
JavaScript更改class和id的方法
2008/10/10 Javascript
基于Jquery的淡入淡出的特效基础练习
2010/12/13 Javascript
setInterval()和setTimeout()的用法和区别示例介绍
2013/11/17 Javascript
jQuery实现元素拖拽并cookie保存顺序的方法
2016/02/20 Javascript
基于JavaScript实现快速转换文本语言(繁体中文和简体中文)
2016/03/07 Javascript
js读取json文件片段中的数据实例
2017/03/09 Javascript
JavaScrip数组删除特定元素的几种方法总结
2017/09/06 Javascript
vue中实现滚动加载更多的示例
2017/11/08 Javascript
详解vue中axios的封装
2018/07/18 Javascript
Vue 第三方字体图标引入 Font Awesome的方法
2018/09/28 Javascript
JS异步宏队列微队列原理详解
2020/09/09 Javascript
[53:29]完美世界DOTA2联赛循环赛 DM vs Matador BO2第二场 11.04
2020/11/05 DOTA
python中常用的各种数据库操作模块和连接实例
2014/05/29 Python
python3抓取中文网页的方法
2015/07/28 Python
python 数据的清理行为实例详解
2017/07/12 Python
python如何去除字符串中不想要的字符
2020/07/05 Python
python使用梯度下降算法实现一个多线性回归
2020/03/24 Python
matplotlib jupyter notebook 图像可视化 plt show操作
2020/04/24 Python
Python标准库:内置函数max(iterable, *[, key, default])说明
2020/04/25 Python
基于python的opencv图像处理实现对斑马线的检测示例
2020/11/29 Python
Django 实现图片上传和下载功能
2020/12/31 Python
python实现录制全屏和选择区域录屏功能
2021/02/05 Python
英国百年闻名的优质健康产品连锁店:Holland & Barrett
2019/12/19 全球购物
应届大学生求职的自我评价
2013/11/17 职场文书
入党积极分子自我鉴定范文
2014/03/25 职场文书
学生未请假就回家检讨书
2014/09/22 职场文书
新手必备Python开发环境搭建教程
2021/05/28 Python
Python编解码问题及文本文件处理方法详解
2021/06/20 Python
详解Vue中$props、$attrs和$listeners的使用方法
2022/02/18 Vue.js