浏览器缓存CSS将带来主要的性能提升。 您确保服务器设置为发送标头,这些标头告诉浏览器在给定的时间内挂接到CSS文件。 最好的做法是,即使不是大多数站点,许多站点已经在这样做。
与浏览器缓存紧密结合的是缓存清除 。 假设浏览器将CSS文件缓存了一年(这并不罕见)。 然后,您想更改CSS。 您需要一种策略来打破缓存并强制浏览器下载CSS的新副本。
这里有一些方法。
CSS必须缓存起来才有意义……
为了确保这一点,这是缓存CSS文件的一些看起来不错的标头:
我们正在寻找那个Cache-Control
and Expires
标头。 我不是服务器配置专家。 我可能会看一下H5BP服务器配置。 但是,这里有一些经典的Apache / HTAccess方法来实现:
<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf)(\.gz)?$">
Header set Expires "Thu, 15 Apr 2020 20:00:00 GMT"
</FilesMatch>
<IfModule mod_expires.c>
ExpiresActive on
ExpiresByType text/css "access plus 1 year"
ExpiresByType application/javascript "access plus 1 year"
</IfModule>
查询字串
如今,大多数浏览器会看到带有不同查询字符串的URL作为不同文件,并下载新副本。 大多数CDN甚至都支持并建议这样做。
<link rel="stylesheet" href="style.css?v=3.4.1">
零钱吗? 更改为:
<link rel="stylesheet" href="style.css?v=3.4.2">
通过将服务器端变量设置为可在多个位置使用,可以使自己更容易。 因此,对其进行更改将立即破坏许多文件的缓存。
<?php $cssVersion = "3.4.2"; ?>
<link rel="stylesheet" href="global.css?v=<?php echo $cssVersion; ?>">
也许您甚至可以使用语义版本控制 。 您还可以定义一个常量 。
更改文件名
查询字符串并不总是有效。 某些浏览器没有将不同的查询字符串视为不同的文件。 而且某些软件(我听说过: Squid )不会使用查询字符串缓存文件。 史蒂夫·索德斯( Steve Souders) 告诉我们不要这样做。
类似的概念是更改文件名本身。 在HTML中是这样的:
<link rel="stylesheet" href="style.232124.css">
您将以编程方式处理此问题,而不是从字面上更改项目中的文件名。 由于该文件实际上不在服务器上,因此您需要执行一些技巧才能将其路由到正确的文件。 杰里米·基思(Jeremy Keith)不久前就对此进行了报道 。
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+).(\d+).(js|css)$ $1.$3 [L]
这告诉服务器忽略JavaScript和CSS文件名中的这些数字,但是每当我更新该数字时,浏览器仍会将其解释为新文件。
他使用Twig,因此他使用的模板最终类似于:
{% set cssupdate = '20150310' %}
<link rel="stylesheet" href="/css/main.{{ cssupdate }}.css">
我相信您可以想象任何后端语言( 例如ASP )的版本。 通过使构建工具或部署脚本更新变量本身来进行升级。
基于文件更新日期的缓存清除“数字”
在搜索有关此缓存无效化内容的过程中,您会看到很多建议,建议您使用服务器检查文件的上次更新时间,以创建缓存无效化“数字”(数字,即您更改为无效化缓存的所有内容) )。
function autoversion($url) {
$path = pathinfo($url);
$ver = '.'.filemtime($_SERVER['DOCUMENT_ROOT'].$url).'.';
return $path['dirname'].'/'.str_replace('.', $ver, $path['basename']);
}
<link href="<?php autoversion('/path/to/theme.css'); ?>" rel="stylesheet">
我对此不好说。 在我看来 ,要求您的服务器在每个综合浏览量中挖掘这些信息会非常繁琐,而且在生产中很危险。 过去,我做过类似的事情:“我将只让PHP在数据属性中输出图像的尺寸!” 才发现它使服务器瘫痪。 无论如何,要当心。
电子标签
ETags似乎是一个好主意,因为它们的全部要点是检查浏览器是否已经具有该文件副本的信息。
但是那里的大多数建议都说:“关闭您的ETags标头”。 雅虎说 :
ETag的问题在于它们通常使用使它们对托管站点的特定服务器而言唯一的属性构造。 当浏览器从一台服务器获取原始组件,然后尝试在另一台服务器上验证该组件时,ETag将不匹配,这种情况在使用服务器集群处理请求的网站上非常普遍。
另一个问题是它们不如实际的缓存有效。 为了检查ETag, 仍然需要发出网络请求。 不仅是影响性能的文件下载,还包括所有网络协商和延迟问题。
同样,这里不是专家,但是通常建议在Apache领域将其关闭:
<IfModule mod_headers.c>
Header unset ETag
</IfModule>
FileETag None
框架为我们做
Rails资产管道
我对Rails Asset Pipeline和Sprockets有一点经验。 如果你问我,那是一个梦想的系统。 我在模板中链接样式表:
<%= stylesheet_link_tag "about/about" %>
并产生如下HTML:
<link href="http://assets.codepen.io/assets/about/about-7ca9d3db0013f3ea9ba05b9dcda5ede0.css" media="screen" rel="stylesheet" type="text/css" />
该高速缓存清除编号仅在文件更改时才更改,因此您只中断需要中断的文件上的高速缓存。 另外,它还有图像和JavaScript的方法。
WordPress的
如果您在WordPress中使用页面缓存工具(例如W3 Total Cache等),则可能不必担心filemtime
业务过于filemtime
服务器资源。
Gilbert Pellegrom 发表了使用它的WordPress特定技术 :
wp_register_style( 'screen', get_template_directory_uri().'/style.css', array(), filemtime( get_template_directory().'/style.css' ) );
wp_enqueue_style( 'screen' );
// Example Output: /style.css?ver=1384432580
WordPress插件崩溃了! 在幕后做同样的事情。 只是对所有内容都会自动执行。
代码包
CodeKit没有用于更改文件名的内置方法,但是它确实具有在您设置的情况下执行Shell脚本的方法。
迈克尔·拉塞尔(Michael Russell)的博客文章中介绍了如何将时间戳添加到文件本身中,我相信您可以进行修改以更改文件名。
制作工具
所有流行的任务运行器/构建工具thingies都具有可帮助更改文件名的插件。 Sufian Rhazi 也有在原始Node.js中执行此操作的帖子 。
咕unt声
古尔普
西兰花
在预处理器内
当链接其他资产中的资产时(例如,从LESS文件中链接到的图像),可以使预处理器工作。 本·纳德尔(Ben Nadel) 就此发表了一篇文章 。
异步CSS
随着关键CSS变得越来越重要,延迟加载CSS变得越来越重要。 还有其他一些原因也会推迟CSS的加载(也许是打印CSS或启动缓存)。
如果您要用loadCSS加载CSS(或者注入一个link标签 ),则需要更新它在JavaScript本身中请求的文件名。 与更改文件名不同,但没有什么不同。
所以
我错过了什么吗? 您的缓存清除策略是什么?
翻译自: https://css-tricks.com/strategies-for-cache-busting-css/