多个JS文件性能优化
页面中引入的JS文件是阻塞式加载的,这样会影响页面性能。以下是JS文件性能优化方法:
一:将所有的<script>标签放到页面底部,也就是</body>闭合标签之前,这能确保在脚本执行前页面完成了渲染
由于JS文件是阻塞式加载,当加载JS文件时,页面停止渲染,这样页面会出现不完整状态。将JS文件的<script>放在页面底部,这样能在加载JS文件时确保页面渲染完成。
二:尽可能的合并脚本文件。页面中<script>标签越少,加载也就越快,响应速度就越快。无论是外链脚本还是内嵌脚本都是如此。
通常一个大型网站或应用需要依赖多个JS文件。可以把多个文件合并成一个,这样只需要引用一个<script>标签,就可以减少性能消耗。文件合并的工作可通过离线的打包工具或者一些实时的
在线服务来实现。
注意:内嵌脚本放在引用的外链样式表的<link>之后会导致阻塞去等待样式表单下载。这样做事为了确保内嵌脚本在执行时能获得最精确的样式信息。因此,建议不要把内嵌脚本紧跟在<link>标签后面
三:采用无阻塞下载JS脚本的方法。
较少JS文件大小并限制HTTP请求数在功能丰富的WEB应用或大型网站上并不是总可行。WEB应用的功能越丰富,所需要的JS代码就越多,尽管下载单个较大的JS文件只产生一个HTTP请求,却会锁死浏览器的一大段时间。为避免这种情况,需要通过一些特定的技术向页面中逐步加载JS文件,这样做在某种程度上说不会阻塞浏览器。
无阻塞加载脚本的本质:在页面加载完成后才加载JS代码。这就意味着在window.onload事件触发后再下载脚本。实现方法:
1.延迟加载脚本:
HTML4为<script>标签定义了一个扩展属性:defer。但defer属性只被IE4和FireFox3.5更高版本的浏览器支持。所以不是一个跨浏览器解决方案。在其他浏览器中,defer直接被忽略,JS文件仍会造成阻塞。如果浏览器支持defer属性,可以这样写:
<script type="text/javascript" src="script1.js" defer></script>
带有defer属性的<script>标签可以放置在文档的任何位置。对应的JS文件将在页面解析到<script>标签时开始下载,但不会执行。直到DOM加载完成,即onload事件触发前才会执行。
当带有defer属性的JS文件下载时,不会阻塞浏览器的其他进程,因此这类文件可以与其他资源文件一起下载。
<html>
<head>
<title>Script Defer Example</title>
</head>
<body>
<script type="text/javascript" defer>
alert("defer");
</script>
<script type="text/javascript">
alert("script");
</script>
<script type="text/javascript">
window.onload = function(){
alert("load");
};
</script>
</body>
</html>
不支持 defer
属性的浏览器的弹出顺序是:“defer”、“script”、“load”。而在支持 defer
属性的浏览器上,弹出的顺序则是:“script”、“defer”、“load”。请注意,带有 defer
属性的<script>
元素不是跟在第二个后面执行,而是在 onload
事件被触发前被调用。
2.异步加载JS文件:async属性:使用所有浏览器
HTML5为<script>标签定义了一个新的扩展属性:async。作用和defer一样,能够异步加载和执行脚本,不因为加载脚本而阻塞页面渲染。但是:使用async,JS脚本一旦下载好了就好执行,所以很有可能不是按照原本的顺序来执行。如果JS脚本前后有依赖性,使用async和有可能会出错。
<script type="text/javascript" src="script1.js" async="true"></script>
四:动态脚本元素
文档对象模型(DOM)允许您使用 JavaScript 动态创建 <script>
元素。
var script = document.createElement ("script");
script.type = "text/javascript";
script.src = "script1.js";
document.getElementsByTagName("head")[0].appendChild(script);
新的<script>元素加载script1.js源文件。此文件当元素添加到页面之后会立刻开始下载。技术重点:无论在何处启动下载,文件的下载和运行都不会阻塞其他页面处理过程。可以将这些代码放在<head>部分而不会对其余部分的页面代码造成影响(除了用于下载文件的HTTP连接)。
当文件使用动态脚本节点下载时,返回的代码通常是立即执行(除了FireFox和Opera,他们讲等待此前的所有动态脚本执行完毕)。当脚本是“自运行”类型时,这一机制运行正常。但是如果脚本只包含供页面其他脚本调用的接口,则会带来问题。这种情况下,您需要跟踪脚本下载完成是否准备妥善,可以使用动态<script>节点发出事件得到相关信息。
新的<script>
元素加载 script1.js 源文件。此文件当元素添加到页面之后立刻开始下载。此技术的重点在于:无论在何处启动下载,文件的下载和运行都不会阻塞其他页面处理过程。您甚至可以将这些代码放在<head>
部分而不会对其余部分的页面代码造成影响(除了用于下载文件的 HTTP 连接)。
Firefox、Opera, Chorme 和 Safari 3+会在<script>
节点接收完成之后发出一个 onload
事件。您可以监听这一事件,以得到脚本准备好的通知:
var script = document.createElement ("script")
script.type = "text/javascript"; //Firefox, Opera, Chrome, Safari 3+
script.onload = function(){
alert("Script loaded!");
}; script.src = "script1.js";
document.getElementsByTagName("head")[0].appendChild(script);
Internet Explorer 支持另一种实现方式,它发出一个 readystatechange
事件。<script>
元素有一个 readyState
属性,它的值随着下载外部文件的过程而改变。readyState
有五种取值:
- “uninitialized”:默认状态
- “loading”:下载开始
- “loaded”:下载完成
- “interactive”:下载完成但尚不可用
- “complete”:所有数据已经准备好
微软文档上说,在<script>
元素的生命周期中,readyState
的这些取值不一定全部出现,但并没有指出哪些取值总会被用到。实践中,我们最感兴趣的是“loaded”和“complete”状态。Internet Explorer 对这两个 readyState
值所表示的最终状态并不一致,有时<script>
元素会得到“loader”却从不出现“complete”,但另外一些情况下出现“complete”而用不到“loaded”。最安全的办法就是在 readystatechange
事件中检查这两种状态,并且当其中一种状态出现时,删除 readystatechange
事件句柄(保证事件不会被处理两次):
var script = document.createElement("script")
script.type = "text/javascript"; //Internet Explorer
script.onreadystatechange = function(){
if (script.readyState == "loaded" || script.readyState == "complete"){
script.onreadystatechange = null;
alert("Script loaded.");
}
}; script.src = "script1.js";
document.getElementsByTagName("head")[0].appendChild(script);
注意:大多数情况下,您希望调用一个函数就可以实现 JavaScript 文件的动态加载。下面的函数封装了标准实现和 IE 实现所需的功能:通过函数进行封装
function loadScript(url, callback){
var script = document.createElement ("script")
script.type = "text/javascript";
if (script.readyState){ //IE
script.onreadystatechange = function(){
if (script.readyState == "loaded" || script.readyState == "complete"){
script.onreadystatechange = null;
callback();
}
};
} else { //Others
script.onload = function(){
callback();
};
}
script.src = url;
document.getElementsByTagName("head")[0].appendChild(script);
}
loadScript("script1.js", function(){
alert("File is loaded!");
});
在页面中动态加载很多 JavaScript 文件,但要注意,浏览器不保证文件加载的顺序。所有主流浏览器之中,只有 Firefox 和 Opera 保证脚本按照您指定的顺序执行。其他浏览器将按照服务器返回它们的次序下载并运行不同的代码文件。但是可以将下载操作串联在一起以保证他们的次序,如下:
loadScript("script1.js", function(){
loadScript("script2.js", function(){
loadScript("script3.js", function(){
alert("All files are loaded!");
});
});
});
此代码等待 script1.js 可用之后才开始加载 script2.js,等 script2.js 可用之后才开始加载 script3.js。虽然此方法可行,但如果要下载和执行的文件很多,还是有些麻烦。如果多个文件的次序十分重要,更好的办法是将这些文件按照正确的次序连接成一个文件。独立文件可以一次性下载所有代码(由于这是异步进行的,使用一个大文件并没有什么损失)。
动态脚本加载是非阻塞 JavaScript 下载中最常用的模式,因为它可以跨浏览器,而且简单易用。
五:使用 XMLHttpRequest(XHR)对象
此技术首先创建一个 XHR 对象,然后下载 JavaScript 文件,接着用一个动态 <script>
元素将 JavaScript 代码注入页面。
var xhr = new XMLHttpRequest();
xhr.open("get", "script1.js", true);
xhr.onreadystatechange = function(){
if (xhr.readyState == 4){
if (xhr.status >= 200 && xhr.status < 300 || xhr.status == 304){
var script = document.createElement ("script");
script.type = "text/javascript";
script.text = xhr.responseText;
document.body.appendChild(script);
}
}
};
xhr.send(null);
方法的主要优点是,可以下载不立即执行的 JavaScript 代码。由于代码返回在<script>
标签之外(换句话说不受<script>
标签约束),它下载后不会自动执行,这使得您可以推迟执行,直到一切都准备好了。另一个优点是,同样的代码在所有现代浏览器中都不会引发异常。
此方法最主要的限制是:JavaScript 文件必须与页面放置在同一个域内,不能从 CDN 下载(CDN 指"内容投递网络(Content Delivery Network)",所以大型网页通常不采用 XHR 脚本注入技术。
多个JS文件性能优化的更多相关文章
- Babylon.js官方性能优化文档中文翻译
在这里列出Babylon.js官方性能优化文档的中英文对照,并在CardSimulate项目里对其中的一些优化方法进行实践. How To 如何 Optimize your scene 优化你的场景 ...
- [Ext JS 4]性能优化
一般的优化技巧 1. 检查你定义的时间监听器 正确的设置事件监听器对性能会有很大的影响. 举例来说, 在定义一个store的时候,设置一个load 的事件去触发从后台读取数据,如果设置single 的 ...
- JS 之性能优化(2)
继续上一篇的JS性能优化之后,下面接着讲关于前端性能优化的内容.如果有不对的地方欢迎纠正. 1.避免过多的重排与重绘操作. 尽量将DOM中的多个读操作放一起,中间不要插入写的操作,因为写操作会导致浏览 ...
- JS 之性能优化(1)
了解JS性能优化是学习前端必备的一项技能.下面就简单的列出几点: 1.注意作用域,避免全局查找. 访问全局变量比访问局部变量慢,是因为需要遍历作用域链,查找作用域链需要额外的时间.所以在一个函数中,将 ...
- js前端性能优化之函数节流和函数防抖
前言:针对一些会频繁触发的事件如scroll.resize,如果正常绑定事件处理函数的话,有可能在很短的时间内多次连续触发事件,十分影响性能 节流: 节流:使得一定时间内只触发一次函数. 它和防抖动最 ...
- [js] 前端性能优化
原文链接:http://www.cnblogs.com/xxcanghai/p/5205998.html 链接:http://www.zhihu.com/question/21658448/answe ...
- js代码性能优化的几个方法
相信写代码对于大部分人都不难,但想写出高性能的代码就需要一定的技术积累啦,下面是一些优化JavaScript代码性能的常见方法. 一.注意作用域 1.避免全局查找 使用全局变量和函数肯定要比局部的开销 ...
- JS性能优化笔记搜索整理
通过网上查找资料了解关于性能优化方面的内容,现简单整理,仅供大家在优化的过程中参考使用,如有什么问题请及时提出,再做出相应的补充修改. 一. 让代码简洁:一些简略的表达方式也会产生很好的优化 eg:x ...
- Ext.js性能优化漫谈
Ext.js是一个用于建立企业级应用的纯JS框架.毫无疑问,它为我们提供了大量的组件,比如container,panel,field,grid,这些组件使用起来很方便,不需要去写js和html,但是e ...
随机推荐
- MyBatis-Spring-Boot 使用总结
接 MyBatis-Spring 使用总结 . mybatis开发团队为Spring Boot 提供了 MyBatis-Spring-Boot-Starter . 首先,MyBatis-Sprin ...
- 【cf490】D. Chocolate(素数定理)
http://codeforces.com/contest/490/problem/D 好神的一题,不会做.. 其实就是将所有的质因子找出来,满足: 最终的所有质因子的乘积相等 但是我们只能操作质因子 ...
- JBPM4.4_工作流基础_准备jBPM4.4环境
1. 工作流基础 1.1. 工作流相关概念 工作流(Workflow),就是“业务过程的部分或整体在计算机应用环境下的自动化”,它主要解决的是“使在多个参与者之间按照某种预定义的规则传递文档.信息或任 ...
- SharePoint PerformancePoint开发实例
前言 由于工作的原因,有一段时间没有发新的随笔了,最近使用了SharePoint PerformancePoint做了一些报表,与大家分享经验. 本文完全原创,转载请说明出处,希望对大家有用. 阅读目 ...
- PowerDesigner概念模型与物理模型相互转换及导出数据字典
最近公司项目竣工,验收完成后,把整体平台的所有文档都写清楚,找包发给甲方,由于本人是维护数据库工作,依上面要求,必须编写<数据库设计说明书>里面格式包含三个部分:概念模型.物理模型.数据字 ...
- 【Python算法】哈希存储、哈希表、散列表原理
哈希表的定义: 哈希存储的基本思想是以关键字Key为自变量,通过一定的函数关系(散列函数或哈希函数),计算出对应的函数值(哈希地址),以这个值作为数据元素的地址,并将数据元素存入到相应地址的存储单元中 ...
- Using the FutureRequestExecutionService Based on classic (blocking) I/O handle a great number of concurrent connections is more important than performance in terms of a raw data throughput
Chapter 7. Advanced topics http://hc.apache.org/httpcomponents-client-ga/tutorial/html/advanced.html ...
- Python笔记-进程Process、线程Thread、上锁
1.对于操作系统来说,一个任务就是一个进程(Process).比如打开一个浏览器就是启动一个浏览器进程,打开一个记事本就启动了一个记事本进程. 2.在一个进程内部,要同时干多件事,就需要同时运行多个“ ...
- Systemd mysql,nginx,php启动配置文件
systemctl的配置文件目录一般在 /usr/lib/systemd/system/ 或者/etc/systemd/system/ 需要注意的是,nginx与php运行用户必须是root,所以不需 ...
- Spring Data CrudRepository增删改查方法(八)
CrudRepository 的主要方法 long count(); boolean exists(Integer arg0); <S extends StudentPO> S sav ...