如何避免大型JSF视图的部分http响应刷新?

时间:2018-03-21 13:47:52

标签: jsf render facelets

今天我花了几个小时在我们的Web应用程序中使用JSF facelets重现一个非常奇怪的UI行为:在某些情况下,在服务器端真正完成渲染整个视图之前,UI部分在Web浏览器中呈现。

最后,所有这些都归结为一个包含大量元素的JSF视图 - 在我的例子中是子菜单的项目。似乎有一些阈值会触发响应的部分刷新

这是一个可视化演示效果的最小化示例:

<?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 lang="de" xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<h:head>
    <style>
        td {
            vertical-align: top;
        }
    </style>
</h:head>
<h:body>

    <h1>EURNEU-10056</h1>

    <table>
        <tr>
            <td>
                <ol>
                    <ui:repeat value="#{bean.strings(10)}" var="str">
                        <li><h:outputText value="#{str}" /></li>
                    </ui:repeat>
                </ol>
                <h:outputText value="#{bean.delay(2000)}" />
            </td>
            <td>
                <ol>
                    <ui:repeat value="#{bean.strings(10)}" var="str">
                        <li><h:outputText value="#{str}" /></li>
                    </ui:repeat>
                </ol>
                <h:outputText value="#{bean.delay(2000)}" />
            </td>
            <td><ol>
                    <ui:repeat value="#{bean.strings(10)}" var="str">
                        <li><h:outputText value="#{str}" /></li>
                    </ui:repeat>
                </ol>
                <h:outputText value="#{bean.delay(2000)}" />
            </td>
        </tr>
    </table>

</h:body>
</html>

这个简单的视图使用以下bean生成一定数量的字符串,并在3列中的每一列之后在 2000ms 的渲染中添加一些人工延迟

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import javax.faces.bean.ManagedBean;

@ManagedBean
public class Bean implements Serializable {

    private static final long serialVersionUID = 1L;

    public List<String> strings(int count) {
        List<String> all = new ArrayList<>();
        for (int i = 0; i < count; i++) {
            all.add(UUID.randomUUID().toString());
        }
        return all;
    }

    public String delay(int delay) {
        try {
            Thread.sleep(delay);
        }
        catch (InterruptedException ex) {
            // NOP;
        }
        return String.format("This string has been delayed for %d ms!", delay);
    }

}

浏览器在处理请求时显示以下阶段:

partial rendering another partial rendering final rendering

如果在生成视图时降低使用的字符串数量,则仅在呈现阶段的最后刷新响应。

我有什么办法可以避免部分渲染吗?(除了降低元素数量)

PS:我们使用JBoss EAP v7.0.9作为服务器。应用程序本身非常复杂。

1 个答案:

答案 0 :(得分:0)

我们认为在web.xml中定义Facelets缓冲区大小可以解决这个问题。

<!-- We raise the buffer size to avoid partial rendering of complex pages. -->
<context-param>
    <param-name>javax.faces.FACELETS_BUFFER_SIZE</param-name>
    <param-value>1024000</param-value>
</context-param>

该设置和生成的HTML的结构定义了当下,浏览器开始呈现响应。在我们的例子中,菜单已经可以渲染,并且比预期的要早得多。