Blood script gets exponentially laggier each blood particle

So I have made a blood script that works perfectly for my needs, the only issue is the more blood created, the laggier it gets whenever a new blood is made.

script:

local Bloods = {}


-- / Add blood function
function AddBlood(Position, BloodObject, Speed, NoPools)
	task.spawn(function()
		local IsTakenID = true
		local NewBloodID = game:GetService("HttpService"):GenerateGUID(false)

		-- / Dont Repeat GUID
		repeat
			local islocalid = false
			for i,v in pairs(Bloods) do
				if v.ID == NewBloodID then
					islocalid = true
				end
			end

			if islocalid then
				NewBloodID = game:GetService("HttpService"):GenerateGUID(false)
			else
				IsTakenID = false
			end
		until IsTakenID == false

		-- / Make New Blood
		local NewBlood = BloodObject:Clone()
		
		

		-- / Set Blood GUID
		local GUIDObject = Instance.new("StringValue", NewBlood)
		GUIDObject.Name = "GUID"
		GUIDObject.Value = NewBloodID

		NewBlood.Position = Position

		local XZVals, InvertedXZVals = 5, -5
		local YVal = 5



		--  / Blood Velocity
		local NewBloodVelocity = Instance.new("BodyVelocity")
		NewBloodVelocity.P = math.huge
		NewBloodVelocity.MaxForce = Vector3.new(math.huge, math.huge, math.huge)
		NewBloodVelocity.Velocity = Vector3.new(math.random(InvertedXZVals, XZVals),math.random(1,YVal),math.random(InvertedXZVals, XZVals))

		NewBloodVelocity.Parent = NewBlood


		-- / Blood Ground Detection
		if NoPools == true then
			-- / We do things differently around here.
			
			NewBlood.CanCollide = true
		else
			local GroundDetectionScript = script:WaitForChild("DoBloodPoolStuff"):Clone()
			GroundDetectionScript.Parent = BloodObject
			GroundDetectionScript.Disabled = false
		end

		-- / Blood Gravity
		
		if NoPools  then
			task.spawn(function()
				local BloodRemoved = false

				task.spawn(function()
					task.wait(1.5)
					BloodRemoved = true
				end)
				-- / Add Blood to table
				table.insert(Bloods, {
					Blood = NewBlood,
					ID = NewBloodID,
				})
				local BloodTableIndex = #Bloods

				repeat 
					task.wait(.1)
					NewBloodVelocity.Velocity = Vector3.new(NewBloodVelocity.Velocity.X, NewBloodVelocity.Velocity.Y - (1 * Speed), NewBloodVelocity.Velocity.Z)
				until BloodRemoved == true
				if NewBloodVelocity then
					NewBloodVelocity:Destroy()
				end

				-- / Remove Blood From Tableqq
				table.remove(Bloods, BloodTableIndex)
			end)
		else
			task.spawn(function()
				
				if NoPools then
					NewBlood:WaitForChild("DoBloodPoolStuff"):Destroy()
					NewBlood.CanCollide = true
				end
				
				local BloodRemoved = false

				-- / Loop Disable Stuff
				game.ReplicatedStorage.ClientModules.BloodHitGround.OnInvoke = function(GUID)
					if GUID == NewBloodID and BloodRemoved == false then
						BloodRemoved = true
					end
				end

				-- / Add Blood to table
				table.insert(Bloods, {
					Blood = NewBlood,
					ID = NewBloodID,
				})
				local BloodTableIndex = #Bloods

				repeat 
					task.wait(.1)
					NewBloodVelocity.Velocity = Vector3.new(NewBloodVelocity.Velocity.X, NewBloodVelocity.Velocity.Y - (1 * Speed), NewBloodVelocity.Velocity.Z)
				until BloodRemoved == true
				if NewBloodVelocity then
					NewBloodVelocity:Destroy()
				end

				
				
				game:GetService("TweenService"):Create(NewBlood, TweenInfo.new(5), {Transparency = 1}):Play()
				task.wait(5)
				-- / Remove Blood From Tableqq
				table.remove(Bloods, BloodTableIndex)
				NewBlood:Destroy()
			end)
		end
		
		NewBlood.Parent = game.Workspace.Blood

		-- / No Blood Lag
		NewBlood:SetNetworkOwner(nil)
	end)
end

-- / Add Blood
game.ReplicatedStorage.ClientModules.AddBlood.OnInvoke = function(Position, PoolSize, Speed, NoPools)
	-- // Add as many blood particles as needed
	for i = 1, PoolSize do
		local Tiny = math.random(1,3)
		
		-- /// Chose between small or large blood at random
		if Tiny == 1 then
			
			AddBlood(Position, script:WaitForChild("BloodParticleSmall"), Speed,NoPools)
			
		else
			
			AddBlood(Position, script:WaitForChild("BloodParticleLarge"), Speed,NoPools)
			
		end
	end
