Thymeleaf 3 upgrade / rendering

classic Classic list List threaded Threaded
20 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Thymeleaf 3 upgrade / rendering

divad91@hotmail.com
This post was updated on .
Hi,

I just moved from thymeleaf 2.1.4 to 3.0.5 by following the migration guide but I see a huge rendering issue. I don't know how this is related to Thymeleaf but my page takes now  sometimes 2 seconds more to get displayed correctly. In the beginning the scroll bar if almost the same heigth of the page then it decrease to get really small.  The page contains quite a lot of stock.

If I revert the migration to Thymeleaf 3 the problem does not occurs anymore (same css, same js).
The only thing that I change is some html to be html 5 compliant (remove void element end tag, raw text elements closing tag).

Don't know if this could be related but my page contains many fragments.

I tried removing all our css and javascript and I still have the problem.
Also, I tried adding a simple alert in my footer and the delay is really long before I see the alert.

* tested in IE 11 and firefox. Same behavior.

Any idea what could cause this ?

Thanks
David
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Thymeleaf 3 upgrade / rendering

divad91@hotmail.com
Ok just found the issue.

My templates were separated in 2 folders (pages and fragments).
I was using 2 template resolvers and needed to set the "check existence" to true otherwise I had an exception when a fragment was trying to be resolve in the pageTemplateResolver.

// templateResolver.setCheckExistence(true);

I moved every templates into 1 folder and disabled the checkExistence property. Now it renders fast !
If I enable it again, it become super slow.

So now my question is, how can I put my files into differents folder without affecting the performance ?
I have over 50 fragments and 20 pages. Would like to have separated folder for clarity.

Thanks
David



Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Thymeleaf 3 upgrade / rendering

danielfernandez
Administrator
You can use the "viewNames" property in view resolvers in order to specify the patterns that your template/fragment names have to match in order to be resolvable by each of the resolvers.

Note however that, if the problem is you have a very large amount of fragments being called in (and therefore their existence on the file system checked for each of them during resolution), enabling the template cache should make this only happen the first time you use each of those templates/fragments. From then on, once cached, there would be no need to resolve templates or fragments again. This is, unless your fragments need being hot-replaced and would not allow caching (which is definitely recommended otherwise)
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Thymeleaf 3 upgrade / rendering

divad91@hotmail.com
Ok thanks I will try that. I don't have a pattern right now for my templates but I will add one to compare.

The template caching is disabled by default in our code (locally only for developpers). Our version is not deployed into our test server so I was not able to compare locally vs our real server with caching enabled.

Thank you.
David
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Thymeleaf 3 upgrade / rendering

divad91@hotmail.com
In reply to this post by danielfernandez
Hi,

I don't see how to use the "viewNames" on the viewResolver.

This is my folder structure :

|- webapp
    |- WEB_INF
       |- templates
          |- fragments
           ----> frag1.html
          |- pages
           ----> page1.html

I have 1 view Controller.
        @Bean(name = "viewResolver")
        public ThymeleafViewResolver getViewResolver() {
                final ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
                viewResolver.setTemplateEngine(getTemplateEngine());
                return viewResolver;
        }
2 template engine

        @Bean(name = "templateEngine")
        public SpringTemplateEngine getTemplateEngine() {
                final SpringTemplateEngine templateEngine = new SpringTemplateEngine();
                templateEngine.setEnableSpringELCompiler(true);
                final Set<ITemplateResolver> templateResolvers = new HashSet<ITemplateResolver>(2);
                templateResolvers.add(this.getPageTemplateResolver());
                templateResolvers.add(this.getFragmentTemplateResolver());
                templateEngine.setTemplateResolvers(templateResolvers);
                return templateEngine;
        }

