It just looks bad when you call it in a loop or in the middle of some random function, but performance and footprint wise it doesn't make a difference. It's dealt with at the parser level. The thing is loaded (only once) even before the script is compiled, and all calls to preload()
are replaced with references to the resource object by the parser. That's also the reason why it only allows string constants for the path argument.
At least that's my understanding of what the docs say.
This makes sense but it wouldn't hurt if somebody actually stress-tested this to confirm it. We all know how Godot documentation can sometimes get a little whacky 🙂
--
EDIT: I made a quick test running a scene with two sibling nodes, each having a script that preloads the same resource in the _ready()
callback.
test_1.gd:
extends Node
func _init():
print("init")
func _ready():
print("ready")
print(preload("res://icon.png"))
test_2.gd:
extends Node
func _init():
print("init 2")
func _ready():
print("ready 2")
print(preload("res://icon.png"))
With verbose flag on, we get this printed in the console:
Loaded builtin certs
Loading resource: res://test.tscn
Loading resource: res://test_1.gd
Loading resource: res://icon.png
Loading resource: res://test_2.gd
init
init 2
ready
[StreamTexture:1259]
ready 2
[StreamTexture:1259]
We can see that the resource (icon.png) is loaded only once, immediately after loading the first script that calls preload()
. Way before you'd expect if preload()
was a regular function call that follows the order of execution. The resource is loaded before objects that "call" preload()
are even created. I in fact think they should have used a special syntax for preloading to avoid this confusion.
If we just replace each preload()
with load()
, the order becomes as expected, because load()
is a regular function call and the resource is loaded exactly after the call (although the second call probably just returns cached data):
Loaded builtin certs
Loading resource: res://test.tscn
Loading resource: res://test_1.gd
Loading resource: res://test_2.gd
init
init 2
ready
Loading resource: res://icon.png
[StreamTexture:1267]
ready 2
Loading resource: res://icon.png
[StreamTexture:1270]