今天我花了几个小时在我们的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);
}
}
浏览器在处理请求时显示以下阶段:
如果在生成视图时降低使用的字符串数量,则仅在呈现阶段的最后刷新响应。
我有什么办法可以避免部分渲染吗?(除了降低元素数量)
PS:我们使用JBoss EAP v7.0.9作为服务器。应用程序本身非常复杂。
答案 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的结构定义了当下,浏览器开始呈现响应。在我们的例子中,菜单已经可以渲染,并且比预期的要早得多。