and 2 view resolvers

        @Bean(name = "fragmentTemplateResolver")
        public SpringResourceTemplateResolver getFragmentTemplateResolver() {
                final SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
                templateResolver.setApplicationContext(this.applicationContext);
                templateResolver.setCheckExistence(false);
                templateResolver.setPrefix("/WEB-INF/templates/fragments/");
                templateResolver.setSuffix(".html");
                templateResolver.setTemplateMode(TemplateMode.HTML);
                templateResolver.setOrder(1);
                templateResolver.setCacheable(!EnvironmentVariable.checkForPresence(EnvironmentVariableEnum.LOCAL));
                return templateResolver;
        }

        @Bean(name = "pageTemplateResolver")
        public SpringResourceTemplateResolver getPageTemplateResolver() {
                final SpringResourceTemplateResolver templateResolver = new  SpringResourceTemplateResolver();
                templateResolver.setApplicationContext(this.applicationContext);
                templateResolver.setCheckExistence(true);
                templateResolver.setPrefix("/WEB-INF/templates/pages/");
                templateResolver.setSuffix(".html");
                templateResolver.setTemplateMode(TemplateMode.HTML);
                templateResolver.setOrder(0);
                templateResolver.setCacheable(!EnvironmentVariable.checkForPresence(EnvironmentVariableEnum.LOCAL));
                return templateResolver;
        }

Heres an example of how I include a fragment :

<th:block th:include="head :: Head" />

So I dont see how to use a pattern in my template resolvers except by renaming all my fragments and prefix them like  "frag_frag1.html" but I found this a little  bit oldschool...

"viewnames" seems to be related to the view resolver. Can we have many of them ? Seems like I need to renamed also all my templates and prefix them. Is there an other way than doing this ?

Thanks
David





Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Thymeleaf 3 upgrade / rendering

divad91@hotmail.com
In reply to this post by danielfernandez
So I changed my resolver like so

        @Bean(name = "fragmentTemplateResolver")
        public SpringResourceTemplateResolver getFragmentTemplateResolver() {
                final SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
                templateResolver.setApplicationContext(this.applicationContext);
                templateResolver.getResolvablePatternSpec().addPattern("fragments/*");
                templateResolver.setPrefix("/WEB-INF/templates/");
                templateResolver.setSuffix(".html");
                templateResolver.setTemplateMode(TemplateMode.HTML);
                templateResolver.setOrder(0);
                templateResolver.setCacheable(!EnvironmentVariable.checkForPresence(EnvironmentVariableEnum.LOCAL));
                return templateResolver;
        }

        @Bean(name = "pageTemplateResolver")
        public SpringResourceTemplateResolver getPageTemplateResolver() {
                final SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
                templateResolver.setApplicationContext(this.applicationContext);
                templateResolver.setPrefix("/WEB-INF/templates/");
                templateResolver.setSuffix(".html");
                templateResolver.setTemplateMode(TemplateMode.HTML);
                templateResolver.setOrder(0);
                templateResolver.setCacheable(!EnvironmentVariable.checkForPresence(EnvironmentVariableEnum.LOCAL));
                return templateResolver;
        }

and changes all my th:include=" by  th:include="fragments/  but I still have the same issue.
It's the fact that having 2 template resolver that seems to cause the rendering issue.

If I put all my templates in the same foler, I dont have any issues.


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Thymeleaf 3 upgrade / rendering

divad91@hotmail.com
In reply to this post by danielfernandez
Had to revert to thymeleaf 2 for now.

I have 2 problems with thymeleaf 3 that I don't know how to solve.
1. Using many resolver cause a rendering glitch. It Looks like the page is loaded by blocks. We see part of the page moving. Takes up to 2 seconds sometime to display the page. Not related to my js or css. Does the same thing if I remove all the js or css. If I revert to thymeleaf 2, the problem doesn't appears.

2. I have an issue with IE 11. Maybe it's related to the fact that the html is more strict (html 5) but
in some of my pages, I have request that never gets a response. The page is loading forever.
I try removing lots of html to see if there was something wrong somewhere but didn't find something specific. Problem occurs on "big" page. Adding 1-2 line of html reproduce the problem.. The same page works fine with thymeleaf 2...

Thanks
David
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Thymeleaf 3 upgrade / rendering

danielfernandez
Administrator
Hello David.

Would it be possible for you to provide us with a functional test project reproducing both issues?

Thanks,
Daniel.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Thymeleaf 3 upgrade / rendering

danielfernandez
Administrator
Oh by the way, one quick fix: both your template resolvers have order 0, so if checkExistence is false there is still a possibility that the wrong template resolver is still kicking in.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Thymeleaf 3 upgrade / rendering