end

--[[
 / Not In Testing
game.ReplicatedStorage.ClientModules.AddABlood.OnServerEvent:Connect(function(plr, balls)
	for i = 1, 10 do
		local Tiny = math.random(1,3)

		-- /// Chose between small or large blood at random
		if Tiny == 1 then

			AddBlood(plr.Character.HumanoidRootPart.Position, script:WaitForChild("BloodParticleSmall"), 2, balls)

		else

			AddBlood(plr.Character.HumanoidRootPart.Position, script:WaitForChild("BloodParticleLarge"), 2, balls)

		end
	end
	plr.Character.Humanoid.Health -= 20
	game.Workspace.TestBloodSound:Play()
end)
]]

-- / Blood Pools


local CurrentPoolGUIDS = {}
game.ReplicatedStorage.ClientModules.AddBloodPool.OnInvoke = function(BloodObject, Position, GUID)
	task.spawn(function()
		local founduid = false
		for i,v in pairs(CurrentPoolGUIDS) do
			if v == GUID then
				founduid = true
			end
		end

		if founduid == false then
			if BloodObject then
				BloodObject:Destroy()
			end
			table.insert(CurrentPoolGUIDS, GUID)
			local BloodIndex = #CurrentPoolGUIDS

			local NewBlood = script.BloodPool:Clone()
			NewBlood.Position = Position
			local size = math.random(100,300)/100 -- old max num: 3.2
			if size > tonumber(script.Settings.MaximumBloodSize.Value) then
				size = tonumber(script.Settings.MaximumBloodSize.Value)
			end

			game:GetService("TweenService"):Create(NewBlood, TweenInfo.new(2), {Size = Vector3.new(0.066, size, size)}):Play()

			NewBlood.Parent = game.Workspace.Blood
			NewBlood:WaitForChild("PlayRandomSound"):Fire()

			task.wait(2 + tonumber(script.Settings.BloodSitTime.Value))


			game:GetService("TweenService"):Create(NewBlood, TweenInfo.new(2), {Transparency = 1}):Play()

			task.wait(2)
			NewBlood:Destroy()
			table.remove(CurrentPoolGUIDS, BloodIndex)
		end


	end)
end

(DoBloodPoolStuff is a script that detects touching the ground and sets it back to make a pool, not having the script does not affect performance so its not that.)
I have no clue what is causing it, help is appreciated!

Fixed it by changing how the blood gravity stopped, works way better now.

local Bloods = {}
local CurrentBloodGUIDGravity = {}

function BloodRemove(GUID)
	
	if table.find(CurrentBloodGUIDGravity, GUID) then
		table.remove(CurrentBloodGUIDGravity, table.find(CurrentBloodGUIDGravity, GUID))
	end
	
end

function AddGravity(NewBlood, NewBloodVelocity, NewBloodID, Speed)

	local BloodRemoved = false

	

	-- / Add Blood to table
	table.insert(Bloods, {
		Blood = NewBlood,
		ID = NewBloodID,
	})
	table.insert(CurrentBloodGUIDGravity, NewBloodID)
	local BloodTableIndex = #Bloods

	repeat 
		task.wait(.1)
		NewBloodVelocity.Velocity = Vector3.new(NewBloodVelocity.Velocity.X, NewBloodVelocity.Velocity.Y - (1 * Speed), NewBloodVelocity.Velocity.Z)
	until not table.find(CurrentBloodGUIDGravity, NewBloodID)
	
	table.remove(CurrentBloodGUIDGravity, table.find(CurrentBloodGUIDGravity, NewBloodID))
	
	
	
	
	if NewBloodVelocity then
		NewBloodVelocity:Destroy()
	end



	-- / Remove Blood From Table	
	table.remove(Bloods, BloodTableIndex)
	NewBlood:Destroy()
end

-- / Loop Disable Stuff
game.ReplicatedStorage.ClientModules.BloodHitGround.OnInvoke = function(GUID)
	BloodRemove(GUID)
end


