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 缓存静态资源过滤器的主要内容,如果未能解决你的问题,请参考以下文章