Thymeleaf Select Option Performance Issue

时间:2018-04-19 00:53:41

标签: spring-mvc thymeleaf

我最近一直在搞乱Spring MVC 5和Thymeleaf 3.0并注意到一些奇怪的事情。我已经开始从网站上的教程实现下拉列表,并注意到一些性能问题。如果我使用以下代码,我的页面需要大约5.5秒才能呈现大约100个项目的下拉列表。

<select th:field="*{item}">
    <option th:each="item : ${items}" 
            th:value="${item.getId()}" 
            th:text="${item.getValue()}"></option>
</select>

另一方面,如果我使用以下代码,我的页面将在大约150毫秒内呈现。

<div th:each="item : ${items}">
    <span th:text="${item.getId()}"/>
    <span th:text="${item.getValue()}"/>
</div>

我已遍历控制器中的项目列表并打印出值,以查看从数据库获取数据是否有任何减速,但是从控制器中抓取项目立即发生。我也尝试在select标签中渲染不同的html元素用于测试目的,即使它不是有效的html,它仍然可以快速呈现页面。

我在页面渲染上遇到极端延迟的唯一一次是当我使用th时:每个选项内部的select标签内部。 Thymeleaf是否以不同的方式处理选择标签?我认为如果相同的项目列表,调用相同的方法可以通过循环divs在130ms内呈现页面,它应该能够以相当的速率创建选项,而不是花5.5秒。

之前有没有人遇到这样的问题?我做了一些搜索,发现在Thymeleaf中存在性能问题循环,但这些情况有超过100,000条记录,我的列表大约有100个项目。任何帮助将不胜感激。

更新

我已经将问题缩小到表现不佳:field =“* {item}”。如果我运行以下代码,页面会立即加载。

<select>
    <option th:each="item : ${items}" 
            th:value="${item.getId()}" 
            th:text="${item.getValue()}"></option>
</select>

一旦我尝试使用th:field =“* {item}”绑定选择,页面会挂起大约5.5秒。是否有任何理由为什么使用th:field绑定会导致滞后问题?

2 个答案:

答案 0 :(得分:0)

对于选择/选项部分,页面创建花费了超过一分钟的时间,同样遇到了问题。我的代码有点不同,因为我在表中有选项,但是我认为这并不重要。我的初始代码如下:

<tr th:each="scorePart,rowStat : ${song.scoreParts}">
    <td>
        <select th:field="*{scoreParts[__${rowStat.index}__].instrument}">
            <option th:each="i2 : ${allInstruments}"
                    th:value="${i2.id}"
                    th:text="${i2.name}">bla</option>
        </select>
    </td>
    <td> more data... </td>
</tr>

但是随后我将ID添加到了字段部分:

<tr th:each="scorePart,rowStat : ${song.scoreParts}">
    <td>
        <select th:field="*{scoreParts[__${rowStat.index}__].instrument.id}">
            <option th:each="i2 : ${allInstruments}"
                    th:value="${i2.id}"
                    th:text="${i2.name}">bla</option>
        </select>
    </td>
    <td> more data... </td>
</tr>

然后一切正常。两种情况的结果相同,只有第二种没有延迟。

答案 1 :(得分:0)

这篇文章很旧,但是希望我可以帮助遇到同样问题的人。几天前发生在我身上。请求将字段映射到对象列表时花费超过40秒的时间。而且,如果仅将属性th:field映射到ID,则在将其返回给控制器时,Spring不会序列化整个对象,仅序列化ID。我发现的解决方案是用不同的语法重新创建Thymeleaf产生的输出。

代替此:

<select th:field="*{item}">
    <option th:each="item : ${items}" 
            th:value="${item.getId()}" 
            th:text="${item.getValue()}"></option>
</select>

执行以下操作:

<select name="item" id="item">
    <option th:each="it : ${items}"
            th:selected ="${it.getId()} == *{item.getId()}"
            th:value="${item.getId()}" 
            th:text="${item.getValue()}"></option>
</select>

输出将相同,但是页面加载速度将提高30倍,并且将保留整个对象“ item”。