I am new to thymeleaf and I am facing some serious performance issues. I'm using theymeleaf version 2.1.2
In one of my pages, I am using thymeleaf each loop for displaying items. When I start tomcat server, Thymeleaf takes around 10 seconds to to render a page with 20 items. Then I click on the page again, this time it's taking 20 seconds. The third time I click on this page, thymeleaf take 30+ seconds. The performance is getting worse and worse after each click. I have embeded my log here. Has anyone experienced similar problem before? Thanks in advance.
19:05:55,719 DEBUG "http-bio-8080"-exec-8 thymeleaf.TemplateEngine:1051 - [THYMELEAF]["http-bio-8080"-exec-8] STARTING PROCESS OF TEMPLATE "layout/default" WITH LOCALE en
19:05:55,719 DEBUG "http-bio-8080"-exec-8 thymeleaf.TemplateEngine:1150 - [THYMELEAF]["http-bio-8080"-exec-8] Starting process on template "layout/default" using mode "HTML5"
19:05:56,582 DEBUG Http Connection Cleanup conn.PoolingClientConnectionManager:292 - Closing expired connections
19:05:56,582 DEBUG Http Connection Cleanup conn.PoolingClientConnectionManager:286 - Closing connections idle longer than 10000 MILLISECONDS
19:05:57,147 DEBUG "http-bio-8080"-exec-8 thymeleaf.TemplateEngine:1159 - [THYMELEAF]["http-bio-8080"-exec-8] Finished process on template "layout/default" using mode "HTML5"
19:05:57,150 DEBUG "http-bio-8080"-exec-8 thymeleaf.TemplateEngine:1065 - [THYMELEAF]["http-bio-8080"-exec-8] FINISHED PROCESS AND OUTPUT OF TEMPLATE "layout/default" WITH LOCALE en
19:05:57,150 DEBUG "http-bio-8080"-exec-8 TemplateEngine.TIMER:1071 - [THYMELEAF]["http-bio-8080"-exec-8][layout/default][en] TEMPLATE "layout/default" WITH LOCALE en PROCESSED IN 1431288703 nanoseconds (approx. 1431ms)
Are you calling any kind of business logic inside your iteration? For example, retrieving things from database as they are rendered or something.... maybe a very complex or database-calling "toString()" method or something like that?
Your log says your page renders in 1.43 seconds (not 10 seconds as you say) which is quite a lot. It certainly doesn't look like the problem is in the Thymeleaf side... A thymeleaf page merely iterating 20 elements from a collection would normally render in a millisecond or so...
Your log also shows some warnings related to expired connections... can it be that you are not properly closing your database connections? this would mean you are exhausting your DB connection pool, which makes your threads wait until existing connections time-out. This matches quite well your described scenario of obtaining slower executions each time...
Thanks. I have put the code inside the raw tag and I have found the root cause of this problem. Seems it's due to the #list.contains() function. I removed those two functions and the loading time reduced five fold.
I have updated the code. Now it's fully visible. I do have some display logic inside. But no call to database. Sorry I probably have taken the wrong log(it is log for another page). It does take around 10 seconds for 20 items.(each item is complex object with embedded object) After removing the two #lists.contains() method, I managed to load the page within 2 second. But there is still one problem. I deployed this on the server and after one day, the performance of the server degrades significantly. (ie the time taken to load the same page is getting longer and longer).
Thymeleaf is not caching any of your data, so your performance degradation shouldn't be caused by your execution of the template. The #lists.contains() method uses the "equals()" method in your objects, are they Strings as they look like in your code sample? Maybe their implementation of "equals()" is complex? What implementation of "java.util.List" is "x.flag"? Is it a hibernate or JPA-managed collection? Are your entities being transparently persisted (and therefore their properties being transparently retrieved from DB while you iterate them?)
I ask this because #lists.contains() simply delegates to the "contains" method of your java.util.List implementation, and it's pretty difficult for me to understand how some executions of List.contains(), even with a quite large list, can provoke a 5x execution time difference if your lists are something standard like ArrayList's --which probably are not. So I'm inclined to think your "x" objects are JPA or hibernate entities whose properties are being transparently hydrated during template execution, which is causing your problems. I still think this looks quite a lot like a DB access issue...
Btw... I don't know how many images you have per "x" instance, but your flags seem like they could be computed before iterating the images, not inside the iteration...
I actually found out the cause of the slowness. Aside from the two #lists.contains() method, I have some other utility methods such as #map.size() etc. Seems there are some issues with those utility methods. I don't know exactly the root cause of this, but after shifting those method calls to my beans methods, ie (having a attribute declared in my bean instead of using those utility methods to get size etc), everything works fine for me. Hope it helps for people with the same problem.
I just ran into a similar issue. One view, which was very similar to a dozen others and had been working fine, suddenly started taking 15 to 30 seconds to render. It was testing two lists with isEmpty and outputting numerous variables within two sets of nested loops but wasn't doing anything that could possibly take more that 100 milliseconds like most of the other views.
From the log files my java code and database lookups were quickly eliminated as suspects and the trouble area was narrowed down to about 50 lines of code using Thymeleaf pre-processing, expression utility object methods, and some i18n substitutions. Commenting portions of these lines would decrease load times to 4 or 5 seconds but only commenting all of them brought the times back to normal. This persisted through many undeploy / deploy cycles, a few Tomcat stop / start cycles, and deployment to another server.
I wasted many hours debugging, using my most advanced Google Foo, and cursing Thymeleaf for ruining my life (project deliverable due). Then the first result for the simple search phrase "Thymeleaf slowness" brought me here.
Following jackyxuebin's advice I moved from Spring 4.0.0 to 4.1.1 and voila the problem disappeared and my sanity was restored.
Many thanks to jackyxuebin, daniel for all his hard work on Thymeleaf, and all who contributed to this thread. Also, apologies for all the unjust things I may have accused Thymeleaf of during fits of hopelessness and frustration ;-)