-- / Add blood function
function AddBlood(Position, BloodObject, Speed, NoPools)
	task.spawn(function()
		local IsTakenID = true
		local NewBloodID = game:GetService("HttpService"):GenerateGUID(false)

		-- / Dont Repeat GUID
		repeat
			local islocalid = false
			for i,v in pairs(Bloods) do
				if v.ID == NewBloodID then
					islocalid = true
				end
			end

			if islocalid then
				NewBloodID = game:GetService("HttpService"):GenerateGUID(false)
			else
				IsTakenID = false
			end
			task.wait()
		until IsTakenID == false

		-- / Make New Blood
		local NewBlood = BloodObject:Clone()
		
		

		-- / Set Blood GUID
		local GUIDObject = Instance.new("StringValue", NewBlood)
		GUIDObject.Name = "GUID"
		GUIDObject.Value = NewBloodID

		NewBlood.Position = Position

		local XZVals, InvertedXZVals = 5, -5
		local YVal = 5



		--  / Blood Velocity
		local NewBloodVelocity = Instance.new("BodyVelocity")
		NewBloodVelocity.P = math.huge
		NewBloodVelocity.MaxForce = Vector3.new(math.huge, math.huge, math.huge)
		NewBloodVelocity.Velocity = Vector3.new(math.random(InvertedXZVals, XZVals),math.random(1,YVal),math.random(InvertedXZVals, XZVals))

		NewBloodVelocity.Parent = NewBlood


		-- / Blood Ground Detection
		if NoPools == true then
			-- / We do things differently around here.
			
			NewBlood.CanCollide = true
		else
			local GroundDetectionScript = script:WaitForChild("DoBloodPoolStuff"):Clone()
			GroundDetectionScript.Parent = BloodObject
			GroundDetectionScript.Disabled = false
		end

		-- / Blood Gravity
		
		if NoPools  then
			task.spawn(function()
				local BloodRemoved = false

				task.spawn(function()
					task.wait(1.5)
					BloodRemoved = true
				end)
				-- / Add Blood to table
				table.insert(Bloods, {
					Blood = NewBlood,
					ID = NewBloodID,
				})
				local BloodTableIndex = #Bloods

				repeat 
					task.wait(.1)
					NewBloodVelocity.Velocity = Vector3.new(NewBloodVelocity.Velocity.X, NewBloodVelocity.Velocity.Y - (1 * Speed), NewBloodVelocity.Velocity.Z)
				until BloodRemoved == true
				if NewBloodVelocity then
					NewBloodVelocity:Destroy()
				end

				-- / Remove Blood From Tableqq
				table.remove(Bloods, BloodTableIndex)
			end)
		else
			task.spawn(function()
				AddGravity(NewBlood, NewBloodVelocity, NewBloodID, Speed)
			end)
		end
		
		NewBlood.Parent = game.Workspace.Blood

		-- / No Blood Lag
		NewBlood:SetNetworkOwner(nil)
	end)
end

-- / Add Blood
game.ReplicatedStorage.ClientModules.AddBlood.OnInvoke = function(Position, PoolSize, Speed, NoPools)
	-- // Add as many blood particles as needed
	for i = 1, PoolSize do
		local Tiny = math.random(1,3)
		
		-- /// Chose between small or large blood at random
		if Tiny == 1 then
			
			AddBlood(Position, script:WaitForChild("BloodParticleSmall"), Speed,NoPools)
			
		else
			
			AddBlood(Position, script:WaitForChild("BloodParticleLarge"), Speed,NoPools)
			
		end
	end
end

--[[
 / Not In Testing
game.ReplicatedStorage.ClientModules.AddABlood.OnServerEvent:Connect(function(plr, balls)
	for i = 1, 10 do
		local Tiny = math.random(1,3)

		-- /// Chose between small or large blood at random
		if Tiny == 1 then

			AddBlood(plr.Character.HumanoidRootPart.Position, script:WaitForChild("BloodParticleSmall"), 2, balls)

		else

			AddBlood(plr.Character.HumanoidRootPart.Position, script:WaitForChild("BloodParticleLarge"), 2, balls)

		end
	end
	plr.Character.Humanoid.Health -= 20
	game.Workspace.TestBloodSound:Play()
end)
]]

-- / Blood Pools


local CurrentPoolGUIDS = {}
game.ReplicatedStorage.ClientModules.AddBloodPool.OnInvoke = function(BloodObject, Position, GUID)
	task.spawn(function()
		local founduid = false
		for i,v in pairs(CurrentPoolGUIDS) do
			if v == GUID then
				founduid = true
			end
		end

		if founduid == false then
			if BloodObject then
				BloodObject:Destroy()
			end
			table.insert(CurrentPoolGUIDS, GUID)
			local BloodIndex = #CurrentPoolGUIDS

			local NewBlood = script.BloodPool:Clone()
			NewBlood.Position = Position
			local size = math.random(100,300)/100 -- old max num: 3.2
			if size > tonumber(script.Settings.MaximumBloodSize.Value) then
				size = tonumber(script.Settings.MaximumBloodSize.Value)
			end

			game:GetService("TweenService"):Create(NewBlood, TweenInfo.new(2), {Size = Vector3.new(0.066, size, size)}):Play()

			NewBlood.Parent = game.Workspace.Blood
			NewBlood:WaitForChild("PlayRandomSound"):Fire()

			task.wait(2 + tonumber(script.Settings.BloodSitTime.Value))


			game:GetService("TweenService"):Create(NewBlood, TweenInfo.new(2), {Transparency = 1}):Play()

			task.wait(2)
			NewBlood:Destroy()
			table.remove(CurrentPoolGUIDS, BloodIndex)
		end


	end)
end
1 Like