HTTP缓存,浏览器差异

时间:2009-09-16 17:24:51

标签: performance apache caching

堆栈的尊重溢出,

所以我最近一直试图完全围绕HTTP资源缓存。值得注意的是,现在我正在简单地查看单个图像的缓存,该图像用于在整个页面中呈现图标/小图像。这是我所看到的奇怪行为的解释:

因此,在给定的页面上,我只有一个图像:icons.sprite.gif。有四个元素使用精灵在页面上显示各种图标。在我的Apache配置中,我安装了mod_expires和以下缓存控制指令:

ExpiresActive On
ExpiresDefault "access plus 300 seconds"

ExpiresByType text/html "access plus 1 day"
ExpiresByType text/css "access plus 1 day"
ExpiresByType text/javascript "access plus 1 day"
ExpiresByType image/gif "access plus 1 week"
ExpiresByType image/jpg "access plus 1 week"
ExpiresByType image/png "access plus 1 week"
ExpiresByType application/x-shockwave-flash "access plus 1 day"

现在,这是奇怪的。在Safari中,当我加载页面时,网络检查器只显示一个sprite请求。这是完美的,按预期工作。另一方面,使用Internet Explorer和Firefox,Fidder / Firebug显示四个成功请求的sprited图像=什么!?后续请求会导致单个缓存命中,但第一个加载包含四个并发请求。这似乎是一个相当大的wtf,因为它似乎绕过了spriting的整个点,这是为了减少给定页面加载周期中的资源请求的绝对数量。

可能发生的事情:

页面加载速度足够快,当第二个元素渲染到使用sprited背景图像的文档时,sprite的第一个请求还没有完成。因此,如果资源尚未缓存,则在呈现后面的元素时,它们会导致对资源的新请求,即使它已经被加载。 Safari以某种方式处理和防止这种情况(我知道Safari的缓存实践与其他浏览器有些不同)。

所以 - 我在这里寻找一些确认/输入。对于这些浏览器,这是否“按预期工作” - 此外,它是否否定了与spriting相关的性能提升(这确实引入了css维护的复杂性)?或者,我有什么不对劲吗?

感谢您的想法/建议。

干杯,

Skone

2 个答案:

答案 0 :(得分:4)

所以,经过大量的改编后,我想出了如何解决这个问题。

比方说,我创建一个精灵并按如下方式使用css:

.icon { 
   background: transparent url(/media/common/images/sprite.gif) scroll no-repeat 0 -33px;
}

.logo {
   background: transparent url(/media/common/images/sprite.gif) scroll no-repeat 0 -10px;
}

在firefox中,这将导致对该图像的两个请求,而不是对图像的单个请求。因此,修复方法是整合css规则:

.sprited {
  background: transparent url(/media/common/images/sprite.gif) scroll no-repeat 0 0;
}

.icon { 
   background-position: 0 -33px;
}

.logo {
   background-position: 0 -10px;
}

我意识到这本身更合适,因为它避免了sprited元素之间的背景属性的重复。

无论如何,希望这证明对另一个spriter有用!

编辑:经过一些额外的测试后,这实际上只发生在Mozilla Firefox(独立于平台)中。 Safari和IE解释对同一图像的多个引用并发出单个请求,而Firefox似乎对通过CSS链接的每个图像发出唯一请求。

我意识到它可能没有被特别理解为一个错误,但在一个浏览器竞争被标记为最快的时代 - 似乎是Firefox的潜在改进!

你们有什么想法,我应该把它作为一个错误提交给Mozilla吗?

答案 1 :(得分:1)

您对情况的分析似乎正朝着正确的方向发展。以下是我的一些想法:

首先,最大连接数的概念。浏览器设置不同。与此相关,Firefox /其他浏览器可能会尝试在多个连接上加载相同的资源,直到一个成功,而Safari只会尝试为给定资源建立一个连接。

第二,Safari只拨打一个电话吗?或者仅报告单个成功通话?也就是说,Safari对给定资源发出4个请求,第一个请求完成,其余部分被忽略而不报告。

第三,Safari只是更快吗?尝试更大的图像或通过Safari中的慢速连接下载,看看它是否会与其他浏览器具有相同的“问题”。

最后,我一般不相信这会否定使用精灵的性能提升。在有几十个或者几十个图像的情况下,精灵真的可以提供帮助,以减少http请求。如果您使用精灵拍摄少量图像(例如5-10),那么在这种情况下几乎没有意义。

与http请求无关的精灵的另一个好处与交互式延迟有关。 IE浏览器过去只在元素上显示后才下载图像,例如在悬停时,在悬停状态下创建滞后。精灵解决了这个问题。