Let's say I have a PWA where two routes are SSR'ed (/dashboard and /logs) and each of those pages load a script preact.bundle.mjs.
When the user visits first /dashboard the script gets downloaded, parsed and evaluated. After navigating to /logs I know the script gets picked up from cache, but does it get parsed and evaluated again?
If the app would have been an SPA the script would not be re evaluated again, hence saving time and CPU cycles?
Is there a way to combine the benefits of both, e.g.: fast rendering due to SSR, but avoid re-evaluation of scripts on navigation events like in SPAs? Maybe with a careful orchestration of a Service Worker that would extract relevant fragments of HTML from the server response and patch the page?
Browsers' JavaScript engines like V8 take advantage of code caching to avoid having to repeatedly parse and compile the same script in a short amount of time.
It's probably sufficient to let the JS engines do their thing, but if you're not sure about the performance effects, profile your page. If you find that there's still to much overhead, or the results aren't as consistent as you'd like, a SPA architecture is probably your best recourse.
SPA and SSR are not mutually exclusive though. There are patterns to do SSR for the initial navigation, hydrating the framework state on the client, then all subsequent navigations are controlled by the SPA. One gotcha is that patterns like this may trade one performance cost for another, for example faster loading performance on subsequent navigations at the expense of slower responsiveness on the initial load.
So try to optimize for more than one type of performance metric, and weigh any performance benefits against the cost/complexity of having to rearchitect your site.