Good practice for screen change in single page application (SPA)

I want to understand if there are any standard good practices to manage navigations and screen changes within single page applications (SPAs) with respect to loader animations.

Right now I keep a custom state that holds the screen to be shown. Each screen (group) has conditionals in them to show when custom state’s value is set as that screen.

This works fine from functional perspective. But I do not do the “loading animations” (loaders) in these very well. I have one common loading pop-up that I show and hide in some of the workflows.

However, when custom state is changed, one group is hidden and another group is shown. All this happens without workflow. Now the new group that is shown, shows blank for a while with half its elements loaded/not-loaded etc. In such cases I want to just show loading animation while the content of the screen is loading (which can have multiple repeating groups, multiple groups etc.) and hide it when they are all loaded.

It is very cumbersome and error prone to put lot of conditionals for each repeating group’s is loading (which also is not very reliable in itself). Also, not sure how to put conditional on group's content is loading. I did put show/hide of loading animation, but either the the animation shows only momentarily while the screen will be white for long, or for some logical issue (or because of complexity, it would not get hidden when it should get hidden).
So I am looking to see if there are any good and simple practices here.

Any idea how it is done by people who implement SPAs?