【问题标题】:CSS and Javascript loads too long on Tomcat 8 or 9Tomcat 8 或 9 上的 CSS 和 Javascript 加载时间过长
【发布时间】:2016-10-04 21:39:22
【问题描述】:

我有 JSF 应用程序,当我在嵌入式 Jetty 服务器上运行它时它运行良好。但是,当我将它部署到 Tomcat 8.0.35 时,加载 CSS 和 Javascript 文件需要 20 多秒。我在 Amazon AWS 服务器上运行的 Tomcat 和在本地机器上运行的 Tomcat 上遇到了同样的问题。这些都是小文件,在 Jetty 服务器上加载时间都不超过 35 毫秒。

Tomcat 日志并未表明应用程序存在任何类型的问题,而且这种情况在每个页面上都会发生,甚至在登录页面上也是如此。

我在 Tomcat 8 和 Tomcat 9 上遇到了同样的问题,但在 Tomcat 7 上没有。

如果有人能告诉我应该检查什么或如何搜索问题的根源,我将不胜感激。

编辑: 这是登录页面的 h:head 部分,但其他地方都存在同样的问题:

<h:head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script src="https://use.typekit.net/zvv0dgl.js"></script>
<script>try{Typekit.load({ async: true });}catch(e){}</script>
<title>ProSolo - Sign in</title>
<link href="#{request.contextPath}/resources/css2/bootstrap.min.css" rel="stylesheet" />
<link href="#{request.contextPath}/resources/css2/awesome-bootstrap-checkbox.css" rel="stylesheet" />
<link href="#{request.contextPath}/resources/css2/style.css" rel="stylesheet" />

