【问题标题】:JSF 2 Improving page loading performanceJSF 2 提高页面加载性能
【发布时间】:2013-02-02 13:32:00
【问题描述】:

我正在尝试调整 jsf 2 页面的加载性能。 以下是性能测量的一些跟踪: - 首次页面加载:全球页面加载时间为 1404 毫秒,尤其是在“渲染响应”阶段

+++++ ++++++ +++++ [PHASE LISTENER] START PHASE RESTORE_VIEW 1 +++ ++++++ +++++ +++++ ++++++ +++++ [PHASE LISTENER] END PHASE RESTORE_VIEW 1 执行时间 = 21ms +++ ++++++ + ++++ +++++ ++++++ +++++ [PHASE LISTENER] START PHASE APPLY_REQUEST_VALUES 2 +++ ++++++ +++++ +++++ ++++++ +++++ [ PHASE LISTENER] END PHASE APPLY_REQUEST_VALUES 2 执行时间 = 1ms +++ ++++++ +++++ +++++ ++++++ +++++ [PHASE LISTENER] START PHASE PROCESS_VALIDATIONS 3 +++ ++++++ +++++ 2013-02-02 14:25:13,205 [http -bio-8083-exec-4] 调试 com.azone.web.form.CarCaracteristicForm - 检查 avnSearchParamsBoImpl DI: OK +++++ ++++++ +++++ [PHASE 监听器] END PHASE PROCESS_VALIDATIONS 3,执行时间 = 60 毫秒 +++ ++++++ +++++ +++++ ++++++ +++++ [PHASE LISTENER] 开始 PHASE UPDATE_MODEL_VALUES 4 +++ ++++++ +++++ +++++ ++++++ + ++++ [PHASE LISTENER] END PHASE UPDATE_MODEL_VALUES 4 执行时间 = 0ms +++ ++++++ +++++ +++++ ++++++ +++++ [PHASE LISTENER] 启动 PHASE INVOKE_APPLICATION 5 +++ ++++++ +++++ +++++ ++++++ + ++++ [PHASE LISTENER] END PHASE INVOKE_APPLICATION 5 执行时间 = 0ms +++ ++++++ +++++ +++++ ++++++ +++++ [PHASE LISTENER] 开始 PHASE RENDER_RESPONSE 6 +++ ++++++ +++++ 2013-02-02 14:25:13,909 [http-bio-8083- exec-4] 信息 com.azone.web.UserSessionBean - 所用时间 SecurityContextHolder.getContext().getAuthentication 0 毫秒 2013-02-02 14:25:13,914 [http-bio-8083-exec-4] 信息 com.azone.web.UserSessionBean - 匿名用户:访客!用户已设置 到新的 +++++ ++++++ +++++ [PHASE LISTENER] END PHASE RENDER_RESPONSE 6 执行时间 = 1318 毫秒 +++ ++++++ +++++ 全局页面执行时间 = 1404ms

  • 第二次页面加载:全局页面加载时间为 656 毫秒,尤其是在“渲染响应”阶段

+++++ ++++++ +++++ [PHASE LISTENER] START PHASE RESTORE_VIEW 1 +++ ++++++ +++++ +++++ ++++++ +++++ [PHASE LISTENER] END PHASE RESTORE_VIEW 1 执行时间 = 37ms +++ ++++++ + ++++ +++++ ++++++ +++++ [PHASE LISTENER] START PHASE APPLY_REQUEST_VALUES 2 +++ ++++++ +++++ +++++ ++++++ +++++ [ PHASE LISTENER] END PHASE APPLY_REQUEST_VALUES 2 执行时间 = 0ms +++ ++++++ +++++ +++++ ++++++ +++++ [PHASE LISTENER] START PHASE PROCESS_VALIDATIONS 3 +++ ++++++ +++++ +++++ ++++++ + ++++ [PHASE LISTENER] END PHASE PROCESS_VALIDATIONS 3 执行时间 = 0ms +++ ++++++ +++++ +++++ ++++++ +++++ [PHASE LISTENER] 开始 PHASE UPDATE_MODEL_VALUES 4 +++ ++++++ +++++ +++++ ++++++ + ++++ [PHASE LISTENER] END PHASE UPDATE_MODEL_VALUES 4 执行时间 = 0ms +++ ++++++ +++++ +++++ ++++++ +++++ [PHASE LISTENER] 启动 PHASE INVOKE_APPLICATION 5 +++ ++++++ +++++ +++++ ++++++ + ++++ [PHASE LISTENER] END PHASE INVOKE_APPLICATION 5 执行时间 = 0ms +++ ++++++ +++++ +++++ ++++++ +++++ [PHASE LISTENER] 开始 PHASE RENDER_RESPONSE 6 +++ ++++++ +++++ 2013-02-02 14:28:16,535 [http-bio-8083- exec-3] 信息 com.azone.web.UserSessionBean - 所用时间 SecurityContextHolder.getContext().getAuthentication 0 毫秒 2013-02-02 14:28:16,536 [http-bio-8083-exec-3] 信息 com.azone.web.UserSessionBean - 匿名用户:访客!用户已设置 到新的 +++++ ++++++ +++++ [PHASE LISTENER] END PHASE RENDER_RESPONSE 6,执行时间 = 614ms +++ ++++++ +++++ 全局页面执行时间 = 656ms