divad91@hotmail.com
Oh good point. Ill try that.
Not sure how i can provide a functionnal test. Im working on internal transactionnal application. I don't have nothing public. Our pages are separated by many fragments.
Ill check what I can do.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Thymeleaf 3 upgrade / rendering

divad91@hotmail.com
In reply to this post by danielfernandez
So still have the same problem.

Finally, I have just one template resolver.

        @Bean(name = "templateResolver")
        public SpringResourceTemplateResolver getTemplateResolver() {
                final SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
                templateResolver.setApplicationContext(this.applicationContext);
                templateResolver.setPrefix("/WEB-INF/templates/");
                templateResolver.setSuffix(".html");
                templateResolver.setTemplateMode(TemplateMode.HTML);
                templateResolver.setOrder(0);
                templateResolver.setCacheable(true);
                return templateResolver;
        }

        @Bean(name = "templateEngine")
        public SpringTemplateEngine getTemplateEngine() {
                final SpringTemplateEngine templateEngine = new SpringTemplateEngine();
                templateEngine.setEnableSpringELCompiler(true);
                templateEngine.addTemplateResolver(this.getTemplateResolver());
                return templateEngine;
        }

        @Bean(name = "viewResolver")
        public ThymeleafViewResolver getViewResolver() {
                final ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
                viewResolver.setTemplateEngine(getTemplateEngine());
                return viewResolver;
        }


For all my fragment, I include them by prefixing them with "fragments/myFragment :: MyFragment".


How does the template engine works ? Is there multiple interaction with the server for resolving a page template ? When I check my http request, I only see 1 POST (post/get/redirect pattern) and 1 GET containing the entire page but I feel like theres many interactions.

If I save my page (save as html) and open it the problem does not occur but when coming from the server I have the issue. With caching enable, my page take 779ms to be processed. So it does not look like a performance issue.

I try turning off the spel compiler but it's 200% worst. The page takes an eternity to load. That's why I think there many interactions with the server but I can't figure out since I don't see the request.

Logs doesn't help me much either. All I see is stuff related to the cache.

ex:
[EXPRESSION_CACHE][CACHE_MISS] Cache miss in cache "EXPRESSION_CACHE" for key "spel|nextMetadata.visible".
[EXPRESSION_CACHE][CACHE_REMOVE][500] Max size exceeded for cache "EXPRESSION_CACHE". Removing entry for key "spel|studentType.metadata.visible". New size is 500.
[EXPRESSION_CACHE][CACHE_ADD][500] Adding cache entry in cache "EXPRESSION_CACHE" for key "spel|nextMetadata.visible". New size is 500.


Any idea/clarification ? Thanks
David

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Thymeleaf 3 upgrade / rendering

danielfernandez
Administrator
Your configuration looks OK as a default one. I mean, it would be a good configuration for most people and there is no reason why you would have any kind of performance issue at the Thymeleaf side, given your templates seem to be local files.

When you are measuring times, are you taking these times from Thymeleaf's TIMER logger (set "org.thymeleaf.TemplateEngine.TIMER" to TRACE)? or what you are measuring is the entire request-response cycle? if it's the latter, please take into account that you are not measuring template execution, but rather your entire application (Spring controllers, database access, etc.)

As for HTTP calls, Thymeleaf does not perform any internal HTTP calls to retrieve your templates, from your configuration I see they are local resources. So they are directly read from the file system using Spring's resource resolution mechanism.

Spring's SpEL compiler affects the potential performance of the expressions used in your templates. If turning your SpEL compiler off makes the page run 200% slower, then I'm guessing you have a really, really huge number of ${...} expressions or these expressions execute some really complicated logic inside your Model objects. Also, note the SpEL compiler improved vastly from Spring 4.2 onwards.

Anyway, this point reached we would really need a reproduction project in order to know what is happening in your specific scenario. Something we could execute, verify your issue/s, and then debug and see what's going on there...

Regards,
Daniel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Thymeleaf 3 upgrade / rendering

divad91@hotmail.com
Thanks for your time !

The time I give was with the thymeleaf timer logger.

Yes we have a huge amount of expressions. Our pages contains many fragment that call other fragment and every thing is manage server side.

