JSF缓存静态资源过滤器

时间:2013-02-24 23:25:00

标签: jsf servlet-filters browser-cache

如何根据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。为什么这有必要?

3 个答案:

答案 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代替publicExpires标题无效。另请注意,缺少Cache-Control标头意味着public(由JSF资源完成)。

答案 1 :(得分:4)

以下是我编写缓存过滤器的方法。就像一个魅力。

编写缓存过滤器以提高JSF / Servlet屏幕静态内容的性能

在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(来自缓存),你就完成了。

其他性能改进,例如gzip

有关可以显着改变您的webapp或网站性能的其他简单性能改进,请参阅以下链接,例如gzip或JQuery UI组件。 https://stackoverflow.com/a/35567464/5076414

答案 2 :(得分:1)

无需编写过滤器,Tomcat 7已经有ExpiryFilter,可以将Cache-Control添加到您的资源中。它可以基于修改或访问时间。请参阅此博客:

http://kahimyang.info/kauswagan/howto_blogs/1574-improving_page_load_with_mod_expires_and_expiresfilter_in_jsf_applications