JSF 缓存静态资源过滤器

Posted

技术标签:

【中文标题】JSF 缓存静态资源过滤器【英文标题】:JSF Cache Static Resources Filter 【发布时间】:2013-02-10 01:31:01 【问题描述】:

如何编写一个过滤器,以按照 Google (https://developers.google.com/speed/docs/best-practices/caching) 的建议适当缓存静态资源。

创建一个将上次修改日期设置为某个静态日期的过滤器是否足够(每次服务器重新启动时都会更改)?

指定 Expires 或 Cache-Control max-age 之一很重要, 和 Last-Modified 或 ETag 之一,用于所有可缓存资源。它是 多余地指定 Expires 和 Cache-Control: max-age,或 同时指定 Last-Modified 和 ETag。

上面的链接似乎建议您需要指定 Expires 或 Cache-Control。为什么有必要?

【问题讨论】:

【参考方案1】:

如何编写一个过滤器,以按照 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 资源完成)。

【讨论】:

记住 defaultResourceMaxAge 仅在 javax.faces.PROJECT_STAGE 设置为 Production 时才有效【参考方案2】:

这是我编写缓存过滤器的方式。像魅力一样工作。

编写缓存过滤器以提高 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 浏览器中 -> 右键单击​​屏幕 -> 检查 -> 单击网络选项卡 -> 刷新屏幕。 点击图片、图标、样式表,看看您是否在响应标题

中看到以下内容

Cache-Control:max-age=2592000

同样当你刷新页面时,如果元素的状态是 304 而不是 200(来自缓存),你就完成了。

gzip 等其他性能改进

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

【讨论】:

【参考方案3】:

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

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

【讨论】:

感谢您发布您的答案!请注意,您应该在此处、此站点上发布答案的基本部分,否则您的帖子有被删除的风险See the FAQ where it mentions answers that are 'barely more than a link'. 如果您愿意,您仍然可以包含该链接,但仅作为“参考”。答案应该是独立的,不需要链接。 链接已损坏。

以上是关于JSF 缓存静态资源过滤器的主要内容,如果未能解决你的问题,请参考以下文章

Nginx静态资源部署

spring boot 1.5.4 整合redis拦截器过滤器监听器静态资源配置(十六)

前端静态资源缓存控制策略浅析

nginx缓存静态资源,只需几个配置提升10倍页面加载速度

HTTP静态资源缓存永远策略

Nginx实现静态资源的缓存