添加文件过期或缓存头(性能优化)
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 30d;#设置30天过期
}
location ~ .*\.(js|css)?$
{
expires 1h;#设置1小时过期
}
什么是 Expires headers?
Expires headers 是服务器端返回的头信息,它可以告知浏览器某一文件的过期时间,浏览器会根据这个时间来决定是否从服务器下载该文件,还是从本地缓存里获取这个文件 。
为文件设置过期时间不仅是为了减小从服务器下载的负担(不断的重复下载没有更改过的内容,是在浪费加载时间),更主要的是为减少对服务器的HTTP请求数量。
当你访问一个站点时,浏览器负责与服务器之间通信,获取需要下载的文件。然后将它们显示出来。随着富媒体时代的到来,网页内容越来越丰富,从服务器端下载的内容也就越多。
如果一个页面只有少数几张图片,重复的加载也许影响不大。但是如果页面需要加载的文件过多,并且尺寸都很大,重复的下载,就会严重影响加载时间。
它是如何工作的?
“Expires headers”的工作内容可以说是相当的简单。它会告知浏览器,某个文件可以在浏览器缓存目录中保留多久,这样后续页面中如果有这个文件时,就不需要重新下载了。虽然用户第一次访问时,需要下载所有文件,但使用“Expires headers”可以帮助用户在后续的访问时节约加载时间。
你可以为某一类型的文件甚至是某一指定的文件设置过期时间。这样你就可以为经常需要变动的内容,单独设置过期时间了。
为什么设置它很重要?
添加“Expires headers”配置,不但可以减少用户对浏览器的HTTP请求次数,减轻服务器负担。同样它也可以为你的用户节约宝贵的时间。
如何添加“Expires headers”?
首先你需要确定,那些文件经常有变动,以及那一类的文件不会经常改动。一些常用的文件类型如下:
images: jpg, gif, png
favicon/ico
javascript
css
然后,你应该确定一下某类型文件的过期时间。一般来说,图片类型的文件不会经常改变,网站的图标(favicon)可能很长时间不会改变,而脚本和样式文件可能会经常需要变化。
我们可以在.htaccess或者httpd.conf文件中设置“Expires headers”,在改动之前你最后对它们做一上备份。
打开.htaccess或者httpd.conf文件,在里面追加如下内容:
<IfModule mod_expires.c>
# Enable expirations
ExpiresActive On
# Default directive
ExpiresDefault "access plus 1 month"
</IfModule>
首先我们启用"Expires headers"扩展,然后指定一个默认的过期时间,然后可以继续增加某一类型文件的过期时间,你需要根据个人网站的状况改变参数,配置内容类似如下:
# My favicon
ExpiresByType image/x-icon "access plus 1 year"
# Images
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/jpg "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
# CSS
ExpiresByType text/css "access 1 month"
# Javascript
ExpiresByType application/javascript "access plus 1 year"
完整的配置如下:
<IfModule mod_expires.c>
# Enable expirations
ExpiresActive On
# Default directive
ExpiresDefault "access plus 1 month"
# My favicon
ExpiresByType image/x-icon "access plus 1 year"
# Images
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/jpg "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
# CSS
ExpiresByType text/css "access 1 month"
# Javascript
ExpiresByType application/javascript "access plus 1 year"
</IfModule>
Cache-Control的使用机制
Cache-Control属性值是在server端配置的,不同的服务器有不同的配置,web服务器 apache、nginx、IIS,应用服务器tomcat等配置都不尽相同;以Apache为例,在http.conf中做如下配置
第一段代码是指jgp/jepg/png/gif/ico等类型的文件缓存1年。单位是秒,你可以自己算算。第二段代码是指css和js这种文件类型缓存1个月。通常来说一些长期不变的图片比如logo,背景图片,字体,icon小图标等变化一般不会频繁,可以设的久一点。可以设个一年半载,具体设多久见仁见智了。新闻,广告等频繁更新的图片,不用缓存。css,js文件更新的周期会短一点,可以设置一周或者一个月。
如果用户浏览器缓存了页面的资源,你又想让用户更新怎么办呢?你可以通过修改该资源的名称来实现。名字改了,浏览器会当做不同的资源,这样就可以实现了。在大型项目中不可能频繁的更新文件名,要通过全局的配置文件版本的方法。你可以想想有没有更好的方式。详细的Cache-Control可以参考这篇文章How to use Cache-Control
Expires的使用机制
expires也是需要在服务端配置(具体配置也根据服务器而定),expires添加的是该资源过期的日期,浏览器会根据该过期日期与客户端时间对比,如果过期时间还没到,则会去缓存中读取该资源,如果已经到期了,则浏览器判断为该资源已经不新鲜要重新从服务端获取。通过这种方式,可以实现直接从浏览器缓存中读取,而不需要去服务端判断是否已经缓存,避免了这次http请求。值得注意的是expires时间可能存在客户端时间跟服务端时间不一致的问题。所以,建议expires结合Cache-Control一起使用,大型网站中一起使用的情况比较多见。
实际测试效果
未使用expires和cache-control的情况(已经访问过,资源已经缓存):
我使用chrome的network来查看页面加载的情况,利用Live HTTP Headers这个google浏览器插件来监听http发起请求的状况。
打开网址http://stevesouders.com/hpws/expiresoff.php(一个yahoo!工程师的测试demo,拿来用下),注意是打开;(特别注意,刷新的话无论你是否缓存浏览器都会重新发起HTTP请求来判断是否更新)
监听器插件的图片
可以看出虽然是304,但是实际上发起了HTTP请求。
使用Expires和Cahce-Control的情况(已经访问过,资源已经缓存)
打开网址http://stevesouders.com/hpws/expireson.php(一个yahoo!工程师的测试demo,拿来用下)。
可以看出图片都是来自缓存,time为0也可以看出没有发起http请求。
作者:yitalalww
链接:https://www.jianshu.com/p/f331d5f0b979