如何根据Google(https://developers.google.com/speed/docs/best-practices/caching)的建议编写适当缓存静态资源的过滤器。
是否足以创建一个过滤器,将过去修改的日期设置为某个静态日期(每次服务器重新启动时都会更改)?
指定Expires或Cache-Control max-age之一很重要, 和Last-Modified或ETag之一,用于所有可缓存资源。它是 冗余以指定Expires和Cache-Control:max-age或to 指定Last-Modified和ETag。
上面的链接似乎建议您需要指定Expires或Cache-Control。为什么这有必要?
答案 0 :(得分:26)
如何根据Google推荐的
编写适当缓存静态资源的过滤器
如果你的JSF资源意味着/resources
文件夹中的文件完全由JSF内置资源处理程序(and thus all referenced via <h:outputStylesheet>
, <h:outputScript>
, <h:graphicImage>
, #{resource}
and thus not via the plain HTML way)处理,那么你不需要为作业添加一个过滤器。要满足Google建议,您唯一需要做的就是将Expires
日期设置得更远。它默认为7天(604800000毫秒),而Google Page Speed和Yahoo YSlow等性能测试工具建议至少30天(2592000000毫秒)。
在Mojarra中,您可以使用web.xml
中的以下上下文参数进行设置:
<context-param>
<param-name>com.sun.faces.defaultResourceMaxAge</param-name>
<param-value>2592000000</param-value> <!-- 30 days -->
</context-param>
在MyFaces中使用以下内容:
<context-param>
<param-name>org.apache.myfaces.RESOURCE_MAX_TIME_EXPIRES</param-name>
<param-value>2592000000</param-value> <!-- 30 days -->
</context-param>
是否足以创建一个过滤器,将过去修改的日期设置为某个静态日期(每次服务器重新启动时都会更改)?
您不需要也不需要设置Last-Modified
。 JSF资源处理程序已经自动执行了此操作。如果您因为更改了资源而强制按资源重新加载,则使用资源库版本控制。另请参阅What is the JSF resource library for and how should it be used?
请注意,每次服务器重新启动时更改它都没有意义,因为Expires
标头仍然会告诉浏览器仅在一段时间后重新测试缓存的有效性。在浏览器实际请求资源之前,浏览器永远不会注意到资源Last-Modified
的变化。迫使浏览器难以完全重新请求资源的唯一因素是URL的更改,通常通过更改的查询字符串参数值来实现。 JSF资源库版本控制就是这样做的。
另请注意,OmniFaces CombinedResourceHandler
使用资源的上次修改时间戳作为查询字符串中的“资源版本”而不是资源库版本。因此,如果您正在使用它,则不一定需要资源库版本控制机制。
上面的链接似乎建议您需要指定Expires或Cache-Control。为什么这有必要?
Expires
标头告诉浏览器何时通过条件GET请求重新测试缓存资源的有效性。因此,在此之前,浏览器不会这样做,并将继续使用缓存中的那个。 Cache-Control
告诉浏览器使用哪种缓存策略。请注意,当它设置为例如no-cache
代替public
,Expires
标题无效。另请注意,缺少Cache-Control
标头意味着public
(由JSF资源完成)。
答案 1 :(得分:4)
以下是我编写缓存过滤器的方法。就像一个魅力。
在web.xml中添加以下内容
<filter>
<filter-name>cache</filter-name>
<filter-class>au.com.webapp.config.CacheFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>cache</filter-name>
<url-pattern>*.xhtml</url-pattern>
</filter-mapping>
在你的au.com.webapp.config包中创建一个类CacheFilter,如下所示:
package au.com.webapp.config;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class CacheFilter implements Filter {
private static long maxAge = 86400 * 30; // 30 days in seconds
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse httpResponse = (HttpServletResponse) response;
String uri = ((HttpServletRequest) request).getRequestURI();
if (uri.contains(".js") || uri.contains(".css") || uri.contains(".svg") || uri.contains(".gif")
|| uri.contains(".woff") || uri.contains(".png")) {
httpResponse.setHeader("Cache-Control", "max-age=" + maxAge);
}
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("Cache Filter started: ");
}
@Override
public void destroy() {
}
}
要查看您的内容是否已经使用gzip和缓存,请执行 Google Chrome 浏览器 - &gt;右键点击你的屏幕 - &gt;检查 - &gt;点击网络标签 - &gt;刷新你的屏幕。 点击图片,图标,样式表,看看您是否在响应标题
中看到了以下内容 Cache-Control:max-age=2592000
另外,当你刷新页面时,如果元素的状态是304而不是200(来自缓存),你就完成了。
有关可以显着改变您的webapp或网站性能的其他简单性能改进,请参阅以下链接,例如gzip或JQuery UI组件。 https://stackoverflow.com/a/35567464/5076414
答案 2 :(得分:1)
无需编写过滤器,Tomcat 7已经有ExpiryFilter,可以将Cache-Control添加到您的资源中。它可以基于修改或访问时间。请参阅此博客: