Why are Bindable events delaying?

Hello Devs! I am making a TDS game. Everything was fine. But When zombies enter the base, everything delays. How can I make it run smooth and not delay?
Base Module

local ServerStorage  = game:GetService("ServerStorage")

local bindables = ServerStorage:WaitForChild("Bindables")
local UpdateBaseHealthEvent = bindables:WaitForChild("UpdateBaseHealth")
local map  = workspace.Map
local Base = {}
function Base.Setup(map, health)
	Base.Model = map:WaitForChild("Base")
	Base.CurrentHealth = health
	Base.MaxHealth = health
	
	Base.UpdateHealth()
end

function Base.UpdateHealth(damage)
	if damage then
		Base.CurrentHealth -= damage 
	end
	
	local gui = Base.Model.BillboardGui
	local percent = Base.CurrentHealth / Base.MaxHealth
	
	gui.Health.Fill.Size = UDim2.new(percent,0, 1, 0)
	
		gui.Health.Textt.Text = "Base: "..Base.CurrentHealth.."/"..Base.MaxHealth
end

UpdateBaseHealthEvent.Event:Connect(Base.UpdateHealth)
return Base

Mob Module

local PhysicsService = game:GetService("PhysicsService")
local ServerStorage  = game:GetService("ServerStorage")

local bindables = ServerStorage:WaitForChild("Bindables")
local UpdateBaseHealthEvent = bindables:WaitForChild("UpdateBaseHealth")
local Mob = {}

function Mob.Move(mob, map)
	local hum = mob.Humanoid
	local waypoints = map.Waypoints
	
	for waypoint=1, #waypoints:GetChildren() do
		hum:MoveTo(waypoints[waypoint].Position)
		hum.MoveToFinished:Wait()
	end
	mob:Destroy()
	UpdateBaseHealthEvent:Fire(hum.Health)
end

function Mob.Spawn(name, quantity, map)
	local MobExist = ServerStorage:WaitForChild("Mobs"):FindFirstChild(name)
	if MobExist then
		for i=1, quantity do
			task.wait(0.5)
			local newMob = MobExist:Clone()
			newMob.HumanoidRootPart.CFrame = map.EnemySpawn.CFrame
			newMob.Parent = map.Mobs
			newMob.HumanoidRootPart:SetNetworkOwner(nil)
			for i, object in ipairs(newMob:GetDescendants()) do
				if object:IsA("BasePart") then
					PhysicsService:SetPartCollisionGroup(object, "Mob")
				end
			end
			
			newMob.Humanoid.Died:Connect(function()
				task.wait(0.5)
				newMob:Destroy()
			end)
			coroutine.wrap(Mob.Move)(newMob,map)
		end
	else
		warn("Mob doesnt exist for: "..name)
	end
end

return Mob

2022-03-23 14-23-44 – The video

Usually when alot of parts move, the client has to load all of them, if they have a decent amount of ping it will not run smoothly, you can make the npc SetNetworkOwner() as player, but if alot of players are in the game, then fire a remote even to player which will spawn npc on client, and if client game freezes the npc also freezes, so if the client lags, then the npc also lags, so it won’t cause harsh npc movement

How will I exactly do that tho??

Read these articles

I mean How will I SetNetworkOwner() as player?

Nvm I fixed it by changing the path