高性能的javascript之加载顺序与执行原理篇


Posted in Javascript onJanuary 14, 2018

前言

javascript在浏览器中的性能,可以认为是开发者所面临的最严重的可用性问题,今天,自己看完高性能的javascript的加载和执行这一章,聊聊怎么解决js的加载顺序和执行的原理,下面话不多说了,来一起看看详细的介绍:

高性能的javascript之加载顺序与执行原理篇

当浏览器遇到<script>标签的时候,浏览器必须先话时间下载外链的文件然后并执行,在这过程中,页面渲染和用户交互是完全被阻塞的。

脚本放在哪里比较好?

高性能的javascript之加载顺序与执行原理篇

这种情况无疑是存在严重的性能问题的,由于脚本会阻塞页面的渲染,直到它们全部下载并执行完成后,页面渲染才会继续,下面的图就是代码的执行顺序

高性能的javascript之加载顺序与执行原理篇

第一个js文件下载,要等到第一个js文件下载完全才会执行第二个js文件,不过现在IE8,Firefox3.5,Safari4和Chrome2都允许并行下载js文件,遗憾的是,js下载过程还是会阻塞其他资源的下载,例如:图片

所以提高性能的方法之一:将脚本放在body底部

高性能的javascript之加载顺序与执行原理篇

组织脚本

由于每个<script>标签下载时都会阻塞页面的渲染,所以减少页面包含的<script>标签数量是必不可少的,解决方法:可以把多个js文件合并打包成一个js文件,这样子做的好处就是可以最小化延迟时间将会明显的改善页面的总体性能,除此之外,还可以减少HTTP的请求。

一般来说下载单个100KB的文件比下载4个25KB的文件快。

如果有多个外链的js文件,可以合并成一个js文件

高性能的javascript之加载顺序与执行原理篇

无阻塞的脚本

尽管下载单个较大的js文件只产生一次HTTP的请求,但是会假死浏览器一大段时间,为了避免这种情况,你需要向页面中逐步加载js文件。

延迟的脚本

defer属性指明本元素所含的脚本可以延迟执行,但是只有IE4+和Firefox3.5+的浏览器支持

高性能的javascript之加载顺序与执行原理篇

简单来说defer的机制就是知道DOM加载完成前才去下载js文件,不会阻塞浏览器的其他进程

高性能的javascript之加载顺序与执行原理篇

在不支持defer属性的浏览器弹出的顺序是:defer,script,load

支持defer属性的浏览器弹出的顺序是:script,defer,load

所以说defer是在onload事件执行之前被调用

动态脚本

动态脚本的注入有两种方式,第一就是动态创建script标签,第二就是通过XMLHttpRequest注入页面

先说说第一种怎么使用:

高性能的javascript之加载顺序与执行原理篇

这种技术的重点在于:无论在何时启动下载,文件的下载和执行过程不会阻塞页面其他进程,但是使用动态脚本节点下载js文件时,返回的代码会立即执行(除了Firefox和Opera,它们会等待此前所有动态脚本节点执行完毕)

在主流的浏览器会在<script>标签接收完成时触发一个load事件,但是ie浏览器没有,所以我们必须封装一个兼容所有的浏览器都可以使用的方法

高性能的javascript之加载顺序与执行原理篇

这种方式的缺点就是要清楚文件的加载顺序,当js文件多了,依赖关系复杂的时候,很难管理加载的依赖顺序

高性能的javascript之加载顺序与执行原理篇

就像这样子写的代码很难维护

第二种动态创建脚本方式

高性能的javascript之加载顺序与执行原理篇

实际上相当于创建一个带有内联脚本的<script>标签,一旦新创建的<script>元素被添加到页面,代码就会立即执行然后准备就绪。

优点:就是下载的js代码但是不立即执行,这样子可以把脚本的执行推迟到你准备好的时候执行,这种方法还可以兼容所有的浏览器

缺点:js文件必须与所请求的页面处于相同的域,js文件不能从CDN下载,一般大型web应用都不会使用这种方式

推荐使用无阻塞模式:

先添加动态所需的代码,然后假装初始化页面的剩下的代码

[图片上传失败...(image-dd3f9-1515902024710)]

上面介绍了那么多,给大家推荐一些动态延迟加载的库

有YUI3,LazyLoad和LABjs等这些库,个人觉得LABjs库比较好用,但是没有用过,大家可以去了解一下,使用方法就不在这里说了。

总结:

提高js性能的几个方面

      1.</body>闭合标签之前,将所有的<script>标签放到页面底部。这能确保在脚本执行前页面已经完成了渲染

      2.合并脚本。页面中的<script>标签越少,加载也就越快,响应也更快。无论外链文件还是内嵌脚本都是如此

      3.有多种无阻塞下载js的方法

            3.1使用<script>标签的defer属性

            3.2使用动态创建的<script>元素来下载并执行代码

            3.3使用XHR对象下载js代码并注入页面中

