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 > > > >> > > >
