In Grails 7, the default layout engine for SiteMesh has changed.

In the previous layout engine, the solution bypassed SiteMesh completely at 
runtime as a performance optimization. I created the original optimized 
implementation over 16 years ago in commit 
https://github.com/apache/grails-core/commit/c2beeadf80a278e24526219ca8287fc3fcfc3f2b
 (the very first revision). There were many later optimizations such as 
https://github.com/apache/grails-core/commit/5b5944432aba84fa194b282d4457339ac86fa07a
 to avoid the need to use a servlet filter for the view.

The previous layout engine still exists in the code base and it can be used.
There are some comments about this implementation in 7.0.x source files:
https://github.com/apache/grails-core/blob/7.0.x/grails-gsp/grails-layout/src/main/groovy/org/apache/grails/web/layout/GSPGrailsLayoutPage.java
and
https://github.com/apache/grails-core/blob/7.0.x/grails-gsp/grails-layout/src/main/groovy/org/grails/plugins/web/taglib/RenderGrailsLayoutTagLib.groovy

As a future improvement, it would be possible to refactor grails-layout so that 
the use of SiteMesh is replaced, since it doesn't really require SiteMesh to 
provide the functionality. This refactored solution could be a better default 
than switching to SiteMesh 3.

The upgrade guide provides instructions on how to use the previous layout 
engine:
https://docs.grails.org/latest/guide/upgrading.html#_12_13_layout_plugins

Please rerun your performance tests with the grails-layout plugin.

-Lari

On 2025/09/15 10:33:13 Gianluca Sartori wrote:
> Thank you for the suggestion James,
> 
> we had improvements, but still slightly slower:
> - Is it Groovy 4 being slower than Groovy 3?
> - Did something changed in the GSP processing?
> 
> Same URL, 4 requests with 3 warmup requests (not shown).
> From slower to faster:
> 
> Grails 7 - Indy ON
> TRANSITION rendered in 4807ms
> TRANSITION rendered in 4779ms
> TRANSITION rendered in 4660ms
> TRANSITION rendered in 4699ms
> 
> Grails 7 - Indy OFF
> tasks.withType(GroovyCompile) {
>     groovyOptions.optimizationOptions.indy = false
> }
> TRANSITION rendered in 3660ms
> TRANSITION rendered in 3442ms
> TRANSITION rendered in 3510ms
> TRANSITION rendered in 3700ms
> 
> Grails 6
> TRANSITION rendered in 2853ms
> TRANSITION rendered in 2864ms
> TRANSITION rendered in 2734ms
> TRANSITION rendered in 2800ms
> 
> 
> 
> Gianluca Sartori
> --
> https://dueuno.com
> 
> On Thu, 11 Sept 2025 at 18:44, James Daugherty via dev
> <dev@grails.apache.org> wrote:
> >
> > If you disable invoke dynamic does it make a difference?  Groovy 4 switched
> > to that by default.
> >
> > -James
> >
> > On Thu, Sep 11, 2025 at 12:36 PM Gianluca Sartori <g.sart...@gmail.com>
> > wrote:
> >
> > > I've tested a single page, one created to test our own Table object
> > > generation.
> > >
> > > It's a big page so it is normal that the generation takes time. The
> > > issue is not the 3 seconds duration.
> > >
> > > The problem is that the same page, running on the same hardware, shows
> > > different generation times between Grails 6 (around 3 secs, OK) and
> > > Grails 7 (more than 4 secs - ?).
> > >
> > > Gianluca Sartori
> > > --
> > > https://dueuno.com
> > >
> > > On Thu, 11 Sept 2025 at 18:06, James Fredley <jamesfred...@apache.org>
> > > wrote:
> > > >
> > > > Do these times represent multiple requests?
> > > >
> > > > Here is some recent load testing I performed on an AWS t4g.micro with
> > > 1GB RAM against two actions with GSPs.
> > > >
> > > >
> > > ========================================================================================================================
> > > > ---- Global Information
> > > -------------------------------------------------------------|---Total---|-----OK----|----KO----
> > > > > request count
> > >             |    89,438 |    89,438 |         -
> > > > > min response time (ms)
> > >              |        26 |        26 |         -
> > > > > max response time (ms)
> > >              |       575 |       575 |         -
> > > > > mean response time (ms)
> > >             |        39 |        39 |         -
> > > > > response time std deviation (ms)
> > >              |        19 |        19 |         -
> > > > > response time 50th percentile (ms)
> > >              |        34 |        34 |         -
> > > > > response time 75th percentile (ms)
> > >              |        41 |        41 |         -
> > > > > response time 95th percentile (ms)
> > >              |        63 |        63 |         -
> > > > > response time 99th percentile (ms)
> > >              |        97 |        97 |         -
> > > > > mean throughput (rps)
> > >             |    149.06 |    149.06 |         -
> > > > ---- Response Time Distribution
> > > ----------------------------------------------------------------------------------------
> > > > > OK: t < 800 ms
> > >                                  89,438   (100%)
> > > > > OK: 800 ms <= t < 1200 ms
> > >                                      0     (0%)
> > > > > OK: t >= 1200 ms
> > >                                       0     (0%)
> > > > > KO
> > >                                       0     (0%)
> > > >
> > > ========================================================================================================================
> > > >
> > > > On 2025/09/11 14:11:36 Gianluca Sartori wrote:
> > > > > Hi folks,
> > > > >
> > > > > I've been testing our "stress-test" with grails 7.0.0-RC1, It looks
> > > > > like the GSP rendering is slower than earlier (we do server side
> > > > > rendering so for us it is crucial to keep GSP generation time & final
> > > > > weight as low as possible).
> > > > >
> > > > > This is not at all a priority at the moment, but I was wondering if
> > > > > something changed under the GSP hood or the issue may be somewhere
> > > > > else.
> > > > >
> > > > > Grails 6
> > > > > 15:58:56.608 WARN  [https-jsse-nio-9443-exec-5]
> > > > > d.elements.core.ElementsController       : Rendered TRANSITION in
> > > > > 3230ms
> > > > > 15:59:04.755 WARN  [https-jsse-nio-9443-exec-3]
> > > > > d.elements.core.ElementsController       : Rendered TRANSITION in
> > > > > 2874ms
> > > > > 15:59:13.482 WARN  [https-jsse-nio-9443-exec-1]
> > > > > d.elements.core.ElementsController       : Rendered TRANSITION in
> > > > > 3136ms
> > > > > 15:59:20.795 WARN  [https-jsse-nio-9443-exec-4]
> > > > > d.elements.core.ElementsController       : Rendered TRANSITION in
> > > > > 3121ms
> > > > >
> > > > > Grails 7
> > > > > 16:03:30.043 WARN  [https-jsse-nio-9443-exec-1]
> > > > > d.elements.core.ElementsController       : Rendered TRANSITION in
> > > > > 4608ms
> > > > > 16:03:44.926 WARN  [https-jsse-nio-9443-exec-2]
> > > > > d.elements.core.ElementsController       : Rendered TRANSITION in
> > > > > 4623ms
> > > > > 16:03:59.200 WARN  [https-jsse-nio-9443-exec-4]
> > > > > d.elements.core.ElementsController       : Rendered TRANSITION in
> > > > > 4626ms
> > > > > 16:04:49.791 WARN  [https-jsse-nio-9443-exec-9]
> > > > > d.elements.core.ElementsController       : Rendered TRANSITION in
> > > > > 4994ms
> > > > >
> > > > >
> > > > > Gianluca Sartori
> > > > > --
> > > > > https://dueuno.com
> > > > >
> > >
> 

Reply via email to