For example, all our inputs fields are included that way :

        <input th:fragment="InputFrag(fieldStr, fieldId)"
                th:with="attr=(${attr}!=null?${attr} + ', data-fieldType=InputFrag':'data-fieldType=InputFrag'), maxLength=(${maxlength}!=null?${maxlength}:''), size=(${size}!=null?${size}:'')"
                th:class="(${inputType} == 'radio' or ${inputType} == 'checkbox'?'':'form-control')"
                th:if="*{__${fieldStr}__.metadata.visible}"
                th:type="(${inputType}!=null?${inputType}:'text')"
                th:id="'fld_' + ${fieldId}"
                th:classappend="(${inputClass}!=null?${inputClass}:'')"
                th:placeholder="(${placeholder}!=null?${placeholder}:'')"
                th:disabled="*{__${fieldStr}__.metadata.readOnly}"
                th:title="*{__${fieldStr}__.metadata.tooltip}"
                th:attr="__${attr}__"
                th:field="*{__${fieldStr}__.value}"
                th:maxlength="(*{__${fieldStr}__.metadata.maxLength}!=null?*{__${fieldStr}__.metadata.maxLength}: ${maxLength} )"
                th:value="${value}"
                th:text="${text}"
                th:size="${size}"/>

That the example of an input text only but have this for all kinds of form elements. Every thing is in the bean, populated by the server. So yeah we have a lots of expressions :).
I just don't understand the link with thymeleaf and my UI glicth. With the new version, it's really faster but got that weird UI glicth...

Ill try to build a project to reproduce the issue. Could take a few weeks Im out of town for 2 weeks.

Thanks
David
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Thymeleaf 3 upgrade / rendering

divad91@hotmail.com
This post was updated on .
In reply to this post by danielfernandez
Ok so I had a little of spare time to test that problem again.

A few people of my job took a look also and we don't understand the behavior.
I included 2 pictures of the performance tool in chrome.
One running with thymeleaf 2.1.4 and the other one with thymeleaf 3.0.5. Same html page and data.

Thymeleaf2
Thymeleaf3

With thymeleaf 3, the server response is really fast compare to thymeleaf 2.   3.6 seconds vs 16.6 seconds.
But the problem I have and that I don't understand is that the rendering with thymeleaf 3 took 647ms and with thymeleaf 2 197.ms.  So the rendering is almost 3 time slower. Any idea of how this could be related to thymeleaf ?

I build a dummy demo project using the project
https://github.com/jmiguelsamper/thymeleaf3-spring-helloworld
You can download mine with my changes at https://www.dropbox.com/s/wuqzusvmrvyngc5/thymeleaf3-spring-helloworld-master.zip?dl=0
Basically, it's just 1 page that contains 7000 lines to parse.
It a bit hard to see because the response is really fast but with thymeleaf 3, you will see the yellow footer glicth a little bit with IE (worse in IE). With thymeleaf 2, the response is slow but the page load entirely in 1 block.
Again, same html page, data etc. Request content size, headers are exactly the same.

** The issue in the demo project is really not a big deal but in my project, it can take 2-3 seconds...
** I run this with eclipse luna and tomcat (via eclipse) and java 6

Thank for your time
David.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Thymeleaf 3 upgrade / rendering

danielfernandez
Administrator

I've tested your application, both with Thymeleaf 3 and Thymeleaf 2. But I would need help understanding what is exactly the situation you are looking at as an issue right now...

With Thymeleaf 3, and using Thymeleaf's TIMER log (which your example app doesn't have enabled) I see:


2017-05-29 23:50:32,764 TRACE [TIMER] (TemplateEngine.java:1110) - [THYMELEAF][http-bio-8080-exec-1][index][en][18557902][19] TEMPLATE "index [text/html]" WITH LOCALE en PROCESSED IN 18557902 nanoseconds (approx. 19ms)
2017-05-29 23:50:32,942 TRACE [TIMER] (TemplateEngine.java:1110) - [THYMELEAF][http-bio-8080-exec-1][index][en][13481881][13] TEMPLATE "index [text/html]" WITH LOCALE en PROCESSED IN 13481881 nanoseconds (approx. 13ms)
2017-05-29 23:50:33,092 TRACE [TIMER] (TemplateEngine.java:1110) - [THYMELEAF][http-bio-8080-exec-6][index][en][19049399][19] TEMPLATE "index [text/html]" WITH LOCALE en PROCESSED IN 19049399 nanoseconds (approx. 19ms)

