做项目的过程中出现了一些性能问题,所以在网上找了一些资源来解决这个问题,写出来记录一下。
本文章内容是转载过来的,供大家讨论学习,共两篇:
如何更快速加载你的JS页面
JavaScript现在极其重要。一些网站使用JavaScript来增添魅力,如今的许多Web应用程序依赖它,其中一些甚至是完全用JavaScript编写而成的。我在本文中将指出一些重要的规则,介绍如何使用你的JavaScript、使用哪些工具以及你将从中得到什么好处。
确保代码尽量简洁
不要什么都依赖JavaScript。不要编写重复性的脚本。要把JavaScript当作糖果工具,只是起到美化作用。别给你的网站添加大量的JavaScript代码。只有必要的时候用一下。只有确实能改善用户体验的时候用一下。
尽量减少DOM访问
使用JavaScript访问DOM元素很容易,代码更容易阅读,但是速度很慢。下面介绍几个要点:限制使用JavaScript来修饰网页布局,把针对访问元素的引用缓存起来。有时,当你的网站依赖大量的DOM改动时,就应该考虑限制你的标记。这是改用HTML5、舍弃那些原来的XHTML和HTML4的一个充分理由。你可以查看DOM元素的数量,只要在Firebug插件的控制台中输入:document.getElementsByTagName('*').length。
压缩代码
要提供经过压缩的JavaScript页面,最有效的办法就是先用JavaScript压缩工具对你的代码压缩一下,这种压缩工具可以压缩变量和参数名称,然后提供因而获得的代码,使用了gzip压缩。
是的,我没有压缩我的main.js,但你要检查有没有未经压缩的任何jQuery插件,别忘了压缩。下面我列出了压缩方面的几个方案。
YUI压缩工具(我的最爱,jQuery开发团队就使用它),初学者指南(http://www.slideshare.net/nzakas/extreme-JavaScript-compression-with-yui-compressor)、第二指南 (http://vilimpoc.org/research/js-speedup/)和官方网站(http://developer.yahoo.com/yui/compressor/)。
Dean Edwards Packer(http://dean.edwards.name/packer/)
JSMin(http://crockford.com/JavaScript/jsmin)
GZip压缩:其背后的想法是,缩短在浏览器和服务器之间传送数据的时间。缩短时间后,你得到标题是Accept-Encoding: gzip,deflate的一个文件。不过这种压缩方法有一些缺点。它在服务器端和客户端都要占用处理器资源(以便压缩和解压缩),还要占用磁盘空间。
避免eval():虽然有时eval()会在时间方面带来一些效率,但使用它绝对是错误的做法。eval()导致你的代码看起来更脏,而且会逃过大多数压缩工具的压缩。
加快JavaScript装入速度的工具:Lab.js
有许多出色的工具可以加快JavaScript装入的速度。值得一提的一款工具是Lab.js。
借助LAB.js(装入和阻止JavaScript),你就可以并行装入JavaScript文件,加快总的装入过程。此外,你还可以为需要装入的脚本设置某个顺序,那样就能确保依赖关系的完整性。此外,开发者声称其网站上的速度提升了2倍。
使用适当的CDN
现在许多网页使用内容分发网络(CDN)。它可以改进你的缓存机制,因为每个人都可以使用它。它还能为你节省一些带宽。你很容易使用ping检测或使用Firebug调试那些服务器,以便搞清可以从哪些方面加快数据的速度。选择CDN时,要照顾到你网站那些访客的位置。记得尽可能使用公共存储库。
面向jQuery的几个CDN方案:
http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js——谷歌Ajax,关于更多库的信息请参阅http://code.google.com/apis/libraries/devguide.html#Libraries。
http://ajax.microsoft.com/ajax/jquery/jquery-1.4.2.min.js——微软的CDN
http://code.jquery.com/jquery-1.4.2.min.js——Edgecast (mt)。
网页末尾装入JavaScript
如果你关注用户,用户因互联网连接速度慢而没有离开你的网页,这是一个非常好的做法。易用性和用户放在首位,JavaScript放在末位。这也许很痛苦,但是你应该有所准备,有些用户会禁用JavaScript。可以在头部分放置需要装入的一些JavaScript,但是前提是它以异步方式装入。
异步装入跟踪代码
这一点非常重要。我们大多数人使用谷歌分析工具(Google Analytics)来获得统计数据。这很好。现在看一下你把你的跟踪代码放在哪里。是放在头部分?还是说它使用document.write?然后,如果你没有使用谷歌分析工具异步跟踪代码,那也只能怪你自己。
这就是谷歌分析工具异步跟踪代码的样子。我们必须承认,它使用DOM,而不是使用document.write,这可能更适合你。它可以在网页装入之前检测到其中一些事件,这非常重要。现在想一想这种情况,你的网页甚至还没有装入,所有用户都关闭了网页。已找到了解决页面浏览量错失的办法。
_gaq.push(['_setAccount', 'UA-XXXXXXX-XX']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/JavaScript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') +
'.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
没有使用谷歌分析工具?这不是问题,今天的分析工具提供商大多允许你使用异步跟踪。
Ajax优化
Ajax请求对你网站的性能有重大影响。下面我介绍关于Ajax优化的几个要点。
缓存你的ajax
先看一下你的代码。你的ajax可以缓存吗?是的,它依赖数据,但是你的ajax请求大多应该可以缓存。在jQuery中,你的请求在默认情况下已被缓存,不包括script和jsonp数据类型。
针对Ajax请求使用GET
POST类型请求要发送两个TCP数据包(先发送标题,然后发送数据)。GET类型请求只需要发送一个数据包(这可能取决于你的cookie数量)。所以,当你的URL长度不到2K,你又想请求一些数据时,不妨使用GET。
使用ySlow
说到性能,ySlow既简单,又极其有效。它可以对你的网站进行评分,显示哪些方面需要改正,以及应关注哪些方面。
另外支一招:把你的JavaScript打包成PNG文件
设想一下:把你的JS和CSS添加到图片的末尾,然后用CSS来裁切,通过一次HTTP请求来获得应用程序中所需的所有信息。
我最近找到了这个方法。它基本上把你的JavaScript/css数据打包成PNG文件。之后,你可以拆包,只要使用画布API的getImageData()。此外,它非常高效。你可以在不缩小数据的情况下,多压缩35%左右。而且是无损压缩!我得指出,对比较庞大的脚本来说,在图片指向画布、读取像素的过程中,你会觉得有“一段”装入时间。
以上转载自:http://www.helloweba.com/view-blog-170.html
关于js对页面加载影响的测试
这两天在处理一个小需求,目的是当用户页面里引入一段外部js(外部js由内部生成,用户手动添加),然后根据外部js提供参数回调不同的js文件和方法(js文件和方法未知,由参数传递),回调的js文件异步在客户的页面里加载,目前已实现基本功能,之所以这么做就是为了尽可能的减小外部js对客户页面加载效率的影响。
事实上目前接触到公司的产品中也遇到了这种情况,页面里因为有较多的辅助功能而引入了比较多的js文件,本地测试开发的话基本看不出对页面加载的影响,但是在模拟的较差网络环境下页面瞬间空白的出现时间有点超过预期,虽然不仅仅是那些js文件造成的加载白屏现象,但是过多js零碎文件的引入任然拖慢了页面的加载速度,目前建议使用$LABjs管理和Combo脚本文件来优化。
鉴于这个小需求又想到了js对大型网站页面加载的影响条件,下面根据不同的情况做了不同的对比,已经尽可能的模拟同等条件下的载入效果,展示上会略有不同,已经取了平均值,数据还算是比较可靠。
第一种方式:js文件在页面元
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title></title>
<script type="text/javascript">
// 二维数组矩形转置
var arr=[[2,4,6,8],[8,9,0,-1],[9,6,2,1]]
//定义一个数组存放转置后的数据
var arr1=[];
document.writeln("矩形转置前:<br/>");
//遍历二维数组
for(var i=0;i<arr.length;i++){
for(var j=0;j<arr[i].length;j++){
document.writeln(arr[i][j]);
}
document.writeln("<br/>");
}
document.writeln("<br/>");
document.writeln("矩形转置后:<br/>");
//把装置的数据放入一个数组arr1中
//1、初始化,确定有多少行
for(var i=0;i<arr[0].length;i++){
arr1[i]=[];
}
//2、先遍历旧数组,再动态添加数据
for(var i=0;i<arr.length;i++){
for(var j=0;j<arr[i].length;j++){
//动态添加数据到arr1数组中
arr1[j][i]=arr[i][j];
}
//document.writeln("<br/>");
}
//转置成功,遍历arr1数组
for(var k=0;k<arr1.length;k++){
for(var l=0;l<arr1[k].length;l++){
document.writeln(arr1[k][l]);
}
document.writeln("<br/>");
}
</script>
</head>
<body>
</body>
</html>
本文链接
<%@ page contentType="text/html;charSet=gb2312" import="java.util.*" %>
<%!
String year;
String month;
%>
<%
month=request.getParameter("month");
year =request.getParameter("year");
%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>日历</title>
<!-- 下面是处理onchange事件的JavaScript代码 -->
<script Language="JavaScript">
function changeMonth()
{
var mm = "calendar.jsp?month=" + document.sm.month.options.selectedIndex
+ "&year=" + <%=year%>;
window.open(mm,"_self");
}
</script>
</head>
<%! String days[]; %>
<%
days=new String[42];
for(int i=0;i<42;i++)
days[i]="";
%>
<%
//默认为当天
Calendar thisMonth=Calendar.getInstance();
//如果有参数传入,重新设置月份和年份
if(month!=null&&(!month.equals("null")))
thisMonth.set(Calendar.MONTH, Integer.parseInt(month) );
if(year!=null&&(!year.equals("null")))
thisMonth.set(Calendar.YEAR, Integer.parseInt(year) );
//重新获取年份和月份值
year=String.valueOf(thisMonth.get(Calendar.YEAR));
month=String.valueOf(thisMonth.get(Calendar.MONTH));
//将每周的第一天设置为星期天
thisMonth.setFirstDayOfWeek(Calendar.SUNDAY);
//每个月的第一天标记为1
thisMonth.set(Calendar.DAY_OF_MONTH,1);
//求这个月的第一天是星期几
int firstIndex=thisMonth.get(Calendar.DAY_OF_WEEK)-1;
//求这个月的天数
int maxIndex=thisMonth.getActualMaximum(Calendar.DAY_OF_MONTH);
for(int i=0;i<maxIndex;i++)
days[firstIndex+i]=String.valueOf(i+1);
%>
<body>
<FORM name="sm" method="POST" action="/blog_article/calendar.html">
<%=year%>年 <%=Integer.parseInt(month)+1%>月
<!-- 将日历显示在表格中 -->
<table border="0" width="168" height="81">
<div align=center>
<tr>
<th width="25" height="16" bgcolor="#FFFF00"><font color="red">日</font>
</th>
<th width="25" height="16" bgcolor="#FFFF00">一</th>
<th width="25" height="16" bgcolor="#FFFF00">二</th>
<th width="25" height="16" bgcolor="#FFFF00">三</th>
<th width="25" height="16" bgcolor="#FFFF00">四</th>
<th width="25" height="16" bgcolor="#FFFF00">五</th>
<th width="25" height="16" bgcolor="#FFFF00"><font color="green">六</font></th>
</tr>
<% for(int j=0;j<6;j++) { %>
<tr>
<% for(int i=j*7;i<(j+1)*7;i++) { %>
<td width="15%" height="16" bgcolor="#C0C0C0" valign="middle" align="center">
<%=days[i]%></td>
<% } %>
</tr>
<% } %>
</div>
</table>
<table border="0" width="168" height="20">
<tr>
<td width=30%>
<!-- 提供一个下拉列表供用户选择 -->
<select name="month" size="1" onchange="changeMonth()" >
<option value="0">一月</option>
<option value="1">二月</option>
<option value="2">三月</option>
<option value="3">四月</option>
<option value="4">五月</option>
<option value="5">六月</option>
<option value="6">七月</option>
<option value="7">八月</option>
<option value="8">九月</option>
<option value="9">十月</option>
<option value="10">十一月</option>
<option value="11">十二月</option>
</select></td>
<td width=28%><input type=text name="year" value=<%=year%> size=4 maxlength=4></td>
<td>年</td>
<td width=28%><input type=submit value="提交"></td>
</tr>
</table>
</form>
<script Language="JavaScript">
document.sm.month.options.selectedIndex=<%=month%>;
</script>
</body>
</html>
本文链接