编辑 2 (web.xml):

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:web="http://java.sun.com/xml/ns/javaee"
     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
     metadata-complete="true" version="3.0">
    <display-name>ProSolo</display-name>
    <servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>
    <servlet>
    <servlet-name>fileServlet</servlet-name>
    <servlet-class>org.prosolo.services.upload.FileServlet</servlet-class>
    <init-param>
        <param-name>basePath</param-name>
        <param-value>/WEB-INF/resources</param-value>
    </init-param>
    </servlet>
    <servlet-mapping>
    <servlet-name>fileServlet</servlet-name>
    <url-pattern>/files/*</url-pattern>
    </servlet-mapping>
    <filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
    </filter>
    <filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
    </filter-mapping>
    <filter>
    <filter-name>opensessioninview</filter-name>
    <filter-class>org.prosolo.core.spring.OpenSessionInViewFilter</filter-class>
    <init-param>
        <param-name>singleSession</param-name>
        <param-value>true</param-value>
    </init-param>
    </filter>
    <filter-mapping>
    <filter-name>opensessioninview</filter-name>
    <url-pattern>/*</url-pattern>
    </filter-mapping>
    <filter>
    <filter-name>Login Partial Response Redirect</filter-name>
    <filter-class>org.prosolo.core.jsf.LoginPartialResponseRedirectFilter</filter-class>
    </filter>
    <filter-mapping>
    <filter-name>Login Partial Response Redirect</filter-name>
    <url-pattern>/*</url-pattern>
    </filter-mapping>
    <filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    <filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    </filter-mapping>
    <!--  
    <filter>
      <filter-name>PrimeFaces FileUpload Filter</filter-name>
      <filter-class>org.prosolo.core.jsf.primefaces.FileUploadFilter</filter-class>
    </filter>
    <filter-mapping>
      <filter-name>PrimeFaces FileUpload Filter</filter-name>
      <servlet-name>Faces Servlet</servlet-name>
    </filter-mapping>
    -->
    <filter>
    <filter-name>gzipResponseFilter</filter-name>
    <filter-class>org.omnifaces.filter.GzipResponseFilter</filter-class>
    </filter>
    <filter-mapping>
    <filter-name>gzipResponseFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>ERROR</dispatcher>
    </filter-mapping>
    <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        org.prosolo.core.spring.SpringConfig,
        org.prosolo.core.spring.security.SpringSecurityConfig,
        org.prosolo.core.hibernate.HibernateConfig
    </param-value>
    </context-param>
    <context-param>
    <param-name>contextClass</param-name>
    <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
    </context-param>
    <context-param>
    <param-name>com.sun.faces.expressionFactory</param-name>
    <param-value>com.sun.el.ExpressionFactoryImpl</param-value>
    </context-param>
    <!-- added for p:fileUpload, options: auto, native, commons-->
    <context-param>
    <param-name>primefaces.UPLOADER</param-name>
    <param-value>native</param-value>
    </context-param>
    <listener>
    <listener-class>org.prosolo.app.BeforeContextLoader</listener-class>
    </listener>
    <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <listener>
    <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
    </listener>
    <listener>
    <listener-class>org.prosolo.app.AfterContextLoader</listener-class>
    </listener>
    <listener>
    <listener-class>org.apache.myfaces.webapp.StartupServletContextListener</listener-class>
    </listener>
    <listener>
    <listener-class>org.prosolo.web.SessionCountListener</listener-class>
    </listener>
    <error-page>
    <exception-type>javax.faces.application.ViewExpiredException</exception-type>
    <location>/login.xhtml</location>
    </error-page>
    <error-page>
    <exception-type>java.lang.Throwable</exception-type>
    <location>/login.xhtml</location>
    </error-page>
    <session-config>
    <session-timeout>10</session-timeout>
    </session-config>
    <!-- In Production change javax.faces.FACELETS_REFRESH_PERIOD to -1 and javax.faces.PROJECT_STAGE to 'Production' -->
    <!-- In Development change javax.faces.FACELETS_REFRESH_PERIOD to 1 and javax.faces.PROJECT_STAGE to 'Development' -->
    <context-param>
    <param-name>javax.faces.FACELETS_REFRESH_PERIOD</param-name>
    <param-value>-1</param-value>
    </context-param>
    <context-param>
    <param-name>javax.faces.PROJECT_STAGE</param-name>
    <param-value>Production</param-value>
    </context-param>
    <context-param>
    <param-name>com.sun.faces.enableRestoreView11Compatibility</param-name>
    <param-value>true</param-value>
    </context-param>
    <context-param>
    <description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description>
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
    <param-value>server</param-value>
    </context-param>
    <context-param>
    <param-name>javax.faces.DATETIMECONVERTER_DEFAULT_TIMEZONE_IS_SYSTEM_TIMEZONE</param-name>
    <param-value>true</param-value>
    </context-param>
    <context-param>
    <param-name>javax.faces.FACELETS_LIBRARIES</param-name>
    <param-value>/WEB-INF/functions.taglib.xml</param-value>
    </context-param>
    <context-param>
    <param-name>org.apache.el.parser.SKIP_IDENTIFIER_CHECK</param-name>
    <param-value>true</param-value>
    </context-param>
    <context-param>
    <param-name>primefaces.THEME</param-name>
    <param-value>none</param-value>
    </context-param>
    <context-param>
    <param-name>primefaces.PUBLIC_CAPTCHA_KEY</param-name>
    <param-value>***************************</param-value>
    </context-param>
    <context-param>
    <param-name>primefaces.PRIVATE_CAPTCHA_KEY</param-name>
    <param-value>********************************</param-value>
    </context-param>
    <context-param>
    <param-name>org.apache.myfaces.NUMBER_OF_VIEWS_IN_SESSION</param-name>
    <param-value>20</param-value>
    </context-param>
    <context-param>
    <param-name>org.apache.myfaces.SERIALIZE_STATE_IN_SESSION</param-name>
    <param-value>false</param-value>
    </context-param>
    <context-param>
    <param-name>org.apache.myfaces.COMPRESS_STATE_IN_SESSION</param-name>
    <param-value>false</param-value>
    </context-param>
    <context-param>
    <param-name>org.apache.myfaces.annotation.SCAN_PACKAGES</param-name>
    <param-value>org.prosolo.web</param-value>
    </context-param>
    <context-param>
    <param-name>org.apache.myfaces.STRICT_JSF_2_ALLOW_SLASH_LIBRARY_NAME</param-name>
    <param-value>true</param-value>
    </context-param>
    <context-param>
    <param-name>org.apache.myfaces.USE_ENCRYPTION</param-name>
    <param-value>false</param-value>
    </context-param>
    <context-param>
    <param-name>org.apache.myfaces.ALGORITHM</param-name>
    <param-value>AES</param-value>
    </context-param>
    <context-param>
    <param-name>org.apache.myfaces.SECRET</param-name>
    <param-value>Q0hBTkdFIFNFQ1JFVCEhIQ==</param-value>
    </context-param>
    <context-param>
    <param-name>org.apache.myfaces.MAC_SECRET</param-name>
    <param-value>Q0hBTkdFIE1BQ1NFQ1JFVA==</param-value>
    </context-param>
    <context-param>
    <param-name>javax.faces.RESOURCE_EXCLUDES</param-name>
    <param-value>.class .jsp .jspx .properties .xhtml .xml</param-value>
    </context-param>
    <context-param>
    <param-name>javax.faces.FACELETS_BUFFER_SIZE</param-name>
    <param-value>165535</param-value>
    </context-param>

    <listener>
    <listener-class>org.ocpsoft.rewrite.servlet.impl.RewriteServletRequestListener</listener-class>
    </listener>

    <listener>
    <listener-class>org.ocpsoft.rewrite.servlet.impl.RewriteServletContextListener</listener-class>
    </listener>

    <filter>
    <filter-name>OCPsoft Rewrite Filter</filter-name>
    <filter-class>org.ocpsoft.rewrite.servlet.RewriteFilter</filter-class>
    <async-supported>true</async-supported>
    </filter>
    <filter-mapping>
    <filter-name>OCPsoft Rewrite Filter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
    <dispatcher>ERROR</dispatcher>
    </filter-mapping>
    <!-- <filter>
     <filter-name>Save Page Url In Session Filter</filter-name>
     <filter-class>org.prosolo.core.jsf.SavePageUrlInSessionFilter</filter-class>
   </filter>
   <filter-mapping>
     <filter-name>Save Page Url In Session Filter</filter-name>
     <url-pattern>/*</url-pattern>
     <dispatcher>FORWARD</dispatcher>
     <dispatcher>REQUEST</dispatcher>
   </filter-mapping> -->
</web-app>

【问题讨论】:

    标签: javascript css jsf tomcat


    【解决方案1】:

    我建议使用 &lt;script&gt;&lt;link&gt; 直接链接到 CSS 文件和 java 脚本,为了克服相对路径的问题,请在 URL 前加上 #{request.contextPath},例如,引用 resources/css/app.css,使用: &lt;link href="#{request.contextPath}/resources/css/app.css" rel="stylesheet" /&gt;

    欲了解更多信息,请查看我在 dzone 的文章“Java Server Faces in Real-Life Applications”。

    【讨论】:

    • 感谢您的回答 Jalal。但是,它完全按照您建议的方式连接,例如。你还有什么想法吗?
    • 实际上,所有以这种方式引用的资源在Tomcat 8和9上都会加载20秒,并且从网络加载的jquery.min.js会立即加载。
    • 你能粘贴你的 部分吗?
    • 你的 web.xml 中有很多东西会导致问题,而框架和 api 的这种混合会导致混乱(myfaces、primefaces、spring)我的建议如下,现在: (1)从你的web.xml中删除所有东西(过滤器和侦听器)和测试(很可能它会起作用),如果解决了,然后开始一一添加过滤器,直到问题解决。如果没有,请告诉我。 (2) 对于未来的瓶颈:向过滤器和侦听器添加大量日志记录,以包含毫秒的时间戳,以便能够跟踪此类延迟的日志。
    • 好主意。添加过滤器后,我来到 GzipResponseFilter 作为导致问题的那个,并且该问题已在此处报告github.com/omnifaces/omnifaces/issues/65,因此我只需将omnifaces 的版本更改为具有错误修复的版本。感谢您的帮助。
    猜你喜欢
    • 2012-08-23
    • 2012-11-01
    • 2014-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-20
    相关资源
    最近更新 更多