So the page is rendered in (normally) less than 20ms.

Using Thymeleaf 2.1, I see:


2017-05-30 00:08:00,341 DEBUG [TIMER] (TemplateEngine.java:1071) - [THYMELEAF][http-bio-8080-exec-10][index][en][2109269097][2109] TEMPLATE "index" WITH LOCALE en PROCESSED IN 2109269097 nanoseconds (approx. 2109ms)
2017-05-30 00:08:03,500 DEBUG [TIMER] (TemplateEngine.java:1071) - [THYMELEAF][http-bio-8080-exec-10][index][en][2431214570][2431] TEMPLATE "index" WITH LOCALE en PROCESSED IN 2431214570 nanoseconds (approx. 2431ms)
2017-05-30 00:08:04,714 DEBUG [TIMER] (TemplateEngine.java:1071) - [THYMELEAF][http-bio-8080-exec-3][index][en][2244783018][2245] TEMPLATE "index" WITH LOCALE en PROCESSED IN 2244783018 nanoseconds (approx. 2245ms)

So rendering takes more than 2 entire seconds.

Note that in both cases, times are taken after allowing the server to warm up, i.e., after requesting several executions of the same template.

This actually makes quite a lot of sense, because the engine in Thymeleaf 3 is completely new and event-based (not DOM-based as in Thymeleaf 2.1), and this is a specially important advantage in the case of large iterations because whereas Thymeleaf 2.1 needs to create the entire model of the page being rendered in memory at the server before starting to write it to the output buffers, Thymeleaf 3 will not only start writing to the buffers right away as execution of the template starts, but also not need at all to first create the entire model of the result in memory before outputting it. Thymeleaf 3 will simply process the iteration and send rendered HTML to the browsers (actually, to the server's output buffers) as it is produced.

So Thymeleaf 3 should give you both quicker response and also quicker rendering times at the server, as it definitely is doing in your example.

As for browser rendering times (this confuses me: were you talking about times taken at the browser all the time?), it could happen that the browser actually takes more time to render the entire page because it receives HTML as it is being produced at the server (i.e. while it is actually being produced at the server), whereas in Thymeleaf 2.1 the browser has to wait for the entire HTML to be rendered at the server, so in v2.1 by the time the browser receives the first byte of HTML the rest of it will come very quickly, because it is already fully prepared at the server side and just waiting to be sent. Then maybe in Thymeleaf 3 the browser has to full-stop its renderer and wait a bit longer for the next buffer to come or something like that...

Anyway, this is a logical consequence of rendering being streamlined now and output being sent to the browser from the very first moment, and the much quicker response and total rendering times should more-than-compensate for this (as it actually does, by far and away). And anyway, rendering times at the browser... I don't see how Thymeleaf should worry about this.

So I'm not able to see what is Thymeleaf 3 doing worse in this scenario... could you please explain?

Regards,
Daniel

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Thymeleaf 3 upgrade / rendering

divad91@hotmail.com
Hi,

Yes I bean talking about browser rendering since the beginning :) ! Sorry my english is not to good and it was maybe not clear enough..
That's why the logger was not enable because I know that the "template parsing" is much faster with thymeleaf 3.

So this is exactly the issue I have. My applications contains at lot of "big page" and since with thymeleaf 3 the data is sent from the very begginning , it cause UI glitch. We see the page displayed and some components just moved after 1-2 seconds to their correct position (left menu, footer, etc). So the request is faster but the UI look scetchy.

So is there a way to tell thymeleaf 3 to wait for the entire HTML to be rendered at the server before sending data ?

Thanks
David
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Thymeleaf 3 upgrade / rendering

Emanuel
Administrator
In reply to this post by divad91@hotmail.com
So now that Thymeleaf 3 is so fast that it's streaming HTML to your browser much sooner, is that your application is now victim to browser reflows, aka "layout thrashing".  This is when, as new content is added to your page, the browser has to recalculate the sizes/styles of all affected pieces of the page, and is very often visible with pages that have a LOT of HTML in them.  All the purple seen in the Chrome dev tools is the recalculation of styles and the recalculation of layout, which with a page with complicated CSS rules or intermittent JS code, can be a real burden on a page and cause visible jumping in the UI, which you've been calling "UI glitching" in this thread.

