Have you already tried profiling your use case? That would reveal a
lot more information about what could be slow. Profiling with Async
Profiler and/or Java Flight Recorder could help spot what changes in
the performance profiles between the versions.
Async Profiler works best when used on Linux, and it has a mode
(jfrsync) where it also integrates with Java Flight Recorder by
combining recordings into a single .jfr file. Comparing the profiles
from the different versions of Grails could help in finding out the
root cause.
By comparison, I mean observing the flamegraphs and also comparing the
GC and other metrics with Java Flight Recorder. The OSS GUI for Java
Flight Recorder is Eclipse Mission Control: https://adoptium.net/jmc.
It's very easy to get started with it.
It's possible to configure both Async Profiler and JFR to start
profiling when the process starts and dump the profile when it stops,
so no GUI is required for that, however GUI also provides interactive
profiling. For analysis of the .jfr file, Async Profiler has jfrconv,
which can create nice flamegraphs, and the Eclipse Mission Control UI
can be used for other analysis.
I hope this helps make progress.

-Lari


On Wed, 24 Sept 2025 at 16:17, Gianluca Sartori <[email protected]> wrote:
>
> As suggested, we tested building a JAR. The results are good enough for us
> to consider them production quality, although performance is still almost
> twice as slow on common use cases (small pages with few objects to render).
> Groovy INDY is set to OFF.
>
>
> Grails 6/Groovy 3
> =================
>
> Stress Test:
> TRANSITION rendered in 1564ms
> TRANSITION rendered in 1292ms
> TRANSITION rendered in 1249ms
> TRANSITION rendered in 1288ms
>
> Page 1:
> TRANSITION rendered in 32ms
>
> Page 2:
> TRANSITION rendered in 43ms
>
>
> Grails 7/Groovy 4
> =================
>
> Stress Test:
> TRANSITION rendered in 1607ms
> TRANSITION rendered in 1422ms
> TRANSITION rendered in 1444ms
> TRANSITION rendered in 1470ms
>
> Page 1:
> TRANSITION rendered in 64ms
>
> Page 2:
> TRANSITION rendered in 73ms
>
>
>
> Gianluca Sartori
> --
> https://dueuno.com
>
>
> On Mon, 22 Sept 2025 at 15:03, James Daugherty via dev <
> [email protected]> wrote:
>
> > Hi Gianluca,
> >
> > When you say debug mode, you are doing all of your performance testing with
> > debug mode? I would highly encourage you to test with runWar or runJar
> > without debug mode.  Debug mode has historically always been significantly
> > slower.
> >
> > -James
> >
> > On Mon, Sep 22, 2025 at 4:30 AM Gianluca Sartori <[email protected]>
> > wrote:
> >
> > > Hi David,
> > >
> > > Thank you for your reply, we've done the tests on the same code, the
> > > "only" difference is Grails 6 VS Grails 7. Tests are not in
> > > production, but locally from the IDE in debug mode. Yet grails 6 VS
> > > Grails 7 tests share the same environment.
> > >
> > > We have a hierarchy of objects to build any view, those objects go
> > > from a simple container to a Table that has a Body, a set of Rows,
> > > each row has many Cells each cell can have a Label or many other
> > > components.
> > >
> > > This hierarchy is rendered with GSP fragments (templates) so yes we
> > > may have a lot going on under a rendered Table. I know that most of
> > > the time is taken by the "layout engine" (?) because we've optimized
> > > the Table rendering just by limiting the number of components, thus
> > > embedding them instead of including them as separate templates.
> > >
> > > On the slowness, it is consistently slow but the warmup I've done was
> > > a couple of browser refreshes by hand just to compile the GSPs, I
> > > didn't go through a loop of 10.000 requests.
> > >
> > > About dynamically compiling GSP in production, we haven't specified
> > > anything in the standard 'application.yml' config, but my senses feel
> > > that even in production the first rendering takes longer I've always
> > > thought it was because of GSP compilation and it is not a problem to
> > > us.
> > >
> > >
> > > Gianluca Sartori
> > > --
> > > https://dueuno.com
> > >
> > > On Sun, 21 Sept 2025 at 17:18, David Estes <[email protected]> wrote:
> > > >
> > > > A bit surprising . Is it consistently slower or just the first few
> > > times? Once it warms up it should still be ok for production no? Or are
> > > you  dynamically compiling gsp in prod?
> > > >
> > > > I agree it should be further optimized , but dismissing it for initial
> > > performance seems aggressive. Unless it’s consistently significant on
> > > slowness .
> > > >
> > > > That being said those render times in general seem very high for most
> > > GSP I even render . Is there a large amount of taglib usage, layouts,
> > etc?
> > > Narrowing down what might be causing overall slow page renders may be
> > worth
> > > a gander. With those times I doubt it’s strictly GSP.
> > > >
> > > >
> > > > > On Sep 21, 2025, at 9:26 AM, Gianluca Sartori <[email protected]>
> > > wrote:
> > > > >
> > > > > I guess we need to find a solution refactoring GSP, rendering of
> > > pages must
> > > > > be as fast as possible.
> > > > >
> > > > > I will try to find time to give it a look but this means Grails 7 is
> > > out of
> > > > > scope for us at the moment.
> > > > >
> > > > > Unless we can run it with Groovy 3, i don’t like this, but if it
> > > solves the
> > > > > issue it would make it for us, do you think that would be possible?
> > > > >
> > > > > Should we switch to another templare solution? Which one would you
> > > suggest?
> > > > >
> > > > > Cheers,
> > > > >
> > > > > Gianluca Sartori
> > > > > --
> > > > > https://dueuno.com
> > > > >
> > > > >
> > > > > ---------- Forwarded message ---------
> > > > > From: Daniel Sun <[email protected]>
> > > > > Date: Sat, 20 Sep 2025 at 01:46
> > > > > Subject: Re: GSP generation, Groovy 4 slower than Groovy 3?
> > > > > To: <[email protected]>
> > > > >
> > > > >
> > > > > Hi Gianluca,
> > > > >
> > > > >   Groovy 4 enables indy by default. It's slower to run for the first
> > > time
> > > > > because the initialization for invokedynamic is quite expensive. (
> > See
> > > > > also: https://bugs.openjdk.org/browse/JDK-8278540 )
> > > > >
> > > > >   It ususally gains best performance when the methods are invoked for
> > > > > 10000+ times.
> > > > >
> > > > >   BTW, Jochen proposed some optimization for current design of indy,
> > > the
> > > > > performance for the first runs will be much better when the
> > > optimization is
> > > > > done.
> > > > >
> > > > > Cheers,
> > > > > Daniel Sun
> > > > >
> > > > >> On 2025/09/16 12:18:41 Gianluca Sartori wrote:
> > > > >> Hi folks,
> > > > >>
> > > > >> we have started porting Dueuno to Grails 7/Groovy 4. We have a
> > > > >> stress-test that generates a big table (200 columns x 100 rows) with
> > > > >> GSP (we are doing server-side rendering).
> > > > >>
> > > > >> I'm reporting the tests below. Is there something we can do to get
> > > > >> back the performances we had with Grails 6/Groovy 3?
> > > > >>
> > > > >> Even with INDY turned off we are almost 1sec slower on the tests,
> > more
> > > > >> than 2x slower on normal pages:
> > > > >>
> > > > >> Grails 7/Groovy 4
> > > > >> Page 1 - TRANSITION rendered in 185ms
> > > > >> Page 2 - TRANSITION rendered in 453ms
> > > > >>
> > > > >> Grails 6/Groovy 3
> > > > >> Page 1 - TRANSITION rendered in 83ms
> > > > >> Page 2 - TRANSITION rendered in 280ms
> > > > >>
> > > > >> TESTS
> > > > >> ======
> > > > >> Same URL (Table stress-test), 4 requests after 3 warmup requests
> > (not
> > > > >> shown, cold-running the app from intelliJ), measuring the Grails
> > > > >> render() execution time.
> > > > >>
> > > > >> 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
> > > > >>
> > >
> >

Reply via email to