简体   繁体   English

HTTP缓存,浏览器差异

[英]HTTP Caching, Browser Differences

Esteemed Overflow-ers of the Stack, 尊重堆栈的溢出者,

So I've recently been trying to fully wrap my head around HTTP resource caching. 所以我最近一直试图完全围绕HTTP资源缓存。 Notably, right now I'm looking at simply the caching of a single, sprited image which is used for rendering icons / small images through out the page. 值得注意的是,现在我正在简单地查看单个图像的缓存,该图像用于在整个页面中呈现图标/小图像。 Here's an explanation of the odd behavior I'm seeing: 这是我所看到的奇怪行为的解释:

So, on the given page I have only a single image: icons.sprite.gif. 因此,在给定的页面上,我只有一个图像:icons.sprite.gif。 There are four elements which use the sprite to display various icons on the page. 有四个元素使用精灵在页面上显示各种图标。 In my Apache config, I have mod_expires installed and the following cache-control directives: 在我的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"

Now, here's the weirdness. 现在,这是奇怪的。 In Safari, when I load the page, the net-inspector reveals only a single request for the sprite. 在Safari中,当我加载页面时,网络检查器只显示一个sprite请求。 This is perfect, working as expected. 这是完美的,按预期工作。 On the other hand, with Internet Explorer and Firefox, Fidder / Firebug reveals four successful requests for the sprited image = what!? 另一方面,使用Internet Explorer和Firefox,Fidder / Firebug显示四个成功请求的sprited图像=什么!? Subsequent requests result in a single cache hit, but that first load contains four concurrent requests. 后续请求会导致单个缓存命中,但第一个加载包含四个并发请求。 This seems like a pretty big wtf, as it seems to circumvent the whole point of spriting, which is to the reduce the sheer number of resource requests in a given page-load cycle. 这似乎是一个相当大的wtf,因为它似乎绕过了spriting的整个点,这是为了减少给定页面加载周期中的资源请求的绝对数量。

What may be happening: 可能发生的事情:

The page is loading fast enough that by the time the second element is rendered to the document which uses the sprited background image, the first request for the sprite hasn't finished yet. 页面加载速度足够快,当第二个元素呈现给使用sprited背景图像的文档时,第一个sprite请求尚未完成。 Accordingly, given the resource isn't yet cached, as later elements are rendered, they result in a new request for the resource, even though its already being loaded. 因此,如果资源尚未缓存,则在呈现后面的元素时,它们会导致对资源的新请求,即使它已经被加载。 Safari handles and prevents this somehow (I know that Safari's caching practices are somewhat different than other browsers). Safari以某种方式处理并防止这种情况(我知道Safari的缓存实践与其他浏览器有些不同)。

So -- I'm looking for some confirmation / input here. 所以 - 我在这里寻找一些确认/输入。 Is this "working as expected" for these browsers -- furthermore, does it negate the performance gains associated with spriting (which does introduce css-maintenance complexities)? 对于这些浏览器,这是否“按预期工作” - 此外,它是否否定了与spriting相关的性能提升(这确实引入了css维护的复杂性)? Alternatively, is there something wrong I'm doing? 或者,我有什么不对劲吗?

I appreciate your thoughts / suggestions. 我感谢您的想法/建议。

Cheers, 干杯,

Skone Skone

So, after extensive munging I figured out how to fix the problem. 因此,经过大量的改编后,我想出了如何解决这个问题。

Let say, for instance, that I create a sprite and use css as follows: 比方说,我创建一个精灵并使用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;
}

In firefox, this will cause two requests for that image, as opposed to a single request for the image. 在firefox中,这将导致对该图像的两个请求,而不是对图像的单个请求。 The fix, accordingly, is to consolidate the css-rules as such: 因此,修复方法是整合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;
}

I realize this in itself is more appropriate, as it avoids duplication of the background property among sprited elements. 我意识到这本身更合适,因为它避免了sprited元素之间的背景属性的重复。

Anyway, hope this proves useful for another spriter to be! 无论如何,希望这证明对另一个spriter有用!

Edit : After a bit of additional testing, this in fact only happens in Mozilla Firefox (platform independent). 编辑 :经过一些额外的测试,这实际上只发生在Mozilla Firefox(独立于平台)。 Safari and IE interpret multiple references to the same image and make a single request, while Firefox appears to make a unique request for each image linked to via CSS. Safari和IE解释对同一图像的多个引用并发出单个请求,而Firefox似乎对通过CSS链接的每个图像发出唯一请求。

I realize its probably not specificly understood as a bug, but in an era where browsers are competing for being labeled the fastest -- seems like a potential improvement for Firefox! 我意识到它可能没有被特别理解为一个错误,但在一个浏览器竞争被标记为最快的时代 - 似乎是Firefox的潜在改进!

What do you guys think, should I submit this to Mozilla as a bug? 你们有什么想法,我应该把它作为一个bug提交给Mozilla吗?

Your analysis of the situation seems to be going the right direction. 你对情况的分析似乎正朝着正确的方向发展。 Here are a couple of thoughts I have: 以下是我的一些想法:

First, the concept of maximum number of connections. 首先,最大连接数的概念。 Browsers set this differently. 浏览器设置不同。 Related to this, it may be possible that Firefox / other browsers will attempt to load the same resource on multiple connections until one is successful, whereas Safari only tries one connection for a given resource. 与此相关,Firefox /其他浏览器可能会尝试在多个连接上加载相同的资源,直到一个成功,而Safari只尝试为给定资源建立一个连接。

Second, is Safari only making one call? 其次,Safari只拨打一个电话吗? Or is it only reporting the single successful call? 或者仅报告单个成功通话? That is, Safari makes 4 requests for a given resource, and the first one completes so the rest are ignored and not reported. 也就是说,Safari对给定资源发出4个请求,第一个请求完成,其余部分被忽略而不报告。

Third, is Safari just faster? 第三,Safari只是更快吗? Try a larger image or downloading over a slow connection in Safari to see if it will have the same 'problem' as the other browsers. 尝试更大的图像或通过Safari中的慢速连接下载,看看它是否会与其他浏览器具有相同的“问题”。

Finally, I generally don't believe this negates the performance gains of using sprites. 最后,我通常不相信这会否定使用精灵的性能提升。 Sprites are really there to help in situations where there are several 10's or perhaps 100's of images, so as to reduce the http requests. 在有几十个或者几十个图像的情况下,精灵真的可以提供帮助,以减少http请求。 If you're using sprites for a small number of images (5-10 for example), it almost doesn't make sense in that case. 如果您使用精灵来处理少量图像(例如5-10),那么在这种情况下几乎没有意义。

One other benefit of sprites unrelated to http requests relates to interactive lag. 与http请求无关的精灵的另一个好处与交互式延迟有关。 IE browsers in the past only downloaded images once they were shown on an element, for example on hover, creating a lag in the hover state. IE浏览器过去只在元素上显示后才下载图像,例如在悬停时,在悬停状态下创建滞后。 Sprites solved that problem. 精灵解决了这个问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM