资源命名技巧
我们刚才说的那个技术存在这问题,当我们想修改页面的一个资源的时候,如一个图片,就会出现问题。如果你上传了一个修改过的图片到你的web服务器,新的访问者将会接收到更新的图片,但是之前的访问者(跟新图片前)不会接收到更新的图片。他们看到的是旧的版本,因为你已经通知他们的浏览器不要再次请求图片了。
解决方案就是修改资源的名字,但是这就会带来一些维护的故障了。举个例子,如果你有几个CSS样式表的定义,指向img.png,并且你修改了该图片,把它的名字命名为img2.png,你将不得不在引用该图片的样式表中修改所有的指向,并且更形样式表。对一个大点的项目,你或许要考虑系一个工具来自动完成这个任务。
当你对你的资源进行命名的时候,你需要提出一个命名约定。举个例子,你将:
- 追加时间信息到文件名前,如:img_1185403733.png.
- 使用你资源控制系统(如cvs或者svn)的版本号来命名,如img_1.1.png.
- 文件名前自动增加1(如当你看到一个文件名为img1.png,简单的保存修改的图片为img2.png)
这里并没有一个唯一的答案。根据你个人的偏好,具体的页面,项目的大小,和你开发团队的情况,来决定你的命名约定。
如果你使用CVS,这里有一个小的PHP函数,能够帮助你提取存在CVS中的文件的版本。
function getVersion($file) {
$cmd = 'cvs log -h %s';
$cmd = sprintf($cmd, $file);
exec($cmd, $res);
$version = trim(str_replace('head: ', '', $res[3]));
return $version;
}
}
// example use
$file = 'img.png';
$new_file = 'img_' . getVersion($file) . '.png';
使得Etags失效
当你实施上面的选择的时候,就会遇到潜在的争论。但是下面的这条就会很容易了,你只需要增加下面的内容到你的.htaccess文件即可。
没有FileETags
注意这条规则适合那些有单独主机的站点。如果你在使用一个共享主机,我推荐你跳过这个步,下面是推荐的原因:
- 由于内部的目地,主机的机器会改变
- 你或许会改变主机
- 这条规则复杂。
使用CSS子画面
使用一个称为CSS自画面的技术,你可以将几张不同的图片结合成单独一张,随后使用CSS的background-position属性来显示你当前所需要的图片。这个技术不是给内容图片使用(那些在HTML代码中出现在<img />标签中的图片)的,是为装饰用途的图片准备的。这些图片将不会影响到一个页面的可用性,通常在一个样式表中引入,为了保持代码的简约(规则#0)。
下面看一个例子。我们将准备两张图片。第一张是help.png;第二张是rss.png.以这两张为基础,我们可以创建第三张图片,sprite.png,它包括前面两张。
将两张图片组合成一张图片
第三那张图片文件的大小经常会比前面两张图片文件大小之和的小。为了显示第一张图片,我们使用下面的CSS:
#help {
background-image: url(sprite.png);
background-position: -8px -8px;
width: 16px;
height: 16px;
}
background-image: url(sprite.png);
background-position: -8px -8px;
width: 16px;
height: 16px;
}
为了显示第二张图片,我们使用下面的CSS:
#rss {
background-image: url(sprite.png);
background-position: -8px -40px;
width: 16px;
height: 16px;
}
background-image: url(sprite.png);
background-position: -8px -40px;
width: 16px;
height: 16px;
}
第一眼看上去,这个技术或许有些奇怪,但那时它真的很有用,能减少HTTP请求。这么组合的图片越多越好,因为你正在急剧减少请求所用的开销。这个技术使用的例子,你可以看看文章:this image, used on Yahoo!'s homepage, 或者 this one from Google's.
为了尽快生成子画面图片,而不用计算像素坐标,你可以使用我开发的一个工具:CSS 子画面生成器。 更多的关于CSS子画面,一定要读Dave Shea的文章,题目为CSS Sprites: Image Slicing's Kiss of Death.