for the newer scripters that are experiencing lag spike issues when looping through workspace descendants
workspace:GetDescendants() is expensive, as it loops through the children of each workspace object, and then loops through their children, and loops through the childrens children, so on so forth.
heres some code to fix those lag spikes
local WorkspaceDescendants = workspace:GetDescendants()
local Added, Removed;
local Enabled;
local function DescendantAdded(object)
table.insert(WorkspaceDescendants, object)
end
local function DescendantRemoving(object)
for k, v in ipairs(WorkspaceDescendants) do
if v == object then
table.remove(WorkspaceDescendants, k)
break
end
end
end
local function Disable()
if Enabled then
Enabled = nil
Added:Disconnect()
Removed:Disconnect()
Added = nil
Removed = nil
end
end
local function Enable()
if Enabled then
Disable()
end
Enabled = true
Added = workspace.DescendantAdded:Connect(DescendantAdded)
Removed = workspace.DescendantRemoving:Connect(DescendantRemoving)
end
Enable()
for _, v in ipairs(WorkspaceDescendants) do
--...
end
edit
my code only calls getdescendants once, and then i rely on the variable which reduces lag and makes performance better, unlike workspace:getdescendants(), which doesnt use any caching and lags when you loop through a bunch of parts
I can’t tell if this is an actual resource as it has 0 explanation.
local function DescendantRemoving(object)
for k, v in ipairs(WorkspaceDescendants) do
if v == object then
table.remove(WorkspaceDescendants, k)
end
end
end
This should break when it finds and removes the object as well or you’re wasting time looping through a table which you know doesn’t have the value
ok so you’re a jerk, however a smart jerk so i respect you a lot
my code only calls getdescendants once, and then i rely on the variable which reduces lag and makes performance better
unlike workspace:getdescendants(), which doesnt use any caching
This code is better for performance if you are calling GetDescendants a reasonable amount of times, however if you only plan to use it once then obviously one get descendants call is faster.
There isn’t anything inherit my wrong with this code, and while I would favour table.find for readability, anyone saying this resource is pointless or worse for performance is inherently wrong.
All of this being said, if you are calling GetDescendants() on workspace I would really be questioning if it’s a valid use case that couldn’t just be optimised with collection service.
local WorkspaceDescendants = workspace:GetDescendants()
local function descendantAdded(instance: Instance)
table.insert(WorkspaceDescendants, instance)
end
local Array = {}
function Array.remove(array, value): any?
local index = table.find(array, value)
if index then
return table.remove(array, index)
end
end
local function descendantRemoving(instance: Instance)
Array.remove(WorkspaceDescendants, instance)
end
workspace.DescendantAdded:Connect(descendantAdded)
workspace.DescendantRemoving:Connect(descendantRemoving)
return WorkspaceDescendants
this is meant to be used as a modulescript instead so it can be accessed by any script.
I removed the enable / disable functionality because it doesn’t seem to be necessary
@dellghtfuI you can definitely expand this to be more functional keep track of any Instance, not just workspace. It’d probably get more praises