I tested myself to instance such a scene as you describe it, and it takes 1 millisecond to instance, at most. 90% of the time it takes 0:
var time_before = OS.get_ticks_msec()
var scene = preload("sprite_512.tscn")
var n = scene.instance()
var elapsed = OS.get_ticks_msec() - time_before
print("Ms: " + str(elapsed))
If I instance 500 of them, I effectively get 10ms of elapsed time.
But... are you really considering instancing 500 times an element that can be seen in a 512x512 pixels area? Is it for a scrolling level then? (Obviously, the player cannot see all of them at once).
If it's for loading a level, then 10ms is nothing, tbh. And if you really want no framerate "spike" at all, you can do the loading in a thread, I believe.
A general solution to this is to load all objects once, but never destroy any of them. Instead, if you need to remove one, just hide it. If you need another to spawn, take one you previously made invisible, and show it again. That's called "pooling", re-using objects instead of rebuilding them.
If this is needed in general, it could be easy to implement a singleton that manages instancing of pooled scenes.
If the scene is only a Node2D and a Sprite, why not just make it a Sprite? That makes one node less to build.