We have all run into a problem where your scenes would look way better if you added that one thing, but if you did your PC will likely blow up in your face. this post should help increase your viewport responsiveness and improve your render time as well.
No.1 how to reduce polygon count in a model without loosing too much detail in blender
the first thing you can do is make sure you dont have any unnecessary geometry in your scene, you can do this by using a decimate modifier, this is a destructive method as it will change the way the final model looks and if you apply the modifier there is no way to go back to the old model without using the undo button. you will have to apply the decimate modifier to see significant viewport performance improvements.
No.2 Using collection instances:
for scenes that have a lot of repeated sections like a tunnel or city that may have boroughs, you can get way with reusing the same areas or collection of buildings/parts in other areas of the scene.
what are collection instances:
Collection instances are just duplicates of a collection that can be reused as instances, adding new or duplicating the collection instance does not add workload on the cpu so you can have thousands of instances without ever noticing any significant hit on viewport performance.
No.3 Use Geometry nodes instead of the array modifier
The array modifier is one of the most useful modifiers in the blender modifier stack, but it comes at a cost, the array modifier duplicates the model you have applied it to according to chosen parameters, the issue with it is that, it does not only duplicate the object, it also duplicates the mesh data which in most cases is unnecessary, mesh data holds information like how many vertices a mesh has, faces and normals this is not information necessary for a duplicated object as it can just refer to the original object instead of having its own. thats why when you use the array modifier you will see a polygon count jump in your statistics while if you create the same array setup using geometry nodes you wont see the jump, as geometry nodes creates instances instead of full copies.
Use less render samples and set a time limit:
Since blender 3.0 a new feature of cycles was introduced that let set a time limit for each frame, this is a use this feature to speed up your render time but simply limiting the time it takes each frame to render, most rendered images dont need all the 4024 samples set by default for cycles, some images would look fine with just 1000 samples or 400 samples, so you can do a test render see how many samples your render needs to look good then see how long it takes to render those samples then set that as the limit.
i found that i can get a decent render with a time limit of 30 seconds.
Use the denoiser
More samples in cycles make your render look better but it means that your render is going to take alot of time to finish, you can compromise and use the denoiser to get a clearer image, the denoiser will still need a good number of samples to work with but this will depend on what you are rendering, so you will have to do some test.