One way I like to see this is to open the Chrome dev tools, turn on CPU throttling to as slow as you can tolerate, and then open a big page with a huge table.  I was able to do this with the example app you provided above and could see a very similar performance profile with lots of purple indicating the browser reflows.  Everything there will go towards the overall "rendering" item in the circular chart.

Almost anything can cause browser reflows.  Here's a non-exhaustive list of JS commands that can cause reflows (https://gist.github.com/paulirish/5d52fb081b3570c81e3a), and there are several pages on the internet that talk about it and what can be done about it, including this one from Google (https://developers.google.com/speed/articles/reflow).

Some things I often like to check to help reduce reflows:

 - don't run any scripts until DOMContentLoaded (the event indicating that all the HTML has been downloaded) is done to make sure that scripts don't interfere with the DOM until it's all there.  With imported scripts, this can be done with the "defer" attribute (https://html.spec.whatwg.org/multipage/scripting.html#attr-script-defer).  With inline scripts, you can listen for the event and then execute your code after that, eg:

document.addEventListener('DOMContentLoaded', function(event) {
  // Your code here
});

 - if you have to do DOM updates, schedule it to run at the next frame.  The browser tries to keep a steady 60fps and you can make critical code like DOM changes run during the next frame using requestAnimationFrame

requestAnimationFrame(function() {
  // Your code here
});

 - remove any unused CSS and try to keep your CSS selectors relatively shallow, none of these sorts of things: .class1 .class2 > .another-class:nth-child(3n-1)::not(div)

---
Something I also thought of with the demo app was that most of the reflow was caused by the gigantic blob of HTML that contains all the fragments.  So to make the transition less jarring, I wrapped that section in a <div> with a "hidden" style on it (only has the "display: none;" rule), and then waited for DOMContentLoaded to remove that style with JavaScript so that it appears in 1 big hit.

Here's the original performance profile of the demo app on my computer with CPU throttling turned on to exaggerate how much of an impact reflows are making:



Note that with all the reflows, DOMContentLoaded (the blue line indicating when all the HTML has been loaded) doesn't come along until just under 4 seconds, during which time the page was bouncing all over the place because the page elements kept needing to be recalculated by the browser.

With the trick above, here's the new performance profile:



The profile is much simpler, and DOMContentLoaded happened much sooner, at 2 seconds because we weren't slowing it all down with the reflows.  Then, when the big block of HTML was revealed, it did a large reflow calculation.  Note that this doesn't make the page faster (in the end both took about 4 seconds), but it does get rid of the UI bouncing around a lot which you complained about in a previous post.

Both ways were still much faster than when I switched the demo app to use Thymeleaf 2, which sat there and didn't give me a response for several seconds.

---
 - JS code used to remove the 'hidden' style:

document.addEventListener('DOMContentLoaded', function(event) {
  requestAnimationFrame(function() {
    document.querySelector('.hidden').classList.remove('hidden');
  });
});
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Thymeleaf 3 upgrade / rendering

divad91@hotmail.com
Wow thank you for your time and explanation. We definitively needs to analyse our html/css/js to get rid of that UI jumping and increase performance. Ill try to apply your quick solution first and then read on to do better js/css.

Thanks again !
Im done with this thread. It was not thymelead 3, just wanted to understand correctly the behavior.

David
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Thymeleaf 3 upgrade / rendering

nkramaric
Hi, I am actually having a similar issue with a server-side rendering heavy application.

I updated the Thymeleaf code to first write the entire html to a string and then write that to the response stream. https://github.com/nkramaric/thymeleaf-spring/commit/cac98400ed0ea4c4e7c19a6ac9a12e2450c8aace

This fixed most of the re-flow issues that we were seeing. When the page is streamed it seems that modern browsers behave more "reactionary" meaning they don't optimize the paints and javascript loading and parsing which is unfortunate in this case.

I would suggest that Thymeleaf have an option to not stream the page. Is this something that can be added to the as a configurable option to Thymeleaf?
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Thymeleaf 3 upgrade / rendering

Emanuel
Administrator
Might be a good idea for a feature request.  Best to do that on the GitHub page - features and bugs get a bit better looked at over there.
Loading...