Pathfinding is slow and stuttering after chasing someone

I made this monster that goes to different waypoints and chases the player when it sees them. I’m having an issue where after it chases someone for the first time it gets a lot slower and kinda stutters whenever it chases someone again.

here’s the script, it’s really messy because i took parts of other scripts i found and put them together and it sorta works lol

local Pathfinding = game:GetService("PathfindingService")
local Players = game:GetService("Players")
local player = game.Players.LocalPlayer
local RunService = game:GetService("RunService")
local rig = script.Parent
local PathfindingService = game:GetService("PathfindingService")
local animations = script.Animations

local path = Pathfinding:CreatePath({
	AgentHeight = 9;
	AgentRadius = 3;
	AgentCanJump = false;

	Costs = {
		Water = 100;
		DangerZone = math.huge
	}
})

local Character = script.Parent
local humanoid = Character:WaitForChild("Humanoid")

local waypoints
local nextWaypointIndex
local reachedConnection
local blockedConnection

local function canSeePlayer()
	for _, player in Players:GetPlayers() do
		local playerCharacter = player.Character or player.CharacterAdded:Wait()
		if playerCharacter and playerCharacter.PrimaryPart then
			local playerPos = playerCharacter.PrimaryPart.Position
			local monsterPos = rig.PrimaryPart.Position
			local direction = (playerPos - monsterPos).unit * (playerPos - monsterPos).magnitude

			local raycastParams = RaycastParams.new()
			raycastParams.FilterDescendantsInstances = {rig}

			local result = workspace:Raycast(monsterPos, direction, raycastParams)
			if result and result.Instance:IsDescendantOf(playerCharacter) then
				return true
			end
		end
	end
	return false
end


for i,v in pairs(script.Parent:GetDescendants()) do
	if v:IsA("Part") or v:IsA("MeshPart") then
		v:SetNetworkOwner(nil)
	end
end

local function findTarget()
	local maxDistance = 100
	local nearestTarget

	for index, player in pairs(Players:GetPlayers()) do
		if player.Character then
			local target = player.Character
			local distance = (Character.HumanoidRootPart.Position - target.HumanoidRootPart.Position).Magnitude

			if distance < maxDistance then
				nearestTarget = target
				maxDistance = distance
			end

			if distance < 5 then
				nearestTarget.Humanoid:TakeDamage(25)
			end
		end
	end

	return nearestTarget
end

local function followPath(destination)

	local success, errorMessage = pcall (function()
		path:ComputeAsync(Character.PrimaryPart.Position, destination)
		print("yh")
	end)

	if success and path.Status == Enum.PathStatus.Success then
		waypoints = path:GetWaypoints()

		blockedConnection = path.Blocked:Connect (function(blockedWayPointIndex)
			if blockedWayPointIndex >= nextWaypointIndex then
				blockedConnection:Disconnect()
				followPath(destination)
			end
		end)

		if not reachedConnection then
			reachedConnection = humanoid.MoveToFinished:Connect(function(reached)
				if reached and nextWaypointIndex < #waypoints then
					nextWaypointIndex += 1
					humanoid:MoveTo(waypoints[nextWaypointIndex].Position)
				else
					reachedConnection:Disconnect()
					blockedConnection:Disconnect()
				end
			end)
		end

		nextWaypointIndex = 2
		humanoid:MoveTo(waypoints[nextWaypointIndex].Position)
	else
		warn("Path not computed!", errorMessage)
	end
end





local function calculatePath(destination)
	local agentParams = {
		["AgentHeight"] = 9,
		["AgentRadius"] = 4,
		["AgentCanJump"] = false
	}

	local path = PathfindingService:CreatePath(agentParams)
	path:ComputeAsync(rig.HumanoidRootPart.Position, destination)
	return path
end

local function walkToDestination(destination)
	local path = calculatePath(destination)

	if path.Status == Enum.PathStatus.Success then
		for _, waypoint in pairs(path:GetWaypoints()) do
			local nearestPlayer = findTarget()
			if nearestPlayer then

				local FOV = math.cos(math.rad(120)) -- Use degrees, coverts degrees to a number between -1 and 1 to use compare to the dot product. You could also just change this to a number between -1 and 1 instead like .5 which is 45 degrees

				for _, player in pairs(game:GetService("Players"):GetPlayers()) do
					local character = player.Character or player.CharacterAdded:Wait() -- or just use "continue" to skip if their character hasn't been loaded if you don't want to yield the thread
					local direction = (character.HumanoidRootPart.Position - rig.Head.Position).Unit -- Get the direction from the Enemy to the Player
					local lookVector = rig.Head.CFrame.LookVector

					local dot = lookVector:Dot(direction) -- this is the dot product I mentioned.
					if dot > FOV then -- include all angles within a range to be in the enemies FOV
						if canSeePlayer() then
							break
						else
							rig.Humanoid:MoveTo(waypoint.Position)
							rig.Humanoid.MoveToFinished:Wait()
						end
					else
						rig.Humanoid:MoveTo(waypoint.Position)
						rig.Humanoid.MoveToFinished:Wait()
					end
				end
			else
				rig.Humanoid:MoveTo(waypoint.Position)
				rig.Humanoid.MoveToFinished:Wait()
			end
		end
	else
		rig.Humanoid:MoveTo(destination - (rig.HumanoidRootPart.CFrame.LookVector * 10))
	end
end

local function patrol()
	script.Parent.Humanoid.WalkSpeed = 8
	local waypoints = workspace.Waypoints.Bacteria3:GetChildren()
	local randomNumber = math.random(1, #waypoints)

	walkToDestination(waypoints[randomNumber].Position)
end



while task.wait() do
	local target = findTarget()
	if target then

		local FOV = math.cos(math.rad(120)) 

		for _, player in pairs(game:GetService("Players"):GetPlayers()) do
			local character = player.Character or player.CharacterAdded:Wait()
			local direction = (character.HumanoidRootPart.Position - rig.Head.Position).Unit
			local lookVector = rig.Head.CFrame.LookVector

			local dot = lookVector:Dot(direction)
			if dot > FOV then
				if canSeePlayer() then
					script.Parent.Humanoid.WalkSpeed = 20
					print(target.Name)
					followPath(target.HumanoidRootPart.Position)
					if canSeePlayer() == false then
						
						local Timer = 4
						local WaitTime = 0.1

						while Timer > 0 do
							if canSeePlayer() then
								break
							end
							wait(WaitTime)
							Timer -= WaitTime
							followPath(target.HumanoidRootPart.Position)
						end
					end
				else
					patrol()
				end
			else
				patrol()
			end
		end

	else
		patrol()
	end
end

radius is too big. set it to 1

i changed the radius to 1, but the same exact thing is still happening

I reported it for bug reports. Seems like roblox pathfinding is broken