I tried to make blood physic with raycast but it lags

lag become harder when I try to make more blood.
if I make 300 blood particles and wait until it disappear, and when I make it again, it still lags.
Is there something that should be removed after function?

coroutine.wrap(function()
				local bloodDone, bloodError = pcall(function()
					local bloodRemoved = false
					local arrowRay = RaycastParams.new()
					local arrowForce = bloodPart.CFrame
					local arrowForceX, arrowForceY, arrowForceZ = arrowForce:ToEulerAnglesXYZ()
					local arrowGravity = 0
					local arrowRay = RaycastParams.new()
					arrowRay.FilterType = Enum.RaycastFilterType.Blacklist
					while true do
						local nextArrowCF = bloodPart.CFrame + arrowForce.LookVector * 0.3 - Vector3.new(0, arrowGravity, 0)
						local ignoreList = {}
						for _, unlist in pairs(workspace:GetDescendants()) do
							if unlist:IsA("BasePart") then
								if unlist.CanCollide == false or unlist.Anchored == false then
									table.insert(ignoreList, unlist)
								end
							end
						end
						arrowRay.FilterDescendantsInstances = ignoreList
						local arrowRotation = CFrame.new(bloodPart.Position, nextArrowCF.Position)
						local arrowResult = workspace:Raycast(bloodPart.Position, arrowRotation.LookVector * (bloodPart.Position - nextArrowCF.Position).magnitude, arrowRay)
						bloodPart.CFrame = bloodPart.CFrame + arrowForce.LookVector * 0.3 - Vector3.new(0, arrowGravity, 0)
						if arrowResult then
							bloodRemoved = true
							local bloodSize = math.random(5 + math.round(bloodAmount / 8), 20 + math.round(bloodAmount / 2)) / 10
							local bloodExpand = (bloodSize - 0.1) / 20
							local floorBlood = game:GetService("ServerStorage").floorBlood:Clone()
							floorBlood.CFrame = CFrame.new(arrowResult.Position, arrowResult.Position + arrowResult.Normal)
							floorBlood.Size = Vector3.new(0.1, 0.1, 0.1)
							floorBlood.Parent = workspace
							for expandCount = 1, 20 do
								floorBlood.Size = Vector3.new(floorBlood.Size.X + bloodExpand, floorBlood.Size.Y + bloodExpand, 0.1)
								game:GetService("RunService").Heartbeat:wait()
							end
							bloodPart:Destroy()
							
							if lastTime ~= nil then
								wait(lastTime)
							else
								wait(10)
							end
							
							for disCount = 1, 100 do
								floorBlood.Transparency += 0.01
								game:GetService("RunService").Heartbeat:wait()
							end
							floorBlood:Destroy()
						end
						arrowGravity += 0.03
						if bloodRemoved == true then
							break
						end
						game:GetService("RunService").Heartbeat:wait()
					end
				end)
				if not bloodDone then
					warn(bloodError)
					bloodPart:Destroy()
				end
			end)()