《Higb Performance Web Sites》(中文名:“高性能网站建设指南”)这本书对于前端工程师来说,绝对值得一读。本人有幸从公司借阅了,但不幸的是感觉翻译有点怪怪的。尤其是在翻译CSS Sprites的关键部分,让人不知所云。幸亏原理比较简单,所以没有造成障碍。^_^
本人看书有做笔记、写示例、发牢骚的习惯,所以有了下文。个人备忘也罢,初学者入门也罢,反正赖在这里。所以,拍砖也罢,口水也罢,我都忍着,呵呵。。。
当一个页面的图片在没有使用任何方案的情况下,五个图片超链接就只能使用五个图标按钮。
代码如下:
<
div
style
="border: 2px ridge rgb(51, 51, 51); background-color: rgb(244, 245, 235); width: 200px; padding-top: 4px;"
>
<
center
>
<
a
href
="javascript:alert('Home')"
title
="Home"
><
img
src
="http_request_img/home.gif"
border
="0"
></
a
>
<
a
href
="javascript:alert('Gift')"
title
="Gift"
><
img
src
="http_request_img/gift.gif"
border
="0"
></
a
>
<
a
href
="javascript:alert('Cart')"
title
="Cart"
><
img
src
="http_request_img/cart.gif"
border
="0"
></
a
>
<
a
href
="javascript:alert('Settings')"
title
="Settings"
><
img
src
="http_request_img/settings.gif"
border
="0"
></
a
>
<
a
href
="javascript:alert('Help')"
title
="Help"
><
img
src
="http_request_img/help.gif"
border
="0"
></
a
>
</
center
>
</
div
>
效果如下:
注意:这五个按钮分别使用了五张图片
那么,五张图片就意味着你的该页面又多了五个HTTP请求,它将大大降低页面的呈现效率。增加的HTTP请求是导致页面性能下降的最大刽子手,所以我们应该尽量减少HTTP请求,而图片是增加HTTP请求的最大可能者,搞定它,事不宜迟!呵呵^_^
下面列出了三种解决方案:
方案一:图片地图(图像热点):它将用户的点击映射到一个操作,而无需向后端Web服务器发送任何请求。
代码如下:
<
div
class
="panel_div"
style
="border:2px ridge #333333;background-color:rgb(244, 245, 235);width:180px;padding:4px 0px 0px 2px;"
>
<
img
usemap
="#mymap"
src
="http_request_img/imagemap.gif"
border
="0"
/>
<
map
name
="mymap"
>
<!--
img使用的map
-->
<
area
shape
="rect"
coords
="0,0,31,31"
href
="javascript:alert('Home');"
/>
<
area
shape
="rect"
coords
="36,0,66,31"
href
="javascript:alert('Gifts');"
/>
<
area
shape
="rect"
coords
="71,0,101,31"
href
="javascript:alert('Cart')"
/>
<
area
shape
="rect"
coords
="106,0,136,31"
href
="javascript:alert('Set')"
/>
<
area
shape
="rect"
coords
="141,0,171,31"
href
="javascript:alert('Help')"
/>
</
map
>
</
div
>
效果如下:
注意:这五个按钮其实是在一张图片中
方案二:CSS Sprites:使用这种方式也可以将五张图片合并为一张图片,并且更为灵活。
代码如下:
<
style
>
/*
对div中所有span的样式设置
*/
#navbar span
{
/*
定义<span>标签将截取的图片宽度和高度
*/
width
:
30px
;
height
:
31px
;
/*
添加包含了所有图标的图片
*/
background-image
:
url(http_request_img/imagemap.gif)
;
display
:
inline
;
float
:
left
;
}
/*
background-position:指定图标在CSS Sprites图片的偏移量
margin-left 和 margin-right 则用来定位图标位置
*/
.home
{
background-position
:
0 0
;
margin-left
:
2px
;
}
.gifts
{
background-position
:
-35px 0
;
margin-left
:
50px
;
}
.cart
{
background-position
:
-70px 0
;
margin-left
:
120px
;
}
</
style
>
<
div
id
="navbar"
style
="border: 2px ridge rgb(51, 51, 51); padding: 4px 0pt; background-color:#ff0; width: 300px; height: 32px;"
>
<
a
href
="javascript:alert('Home')"
title
="Home"
>
<
span
class
="home"
></
span
></
a
>
<!--
注意:该span标签用来加载图片
-->
<
a
href
="javascript:alert('Gifts')"
title
="Gifts"
>
<
span
class
="gifts"
></
span
></
a
>
<!--
注意:该span标签用来加载图片
-->
<
a
href
="javascript:alert('Cart')"
title
="Cart"
>
<
span
class
="cart"
></
span
></
a
>
<!--
注意:该span标签用来加载图片
-->
</
div
>
效果如下:
注意:在这个“CSS Sprites”中用到的图片就是“图片地图”中的同一张图片。(并特地只显示其中的三个图标)
CSS Sprites的原理:只是定位到图片其中的一块区域,并显示在某个位置而已。
CSS Sprites的优点:通过只使用一个图片减少了HTTP请求,并且比“图片地图”更灵活。
很多人会误认为:合并的图片要比分离的图片的总和要大,因为合并的图片中包含有附加的空白区域。
实际上,合并的图片要比分离的图片的总和要小,这是因为它降低了图片自身的开销(颜色表、格式信息,等等)。
方案三:内联图片:通过使用data: URL模式在Web页面中包含图片,且无需任何额外的HTTP请求。(IE目前不支持)
1、内联图片的原理:允许将小块数据内联为‘立即数(immediate data)’,数据就包含在其URL自身之中。
2、内联图片的格式:data:[<mediatype>][;base64],<data>
举例:一个内联图片可以定义为
<img src="data:image/gif;base64,asdfghjklaasdvdddddddaaaaaddddd++ddd======ssswdvdv33" >
其中“asdfghjklaasdvdddddddaaaaaddddd++ddd======ssswdvdv33”就是该图片的数据。
data: URL模式-> 基本用于内联图片,可以用在任何需要指定URL的地方,如:script和a标签中。
3、内联图片的缺陷:
a> 不受IE的支持(IE7也如此);
b> 保存数据的大小上受限制(Firefox 1.5支持高达100KB的数据);
c> Base64编码会增加其图片的大小;
d> 在跨越不同页面时不会被缓存
(可以将内联图片作为背景图片保存在外部CSS样式表中来解决此问题,但会增加一个HTTP请求以换得数据被缓存的结果。);
在PHP技术中,使用函数file_get_contents从磁盘读取图片并插入到页面中来创建内联图片:
在其HTML中,使用style标签的href属性指定外部样式表文件时,直接指定到了一个PHP模版的.php文件(注意:不是.css文件),该PHP模版使用file_get_contents函数生成其样式表:
.home{ background-image:url(data:image/gif;base64,<?php echo base64_encode(file_get_contents("../img/home.gif")) ?>);}
其最终数据将是base64编码格式的图片data数据。
当然,使用ASP.NET技术生成其base64编码格式的图片data数据也不会很难。大家可以自行实验。
本人推荐:根据具体情况,使用方案一:图片地图(图像热点)或方案二:CSS Sprites。
附加知识:URL中的相关协议:http:、data:、file:、ftp:、mailto:、smtp:、pop:、dns:、whois:、finger:、daytime:、news:、urn: 等。这其中有一些是官方注册的,还有一些是由于广泛使用而被接受。
2010.8.27 补记:
【推荐】重典博客中的这篇文章:
在ASP.NET中自动合并小图片并使用CSS Sprite显示出来