原文链接(需越墙):developers.google.com/web/fundame…此作是谷歌开发者网站关于Web性能优化的入门系列文章之一,该系列的其他篇章,及对应的高级系列文章,本人后续会持续发布,欢迎大家关注。(转载请注明出处)
When someone visits a website, everything the site needs to display and operate has to come from somewhere. All the text, images, CSS styles, scripts, media files, and so on must be retrieved by the browser for display or execution. You can give the browser choices about where it can retrieve a resource from, and that can make a big difference in your page's load speed.
当某人访问一个网站时,网站需要展现和操纵的东西肯定是从某些地方来的。所有的文本,图片,CSS样式,脚本,媒体文件,等等一定都是由浏览器负责展现和执行的。你可以告诉浏览器一些可以获取这些资源的地方,而选择的地方不同会导致页面的加载速度有很大的区别。
The first time a browser loads a web page, it stores the page resources in the HTTP Cache. The next time the browser hits that page, it can look in the cache for resources that were previously fetched and retrieve them from disk,
often faster than it can download them from the network.
浏览器在第一次加载一个网页时,会将页面上的资源保存在HTTP缓存中;下次,当浏览器访问这个页面时,浏览器可以从缓存中将这些之前已经获取到的资源直接从硬盘上获取,这比从网络获取要快很多。
While HTTP caching is standardized per the Internet Engineering Task Force (IETF) specifications, browsers may have multiple caches that differ in how they acquire, store, and retain content. You can read about how these caches vary in this excellent article, A Tale of Four Caches.
”HTTP 缓存“是一项已经标准化的规范,是由互联网工程任务组(Internet Engineering Task Force (IETF))制定的,规定浏览器可以拥有多种缓存,而不同的缓存,其获取、存储,和留存方式也不一样。关于这些缓存的区别,这有一篇非常棒的文章,《四种类型的缓存的故事》(A Tale of Four Caches),你可以看下。
Of course, every first-time visitor to your page arrives with nothing yet cached for that page. Even repeat visitors may not have much in the HTTP cache; they might have manually cleared it, or set their browser to do so automatically, or forced a fresh page load with a control-key combination. Still, a significant number of your users may revisit your site with at least some of its components already cached, and that can make a huge difference in load time. Maximizing cache usage is critical to speeding up return visits.
虽然,每个第一次到达你页面的访客,在此之前是没有缓存的;即便是回访客也可能没有多少HTTP缓存;因为他们可能已经手动清除掉了,或者让浏览器自动清除掉了;他们也可能通过控制键(ctrl)组合强制刷新了页面。但不论如何,还是有可观数量的用户会回访你的网站,那个时候,他们已经至少有一些组件是之前已经缓存起来了的,这就可以带来巨大的加载时间的不同。最大化利用缓存对于回访客的回访页面加载速度的提升是至关重要的。
Enabling Caching 开启缓存
Caching works by categorizing certain page resources in terms of how frequently or infrequently they change. Your site's logo image, for example, might almost never change, but your site's scripts might change every few days. It's beneficial to you and your users to determine which types of content are more static and which are more dynamic.
缓存是基于通过按变动频繁程度来对页面资源进行的分类而工作的。例如,网站的Logo 图片,它几乎从不改动,但脚本文件可能每隔几天就会有改动。因此,对每种类型的文件的静态、动态的性质进行评估是非常有帮助的。
It's also important to remember that what we think of as browser caching may in fact take place at any intermediate stop between the original server and the client-side browser, such as a proxy cache or a content delivery network (CDN) cache.
我们对于浏览器缓存的认识同样重要,事实上,缓存可能发生在任何处于服务器和客户端之间的中间件节点上,例如代理服务的缓存和内容分发网络(CDN)中的缓存。
Cache Headers 缓存相关的头部
Two main types of cache headers, cache-control and expires, define the caching characteristics for your resources. Typically, cache-control is considered a more modern and flexible approach than expires, but both headers can be used simultaneously.
有两种主要的缓存相关的头部,Cache-Control 和 Expires,可以用来定义资源的缓存属性。通常,Cache-Control 被认为是比 Expires 更现代化、更灵活的方式,不过其实两种头部是可以同时使用的。
Cache headers are applied to resources at the server level -- for example, in the .htaccess file on an Apache server, used by nearly half of all active websites -- to set their caching characteristics. Caching is enabled by identifying a resource or type of resource, such as images or CSS files, and then specifying headers for the resource(s) with the desired caching options.
通过缓存头部来设置资源的缓存特性是在服务器上进行的——例如,Apache 服务器上的 .htaccess 文件,已经被接近一半的活跃网站所使用;缓存是通过为一个资源或者一类资源——例如图片和 CSS 文件——设置期望的缓存选项来启用的。
Cache-control
You can enable cache-control with a variety of options in a comma-delimited list. Here is an example of an Apache .htaccess configuration that sets caching for various image file types, as matched by an extension list, to one month and public access (some available options are discussed below).
应用 Cache-Control 头部时,你可以通过逗号分隔的列表来配置它的各个选项,下面是 Apache 中的 .htaccess 配置文件的一个例子,它通过文件后缀名列表匹配多种类型的图片文件,来为其设置了一个最长生存周期为一个月,及(缓存器)权限为公开(public)的缓存。
<filesMatch ".(ico|jpg|jpeg|png|gif)$">
Header set Cache-Control "max-age=2592000, public"
</filesMatch>
This example sets caching for styles and scripts, resources that are probably more likely to change than the images, to one day and public access.
下面这个列子,为样式和脚本文件——相对图片文件更新频率更高的一类资源——设置了生存周期为一天,权限为公开的缓存。
<filesMatch ".(css|js)$">
Header set Cache-Control "max-age=86400, public"
</filesMatch>
Cache-control has a number of options, often called directives, that can be set to specifically determine how cache requests are handled. Some common directives are explained below; you can find more information at the Performance Optimization section and at the Mozilla Developer Network.
Cache-Control 拥有一系列的选项,我们通常称之为 directives,他们可以用来指定如何处理对缓存资源的请求。下面是一些常用指令的讲解;更多的信息可以前往对应性能优化章节(Performance Optimization section) 和 Mozilla 开发者网络(Mozilla Developer Network)了解。
no-cache: Somewhat of a misnomer, specifies that content can be cached but, if so, it must be re-validated on each request before being served to a client. This forces the client to check for freshness but allows it to avoid downloading the resource again if it has not changed. Mutually exclusive with no-store.
no-cache: 其实这个名称并不恰当,它的意思是说,可以对内容进行缓存,但如果确实进行了缓存,那么每次请求之前必须(向服务器)进行一次验证。虽然它强制了客户端对资源进行“新鲜程度“检查,但如果资源并未发生变动则可避免再次下载。与 no-store 选项互斥。
no-store: Indicates that the content actually cannot be cached in any way by any primary or intermediate cache. This is a good option for resources that may contain sensitive data, or for resources that will almost certainly change from visit to visit. Mutually exclusive with no-cache.
no-store: 指示内容不应该以任何形式,在主要的缓存或中间件中被缓存起来。适用于那些包含敏感信息,或者那些几乎每次访问都会发生变动的数据。与
no-cache互斥。public: Indicates that the content can be cached by the browser and by any intermediate caches. Overrides the default private setting for requests that use HTTP authentication. Mutually exclusive with private.
public: 指示浏览器可以对内容进行缓存,也可以被任意中间件进行缓存。指定后,会覆盖默认是 private 的 HTTP 验证请求为 public 。与 private 指令互斥。
private: Designates content that may be stored by the user's browser, but may not be cached by any intermediate caches. Often used for user-specific, but not particularly sensitive, data. Mutually exclusive with public.
private: 指示内容可以被浏览器进行缓存,但其他任意中间件不应该缓存。通常用在特定于用户,但又不是特别敏感的数据上。与 public 指令互斥。
max-age: Defines the maximum time that the content may be cached before it must be revalidated or downloaded again from the original server. This option generally replaces the expires header (see below) and takes a value in seconds, with a maximum valid age of one year (31536000 seconds).
max-age: 指定被缓存的内容向服务重新验证或再次下载的之前的最大生存周期,这个选项通常用于代替 Expires 头(请看下文介绍),接受以秒为单位的值,最大值为一年(即31536000秒)
Expires Caching 过期型缓存
You can also enable caching by specifying expiration, or expiry, times for certain types of files, which tell browsers how long to use a cached resource before requesting a fresh copy from the server. The expires header just sets a time in the future when the content should expire. After that point, requests for the content must go back to the original server. With the newer and more flexible cache-control header, the expires header is often used as a fallback.
另外,你也可以通过设置一个过期时间的形式来设置指定文件类型的缓存,以此告诉浏览器缓存资源在重新获取一份新的之前可以被使用多长时间。Expires 头便可以通过设置一个未来的时间点,来设置内容(缓存)的过期时间。在那个时间点之后,对该内容的请求必须回到服务器上。Expires 头通常被作为替补方案与更新、更灵活的 cache-control 头一起使用。
Here's an example of how you might set up caching in the .htaccess file on an Apache server.
下面是 Apache 服务器上在 .htaccess 文件中怎样设置(这种类型的)缓存的例子:
## EXPIRES CACHING ##
ExpiresActive On
ExpiresByType image/jpg "access plus 1 year"
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/gif "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/pdf "access plus 1 month"
ExpiresByType text/x-javascript "access plus 1 month"
ExpiresByType application/x-shockwave-flash "access plus 1 month"
ExpiresByType image/x-icon "access plus 1 year"
ExpiresDefault "access plus 2 days"
## EXPIRES CACHING ##
(来源: GTmetrix)
As you can see, different types of files have different expiry dates in this example: images don't expire for a year after access/caching, while scripts, PDFs, and CSS styles expire in a month, and any file type not explicitly listed expires in two days. The retention periods are up to you, and should be chosen based on the file types and their update frequency. For example, if you regularly change your CSS, you might want to use a shorter expiry, or even none at all, and let it default to the two-day minimum. Conversely, if you link to some static PDF forms that almost never change, you might want to use a longer expiry for them.
你可以看到,在此例中,不同类型的文件设置了不同了过期时间:图片类型的文件(访问或者缓存之后)的过期时间为一年;脚本,PDF,CSS样式文件的过期时间为一个月;其他未显式地列出来的文件类型则为两天。具体的留存周期(retention periods)取决于你,而你应该基于文件的类型以及他们的更新频率来做出选择。例如,如果你经常修改你的CSS文件,那么你应该使用一个较短的过期时间,或者甚至不做设置,就采用默认的“两天”。反之,如果你引用的是一些几乎从不改变的静态PDF表单,那么你应该使用一个较长的过期时间。
Tip: Don't use an expiry greater than one year; that's effectively forever on the internet and, as noted above, is the maximum value for max-age under cache-control.
提示:不要设置超过一年的过期时间,这在因特网上相当于永远;和前面说的 cache-control 中的 max-age 一样,这是它的最大值。
Summary 总结
Caching is a reliable and low-hassle way to improve your pages' load speed and thus your users' experience. It is powerful enough to allow sophisticated nuances for specific content types, but flexible enough to allow easy updates when your site's content changes.
缓存是一种对于提升页面加载速度进而提升用户体验的可靠、低成本的方式。虽然对指定文件类型的精细控制它已经很强大了,但对于内容变动的轻易更新却还不是很灵活。
Be assertive with caching, but also be aware that if you later change a resource that has a long retention period, you may inadvertently deprive some repeat visitors of newer content. You can find a great discussion of caching patterns, options, and potential pitfalls in Caching Best Practices and Max-age Gotchas.
对于缓存我们要信任,但同时也要意识到,如果某个资源拥有一个较长的缓存周期,而之后你又对其进行了修改,那么,无意中你可能就剥夺了某些回访者看到新内容的机会。关于缓存的模式(patterns),选项(options),以及可能的一些陷阱,在《最佳缓存实践和Max-age的要点(Caching Best Practices and Max-age Gotchas)》中做了很好的探讨,你可以找来看看。