NPC script causing server lag?

Hey there, I was recently testing my game with some of my friends and I realised the more I stay in the game the more laggy the game is, my heavy punch script stops working.
image


This is the script performance for my npc script, it slowly goes up, the more people in the game, the faster
I have no idea how to fix this since idk how else to make a npc follow script than doing while loops
here’s my script not the whole script

function getClosestPlayer()
	local closest_player, closest_distance = nil, 200
	for i, player in pairs(workspace:GetChildren()) do
		if player:FindFirstChild("Humanoid") and player ~= NPC and game.Players:GetPlayerFromCharacter(player) and NPC.HitFolder:FindFirstChild(player.Name) then
			local distance = (NPC.PrimaryPart.Position - player.PrimaryPart.Position).Magnitude
			if distance < closest_distance then
				closest_player = player
				closest_distance = distance
			end
		end
	end
	return closest_player, closest_distance
end


	while true do
		local path = pathfinding_service:CreatePath()
		local player, distance = getClosestPlayer()
		coroutine.wrap(function()
			while task.wait() do
				if player then
					player, distance = getClosestPlayer()
				end
			end
		end)()
		if player and distance > 6 then
			path:ComputeAsync(NPC.HumanoidRootPart.Position, player.PrimaryPart.Position)
			local waypoints = path:GetWaypoints()

			for _, waypoint in pairs(waypoints) do  
				NPC.Humanoid:MoveTo(waypoint.Position)
				coroutine.wrap(function()
					while player do
						local distance = (NPC.PrimaryPart.Position - waypoint.Position).Magnitude
						local distance_from_player = (NPC.PrimaryPart.Position - player.PrimaryPart.Position).Magnitude
												
						if distance < 1 then
							break
						end
						if distance_from_player < 4 then
							NPC.Humanoid:MoveTo((NPC.HumanoidRootPart.CFrame*CFrame.new(0,0,-3)).p)
							break
						end
						wait()
					end
				end)()
			end
		elseif player and distance < 6 and script.Parent:GetAttribute("Stunned") == false then
			
			
			
			local eplayer = game.Players:GetPlayerFromCharacter(player)
			if eplayer then
				if eplayer:FindFirstChild("Details") then
					if eplayer.Details:FindFirstChild("IsBlocking") then

						if player:FindFirstChild("PerfectBlocking") then
							if player.PerfectBlocking.Value == true then
								perfectBlocked(player,NPC.Humanoid)	
							else
									
							end
						end
					end
				end
			
			
			end
			if player and distance < 6 then
				punch(player,distance)
			end
			
			
		end
		wait()
	end

Why are you wrapping this in a coroutine? Not just that, but it has no condition to end it so you are constantly spawning these functions.

Remove the coroutine and try agaio.

I thought it would be better to not yield the loop, I didn’t know it would cause lag but ill try removing that rn

that didn’t really fix it, now the npc doesn’t follow me at all
edit: nevermind I removed the corountine of the other loop by mistake