通过以上策略,可以极大提高那些需要使用大量js的web应用的实际性能

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
获取页面高度,窗口高度,滚动条高度等参数值getPageSize,getPageScroll
Sep 22 Javascript
jQuery第三课 修改元素属性及内容的代码
Mar 14 Javascript
由JavaScript技术实现的web小游戏(不含网游)
Jun 12 Javascript
textarea不能通过maxlength属性来限制字数的解决方法
Sep 01 Javascript
JavaScript实现信用卡校验方法
Apr 07 Javascript
简单对比分析JavaScript中的apply,call与this的使用
Dec 04 Javascript
BootStrap智能表单实战系列(三)分块表单配置详解
Jun 13 Javascript
js跨域资源共享 基础篇
Jul 02 Javascript
瀑布流的实现方式(原生js+jquery+css3)
Jun 28 Javascript
jQuery实现的简单日历组件定义与用法示例
Dec 24 jQuery
ES10 特性的完整指南小结
Mar 04 Javascript
vue中使用极验验证码的方法(附demo)
Dec 04 Javascript
关于axios如何全局注册浅析
Jan 14 #Javascript
Vue+Flask实现简单的登录验证跳转的示例代码
Jan 13 #Javascript
react-redux中connect的装饰器用法@connect详解
Jan 13 #Javascript
基于vue实现网站前台的权限管理(前后端分离实践)
Jan 13 #Javascript
详解webpack-dev-server使用http-proxy解决跨域问题
Jan 13 #Javascript
vuejs实现递归树型菜单组件
Jan 13 #Javascript
在vue中通过axios异步使用echarts的方法
Jan 13 #Javascript
You might like
Pain 全世界最小最简单的PHP模板引擎 (普通版)
2011/10/23 PHP
PHP 只允许指定IP访问(允许*号通配符过滤IP)
2014/07/08 PHP
PHP错误Warning: Cannot modify header information - headers already sent by解决方法
2014/09/27 PHP
SAE实时日志接口SDK用法示例
2016/10/09 PHP
PHP面向对象程序设计(OOP)之方法重写(override)操作示例
2018/12/21 PHP
php源码的使用方法讲解
2019/09/26 PHP
PhpStorm 如何优雅的调试Hyperf的方法步骤
2019/11/24 PHP
javascript 屏蔽鼠标键盘的几段代码
2008/01/02 Javascript
AppBaseJs 类库 网上常用的javascript函数及其他js类库写的
2010/03/04 Javascript
浅析XMLHttpRequest的缓存问题
2013/12/13 Javascript
JavaScript定义类和对象的方法
2014/11/26 Javascript
使用Chart.js图表库制作漂亮的响应式表单
2015/10/28 Javascript
关于JavaScript限制字数的输入框的那些事
2016/08/14 Javascript
修改Jquery Dialog 位置的实现方法
2016/08/26 Javascript
javascript动画之磁性吸附效果篇
2016/12/09 Javascript
Bootstrap3 多选和单选框(checkbox)
2016/12/29 Javascript
JavaScript切换搜索引擎的导航网页搜索框实例代码
2017/06/11 Javascript
如何构建 vue-ssr 项目的方法步骤
2020/08/04 Javascript
[02:37]2015国际邀请赛选手档案—LGD.Xiao8
2015/07/28 DOTA
Python错误提示:[Errno 24] Too many open files的分析与解决
2017/02/16 Python
Python实现随机生成有效手机号码及身份证功能示例
2017/06/05 Python
Python使用Matplotlib实现雨点图动画效果的方法
2017/12/23 Python
Python抓取聚划算商品分析页面获取商品信息并以XML格式保存到本地
2018/02/23 Python
python的一些加密方法及python 加密模块
2019/07/11 Python
python用win32gui遍历窗口并设置窗口位置的方法
2019/07/26 Python
Canvas多边形绘制的实现方法
2019/08/05 HTML / CSS
Under Armour安德玛中国官网:美国高端运动科技品牌
2018/03/09 全球购物
英国在线药房:Chemist.co.uk
2019/03/26 全球购物
Notino瑞典:购买香水和美容产品
2019/07/26 全球购物
英语专业毕业生自我鉴定
2013/11/09 职场文书
会计工作心得体会
2014/01/13 职场文书
关于责任的演讲稿
2014/05/20 职场文书
民事授权委托书范文
2014/08/02 职场文书
大三学生学年自我鉴定
2014/09/12 职场文书
2016元旦文艺汇演主持词
2015/07/06 职场文书
Go各时间字符串使用解析
2021/04/02 Golang