缓存 gzip 压缩的 css

Posted

技术标签:

【中文标题】缓存 gzip 压缩的 css【英文标题】:Caching gzipped css 【发布时间】:2010-11-12 18:48:41 【问题描述】:

我已经完成了一些关于如何 gzip 压缩 css 文件的教程,您可以在其中创建一个公共 php 文件以包含 css 文件并进行压缩。问题是我无法让它缓存我的 css 文件。我正在使用 firebug 作为参考,实际上我已经尝试使用相同的代码来压缩一些 javascript 并且它可以很好地缓存它。

代码如下:

如果(扩展加载('zlib')) ob_start('ob_gzhandler'); $偏移量 = 60 * 60 * 24 * 31; header('内容类型:文本/css'); header ('Cache-Control: max-age=' . $offset . ', must-revalidate'); header ('Expires: ' . gmdate ("D, d M Y H:i:s", time() + $offset) . ' GMT'); ob_start("压缩"); 函数压缩($缓冲区) // 删除评论、空格、结束 ;'s $buffer = preg_replace('#/\*.*?\*/#s', '', $buffer); $buffer = preg_replace('/\s*([|:;,])\s+/', '$1', $buffer); $buffer = preg_replace('/\s\s+(.*)/', '$1', $buffer); $buffer = str_replace(';', '', $buffer); $buffer = str_replace('', '', $buffer); 返回$缓冲区; 包括('global.css'); 如果(扩展加载('zlib')) ob_end_flush();

然后我只是将我的 php 文件作为 css 文档引用到其他页面上。 如您所见,我尝试将最大年龄添加到组合中,但也被证明是不成功的。

这是响应标头

日期 格林威治标准时间 2009 年 7 月 21 日星期二 19:59:19 服务器 Apache/1.3.41 (达尔文) PHP/4.4.9 X-Powered-By PHP/4.4.9 缓存控制 max-age=2592000,必须重新验证 过期 格林威治标准时间 2009 年 8 月 20 日星期四 19:59:19 内容编码 压缩包 各不相同 接受编码 活着 超时=15,最大值=93 联系 活着 传输编码 分块 内容类型 文本/CSS

有什么我遗漏的,或者更好的方法吗?

谢谢,

编辑:

检测文件是否已更改并在未更改时发送 304 的脚本结合适当的标头已解决了此问题。

亚瑟

【问题讨论】:

【参考方案1】:

尝试将其添加到标题集:-

$offset = 60 * 60 * 24;
header('Content-type: text/css');
header('Cache-Control: max-age=' . $offset);
header('Expires: ' . gmdate ("D, d M Y H:i:s", time() + $offset) . ' GMT');
header('Last-Modified: ' . gmdate ("D, d M Y H:i:s", time()) . ' GMT');

问题在于缓存控制标头中的must-revalidate 指令。这将导致客户端在每次需要时重新请求 css,并且您的代码没有处理 If-Modified-Since 标头和发送 304 Unmodified 响应状态代码。

上述方法将缓存周期减少到 1 天,并消除了 must-revalidate 指令。它还添加了 Last-Modified 标头(如果缺少 Last-Modified 或 ETag 标头,缓存可能会选择不缓存项目)。

为了改善这一点,您可以找到您正在压缩的 css 文件的实际最后修改时间,并将其作为 Last-Modified 标头发送。您可以在代码中包含请求 If-Modified-Since 标头与 css 文件上次修改时间的值的比较。如果您发现它们相同,则发送这组标头,但也发送 304 Unmodfied 状态并且根本不发送正文。 (我不是真正的 PHP 人,所以我将把它留给 PHP 专家放在另一个答案中)。

在客户端必须再次尝试检索 css 并相应地设置 max-age 值之前,请实际评估您希望客户端缓存 css 多长时间。

【讨论】:

嘿 Anthony,我已经尝试像您建议的那样添加 Last-Modified,并结合后期和先前的修改日期,但没有运气。我还发送了带有 ETag 的标头,如果从那以后进行了修改,但它仍然没有缓存...感谢您的回复,我会记住所有这些以供将来参考和调试。 @askon:这些不是关键因素,关键问题是您在 Cache-Control 标头中包含 must-revalidate 指令。使用这意味着将始终重新获取 css。您还在测试中使用页面刷新 (F5) 吗?这并不能证明任何事情,诸如 css 之类的资源是在刷新上下文下重新获取的,并且没有内置到代码中的 304 机制将导致资源的完整获取。 对不起,我应该更具体一点。我确实删除了必须重新验证的行,这是我的标题响应:freetexthost.com/zqbddbchvz 我不明白的是我可以尝试完全相同的脚本,除了文本/javascript 文档,它显示 200 并缓存它。跨度> 我也忘了注意,是的,我使用 F5 刷新页面,并使用 Firefox 3.5.1 和 Firebug 1.4.0b7 尝试通过简单地添加 ?x=1 到 url 而不是刷新来进行测试。这应该表明 css 正在被缓存。【参考方案2】:

如果您阅读 python/django,您可以阅读django compressor 的代码。它将多个 CSS 文件合二为一。 CSS 部分看起来像是启动 CSSTidy 来清理 CSS。

【讨论】:

2014-12-03:嘿,@downvoter,感谢您光临并就 5 岁半的答案提出您的想法。

以上是关于缓存 gzip 压缩的 css的主要内容,如果未能解决你的问题,请参考以下文章

nginx开启gzip压缩和静态缓存

Nginx优化--网页压缩与缓存时间

IIS静态压缩不是Gzip或缓存文件

网页压缩,缓存,隐藏版本和制作防盗链

nginx优化--gzip压缩与expire浏览器缓存

005-优化web请求一-gzip压缩http缓存控制和缓存校验[PragmaExpiresCache-Controlmax-ageLast-Modified用户刷新访问避免过度304]