这是我的页面来源:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:a4j="http://richfaces.org/a4j"
    xmlns:rich="http://richfaces.org/rich">

<ui:composition template="../templates/template.xhtml">

    <ui:define name="contentWrapper">   

<f:metadata>
    <f:viewParam name="itemFamily" value="#{newItemAdd.itemFamily}" />  
    <f:event     type="preRenderView"     listener="#{newItemAdd.initFamily}" />
</f:metadata>

    <h:form>
        <rich:panel id="mainFilters">

            <h:outputText value="property 1" />

            <h:panelGrid columns="2" cellspacing="6" width="600">

                <h:panelGrid columns="3" cellspacing="6" width="300">

                    <h:outputText value="First name: " />
                    <h:inputText id="fname" value="#{newItemAdd.userForm.user.firstName}">
                        <f:validateRequired />
                        <rich:validator />
                    </h:inputText>
                    <rich:message for="fname" />

                    <h:outputText value="Tel:" />
                    <h:inputText id="tel" value="#{newItemAdd.userForm.currentPhone}">
                        <f:validateRequired />
                        <rich:validator />
                    </h:inputText>
                    <rich:message for="tel" />

                    <h:outputText value="Email:" />
                    <h:inputText id="email" value="#{newItemAdd.userForm.user.email}">
                        <f:validateRequired />
                        <rich:validator />
                    </h:inputText>
                    <rich:message for="email" />

                </h:panelGrid>

                <h:panelGrid columns="2" cellspacing="6" width="300">


                    <h:outputText value="Governorate" />
                    <h:selectOneMenu id="govList"
                        value="#{newItemAdd.itemForm.region.governorate.governorateId}"
                        valueChangeListener="#{newItemAdd.itemForm.processGovernoratesChange}">
                        <f:selectItem id="govdefitm" itemValue="0"
                            itemLabel="All Governorates" />
                        <f:selectItems id="governoratesList"
                            value="#{newItemAdd.itemForm.governoratesList}" />
                        <f:ajax event="change" execute="@this" render="munList" />
                    </h:selectOneMenu>

                    <h:outputText value="Municipality" />
                    <h:selectOneMenu id="munList"
                        value="#{newItemAdd.itemForm.region.municipality.municipalityId}">
                        <f:selectItem id="mundefitm" itemValue=""
                            itemLabel="All Municipalities" />
                        <f:selectItems id="municipalitiesList"
                            value="#{newItemAdd.itemForm.municipalitiesList}" />
                    </h:selectOneMenu>

                </h:panelGrid>
            </h:panelGrid>

            <h:panelGrid columns="2" cellspacing="6" width="600">

                <h:panelGrid columns="3" cellspacing="6" width="300">

                    <h:outputText value="Property 2" />                 
                    <h:inputText id="property2" value="#{newItemAdd.itemForm.property2}" />
                    <rich:message for="property2" />

                    <h:outputText value="Property 3" />
                    <h:selectOneMenu id="propList"
                        value="#{newItemAdd.itemForm.property3}"
                        valueChangeListener="#{newItemAdd.itemForm.processProperty3Change}">
                        <f:selectItem id="mandefitm" itemValue="0" itemLabel="All porperties" />
                        <f:selectItems id="propList"
                            value="#{newItemAdd.itemForm.property3List}" />
                        <f:ajax event="change" execute="@this" render="modList" />
                    </h:selectOneMenu>
                    <rich:message for="propList" />
                </h:panelGrid>

                <h:panelGrid columns="3" cellspacing="6" width="300">
                    <h:outputText value="property 4" />
                    <h:inputText id="prop4" value="#{newItemAdd.itemForm.property4}" />
                    <rich:message for="prop4" />

                    <h:outputText value="Property 4" />
                    <h:selectOneMenu id="prop4List"
                        value="#{newItemAdd.itemForm.model}">
                        <f:selectItem id="moddefitm" itemValue="" itemLabel="All Properties" />
                        <f:selectItems id="prop41List" value="#{newItemAdd.itemForm.properties4List}" />
                    </h:selectOneMenu>
                    <rich:message for="prop4List" />
                </h:panelGrid>

            </h:panelGrid>
        </rich:panel>

        <!-- -->

        <rich:panel id="optionalFilters">

            <h:panelGrid columns="2" cellspacing="6" width="600">

                <h:panelGrid columns="2" cellspacing="6" width="400">
                    <h:outputText value="Property 5" rendered="#{!newItemAdd.type1}"/>
                    <h:selectOneMenu id="property5" rendered="#{!newItemAdd.type1}"
                        value="#{newItemAdd.itemForm.property5}"
                        layout="pageDirection">
                        <f:selectItem id="propId" itemValue="0"
                            itemLabel="Any property" />
                        <f:selectItems value="#{newItemAdd.itemForm.properties5List}" var="item"
                            itemLabel="#{item.label}" itemValue="#{item.value}" />
                    </h:selectOneMenu>

                    <h:outputText value="Property 7 " rendered="#{newItemAdd.type2}"/>
                    <h:selectOneMenu id="property7" rendered="#{newItemAdd.type2}"
                        value="#{newItemAdd.itemForm.family1.property7.property7Id}">
                        <f:selectItem id="trmdefitm" itemValue="0"
                            itemLabel="Any property" />
                        <f:selectItems id="property7List"
                            value="#{newItemAdd.itemForm.property7List}" />
                    </h:selectOneMenu>

                    <h:outputText value="Property 8" />
                    <h:selectOneMenu id="property8List"
                        value="#{newItemAdd.itemForm.property8}">
                        <f:selectItem id="bdydefitm" itemValue=""
                            itemLabel="All properties" />
                        <f:selectItems id="propList" value="#{newItemAdd.itemForm.property8List}" />
                    </h:selectOneMenu>

                    <h:outputText value="Property 9 " rendered="#{newItemAdd.type2}"/>
                    <h:selectOneMenu id="property9" rendered="#{newItemAdd.type2}"
                        value="#{newItemAdd.itemForm.family1.property9.property9Id}">
                        <f:selectItem id="trndefitm" itemValue="0"
                            itemLabel="Any Property" />
                        <f:selectItems id="prop9List"
                            value="#{newItemAdd.itemForm.property9List}" />
                    </h:selectOneMenu>

                    <h:outputText value="Property 10 " />
                    <h:selectOneMenu id="prop10"
                        value="#{newItemAdd.itemForm.property10}">
                        <f:selectItem id="minprcdefitm" itemValue="" itemLabel="Any Property" />
                        <f:selectItems id="prop10List"
                            value="#{newItemAdd.itemForm.property10List}" />
                    </h:selectOneMenu>
                    <h:outputText value=" ?? " />

                    <h:outputText value="property" />
                    <h:outputText value="property ??" />
                    <h:outputText value="property ? property ? property ?" />
                    <h:outputText value="property ? property ? property ?" />
                    <h:outputText value="property ??" />

                </h:panelGrid>


                <h:outputText value="property" />

            </h:panelGrid>

            <h:panelGrid id="property11">
                <h:outputText value="property 11" />
                <h:inputTextarea value="#{newItemAdd.itemForm.property11}" cols="50"
                    rows="10" />
            </h:panelGrid>

            <h:panelGrid columns="2" columnClasses="top,top">
                <rich:fileUpload fileUploadListener="#{newItemAdd.picsManager.listener}"
                    id="upload" acceptedTypes="jpg, gif, png, bmp"
                    ontyperejected="alert('Only JPG, GIF, PNG and BMP files are accepted');"
                    maxFilesQuantity="3">
                    <a4j:ajax event="uploadcomplete" execute="@none" render="info" />
                </rich:fileUpload>

                <h:panelGroup id="info" layout="block">
                    <rich:panel bodyClass="info">
                        <f:facet name="header">
                            <h:outputText value="Uploaded Files Info" />
                        </f:facet>
                        <h:outputText value="No files currently uploaded"
                            rendered="#{newItemAdd.picsManager.size==0}" />
                        <rich:dataGrid columns="1" value="#{newItemAdd.picsManager.files}" var="file"
                            rowKeyVar="row">
                            <rich:panel bodyClass="rich-laguna-panel-no-header">
                                <h:panelGrid columns="2">                               

                                    <a4j:mediaOutput element="img" mimeType="image/jpeg"
                                        createContent="#{newItemAdd.picsManager.paint}" value="#{row}"
                                        style="width:100px; height:100px;" cacheable="false">
                                        <f:param value="#{fileUploadBean.timeStamp}" name="time" />
                                        <a4j:ajax event="click" execute="newItemAdd.picsManager.paint" ></a4j:ajax>

                                    </a4j:mediaOutput>

                                    <h:panelGrid columns="2">
                                        <h:outputText value="File Name:" />
                                        <h:outputText value="#{file.name}" />
                                        <h:outputText value="File Length(bytes):" />
                                        <h:outputText value="#{file.length}" />
                                    </h:panelGrid>
                                </h:panelGrid>
                            </rich:panel>
                        </rich:dataGrid>
                    </rich:panel>
                    <br />
                    <a4j:commandButton action="#{newItemAdd.picsManager.clearUploadData}"
                        render="info, upload" value="Clear Uploaded Data"
                        rendered="#{newItemAdd.picsManager.size>0}" />
                </h:panelGroup>
            </h:panelGrid>

        </rich:panel>
        <rich:messages />
        <a4j:commandButton value="Go!"
            action="#{newItemAdd.testCheck}" />
    </h:form>

    </ui:define>
