Quantcast

Thymeleaf 3 upgrade / rendering

classic Classic list List threaded Threaded
10 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.
Loading...