only 10–20% of the end user response time involves retrieving the requested HTML document.The remaining 80–90% of the time is spent making HTTP requests for all the components(images, scripts, stylesheets, Flash, etc.) referenced in the HTML document.
从这个就能看出为什么要进行前端优化,在此之前,由于自己项目经验少的缘故,对这个前端优化基本不了解。汗颜....
在这里先说下为什么要减少http请求,因为我们知道一个请求,通常会包括DNS查找,建立等待,等待服务器和文件传输,除去文件传输,其他的都是属于系统开销(overhead)。所以减少Http请求就相当于减少不必要的系统开销。
或许说减少http请求,那就页面当中不要那么多图片,flash,样式表等等之类的。但是我们都知道,页面的美观是重要的,用户体验是重要的。我记得我一个同学说“华丽的页面下是死一般的代码,华丽的代码上是死一般的页面”(貌似可能写得不对,意思差不多就OK啦)用户他说不关心你用的什么技术的。所以要想在这两个方面取得平衡,还需要另辟蹊径。
书上有说可以从image maps, CSS sprites,inline images, and combined scripts and stylesheets.来减少Http请求。那下面就逐一进行介绍:
image maps
前面时间实验室的项目也弄过页面,对于这个真不知道。基本上是采用类似于
<div style="background-color: #F4F5EB; border: 2px ridge #333; width: 180px; padding-top: 4px;">
<center>
<a href="javascript:alert('Home')" title="Home"><img border=0 src="/images/home.gif?t=1308898500"></a>
<a href="javascript:alert('Gift')" title="Gift"><img border=0 src="/images/gift.gif?t=1308898500"></a>
<a href="javascript:alert('Cart')" title="Cart"><img border=0 src="/images/cart.gif?t=1308898500"></a>
<a href="javascript:alert('Settings')" title="Settings"><img border=0 src="/images/settings.gif?t=1308898500"></a>
<a href="javascript:alert('Help')" title="Help"><img border=0 src="/images/help.gif?t=1308898500"></a>
</center>
</div>
这里是采用了五个不同的图片,五个单独的链接。但是如果采用image map,这个能减少请求数,而且也不会改变页面原有的视觉效果或者是体验效果。image map是将不同的链接关联到一副图片上。
image maps有两种类型:Server-side image maps 它是所有的图片都指向一个链接,不过要分别传递各自的X,Y坐标,后台根据这些坐标作出不同的反应。Client-side image maps 这个算是用的比较多,不需要后台分析,而是直接将转向不同链接,下面例子就是采用这个。
将上面的代码改成类似于下面的
<div style="background-color: #F4F5EB; border: 2px ridge #333; width: 180px; padding: 4px 0 4px 0;">
<center>
<img usemap="#map1" border=0 src="/images/imagemap.gif?t=1308898940">
<map name="map1">
<area shape="rect" coords="0,0,31,31" href="javascript:alert('Home')" title="Home">
<area shape="rect" coords="36,0,66,31" href="javascript:alert('Gifts')" title="Gifts">
<area shape="rect" coords="71,0,101,31" href="javascript:alert('Cart')" title="Cart">
<area shape="rect" coords="106,0,136,31" href="javascript:alert('Settings')" title="Settings">
<area shape="rect" coords="141,0,171,31" href="javascript:alert('Help')" title="Help">
</map>
</center>
</div>
这里可以看到将5副图片合并成一个图片,通过位置坐标来确定链接。不过这里比较困难的就是位置信息的确定,矩形还好找,其他的图形就很难确定了。确定这些位置是繁琐的,而且人工操作很有可能出现问题。任何事情都有得必有失咯,好好权衡!
在这里突然想到以前做报表的时候,用到的jfreechart生成的图片就是采用Image map。它生成的图片,比如说柱状图、甘特图等等。印象深的是柱状图,记得当时因为页面大小已经固定好的缘故,jfreechart生成的图片如果太小,就会出现问题。可能是图片显示是缩小了,但是实际响应的位置区域没有变化,以至于链接错乱。
CSS sprites
有点类似于Image map都是将不同的图片整合起来,不过它主要是通过background-image和background-position来设置的,例如:
<style>
#navbar span {
width:31px;
height:31px;
display:inline;
float:left;
background-image:url(/images/spritebg.gif);
}
.home { background-position:0 0; margin-right:4px; margin-left: 4px;}
.gifts { background-position:-32px 0; margin-right:4px;}
.cart { background-position:-64px 0; margin-right:4px;}
.settings { background-position:-96px 0; margin-right:4px;}
.help { background-position:-128px 0; margin-right:0px;}
</style>
这种方法相比于image map有好处:image map要求图片的位置上相邻的,而css sprites没有这样的限制,不过同样还是需要人工去进行位置的确定(听说有一个很不错的工具可以帮助实现背景图片的合并和CSS文件的生成:spriteme),而且在定位方位一定要把握准确,是绝对定位还是相对定位,背景图片是否会根据页面大小而进行变化。
Inline Images
It’s possible to include images in your web page without any additional HTTP requests by using the data: URL scheme.说真的,我还真没有见过这个,不过我没有见过的东西多着呢。不过这种方式IE浏览器是不支持的。
先来说说data: URL scheme 吧,它最找是1995年提出的,说它是“allows inclusion of small data items as ‘immediate’ data.”格式如下:
data:[<mediatype>][;base64],<data>,可以说有两个缺点:不被IE浏览器支持,大小限制。FIREFOX 1.5支持的图片大小可达100K,可是这里采用64位编码,会增加文件的大小。
这里还有一个问题,因为data: URLs 是嵌套在页面中的,在不同页面之间不能缓存,加入说图片被不同页面共享,就不适合选择这个。但是可以通过另外一种方法来解决,CSS与之相结合,将data: URLs 写入css中,类似于
.home { background-image: url(data:image/gif;base64,R0lGODlhHwAfAPcAAAAAAIxKA...);}
.gift { background-image: url(data:image/gif;base64,R0lGODlhHwAfAPcAAAAAAABCp...);}
这里会觉得url中的内容比较难写,可以使用file_get_contents PHP 函数来创建inline images,如:
.home { background-image: url(data:image/gif;base64,
<?php echo base64_encode(file_get_contents("../images/home.gif")) ?>);}
.gift { background-image: url(data:image/gif;base64,
<?php echo base64_encode(file_get_contents("../images/gift.gif")) ?>);}
Combined Scripts and Stylesheets
真是鱼和熊掌不能兼得,模块化的思想使我们将样式和html内容分开,生成js、css文件,在界面中导入这些文件,易于管理。有些时候我们将一个页面的css,分写成head.css、footer.css、content.css确实这样的思想易于管理,但是这样会导致增加http请求。在这里有提到将css能尽量写道一个文件中,将js文件和css文件整合(这个我认为不可行,难于维护和管理).