As a Roblox developer, it is currently too hard to make fast loading times on the client using the Instance:WaitForChild() alone. It has been a bottleneck and a root of multiple problems during my time on Roblox. Due to its unnecessary yielding behavior of always yielding at least for one frame. This is especially noticeable for long chains of WaitForChild
If Roblox is able to address this issue, it would improve my development experience because the only method of quickly fetching an instance in case it already exists is
local function AwaitForChild(self:Instance,child:string) : Instance
return self:FindFirstChild(child) or self:WaitForChild(child)
end
which is inconvenient because it requires breaking the common ergonomics of declaring functions after the instances are fetched. Or requiring a module that contains this method, which goes on a feedback loop.
I don’t think this is accurate. If I put this script in ServerScriptService and run in an empty baseplate, I get the expected results which tells me the only scenario it yields is when the child doesn’t exist yet when WaitForChild is called. In other words, WaitForChild does not yield if the child already exists.
-- Control, should not yield. Expected output:
-- Found
-- Deferred
local t = task.defer(print, "Deferred")
print("Found")
task.wait()
print()
-- Direct access, should not yield. Expected output:
-- Found
-- Deferred
local t = task.defer(print, "Deferred")
local spawn = workspace.SpawnLocation
print("Found")
task.wait()
print()
-- FindFirstChild, should not yield. Expected output:
-- Found
-- Deferred
local t = task.defer(print, "Deferred")
local spawn = workspace:FindFirstChild("SpawnLocation")
print("Found")
task.wait()
print()
-- WaitForChild where child already exists, should not yield. Expected output:
-- Found
-- Deferred
local t = task.defer(print, "Deferred")
local spawn = workspace:WaitForChild("SpawnLocation")
print("Found")
task.wait()
print()
-- WaitForChild where child doesn't exist yet, should yield. Expected output:
-- Deferred
-- Found
local spawn = workspace.SpawnLocation
spawn.Name = "SpawnLocation2"
task.defer(function()
spawn.Name = "SpawnLocation"
print("Deferred")
end)
local spawn = workspace:WaitForChild("SpawnLocation")
print("Found")
Since I have no exact examples where the theoretical “does not yield” behavior breaks for some reason, I’ll mark this as an answer. Although I have noticed multiple times that the behavior I described exists in some cases. Maybe better off going with a bug report then.