</ui:composition>

</html>

提前感谢您的帮助。

更新: 我已将我的表单分成如下所述的 2 个表单,但它似乎没有帮助:(

    <h:form>   


        <ui:include src="file_test_part_1.xhtml"/>
        <!-- -->
        <ui:include src="file_test_part_2.xhtml"/>

        <rich:messages />
        <a4j:commandButton value="Go!"
            action="#{newCarAdd.testCheck}" />
    </h:form>

【问题讨论】:

  • 你有一个巨大的表格,里面有太多的组件。将您的组件分成多个表单中的较小块
  • 我已经把它分成两部分,就像我的更新中描述的那样,但它似乎没有帮助:(。

标签: performance jsf-2 richfaces performance-testing


【解决方案1】:

您可以采取一些措施来提高屏幕的性能

  1. GZIP 过滤器将显着减少初始加载时间。它在传输到客户端浏览器时压缩页面内容(动态和静态内容)。参考https://stackoverflow.com/a/35567295/5076414
  2. 您还可以实现一个 cacheFilter 来带来 您的屏幕与基于 JavaScript 的 UI 相当。这将缓存屏幕的静态内容,例如图标、图像、样式表、javascript 等。您可以控制要缓存的内容和要排除的内容。参考https://stackoverflow.com/a/35567540/5076414
  3. 对于客户端 UI 组件,您可以使用 Primefaces,即 JQuery 基于用户界面。

如何验证我的屏幕是否使用 gzip 和缓存

要查看您的内容是否已经使用 gzip 和缓存,请在您的 Google Chrome 浏览器中 -> 右键单击​​屏幕 -> 检查 -> 单击网络选项卡 -> 刷新屏幕。 点击图片、图标、样式表,看看您是否在响应标题

中看到以下内容

Cache-Control:max-age=2592000 如果元素的状态为 304(来自缓存)

Content-Encoding:gzip 如果元素的状态为 200

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多