Need help optimizing my Flash step ability

I’ve recently scripted a flash step ability that I personnaly absolutely love and think is much better than a simple running system or dashing system.

The only issue is, players were able to phase through objects and that is something I absolutely do not want.

For this reason, I’ve added an OnTouched event to simply cancel out the tween if they hit something.
Only downside of doing that… when they’re getting ganked by a bunch of entities (NPCs) the script goes haywire and lag out the client.

I’d like some help with improving it if possible or some pointers.

-- Get a reference to the player's character and humanoid root part
local player = game.Players.LocalPlayer
local character = player.Character
local humanoidRootPart = character:WaitForChild("HumanoidRootPart")

-- Get a reference to the TweenService
local TweenService = game:GetService("TweenService")

-- Define a variable to track whether the ability is on cooldown
local abilityOnCooldown = false

-- Get a reference to the flash step particle effect
local flashStepParticle = game.ReplicatedStorage.Fx.FlashEffect:Clone()
flashStepParticle.Parent = humanoidRootPart

-- Helper function to set the transparency of a model
local function setModelTransparency(model, transparency)
	for _, part in pairs(model:GetDescendants()) do
		if part:IsA("MeshPart") then
			part.Transparency = transparency
		end
	end
end

-- Helper function to create a visual effect
local function createEffect()
	local aura = game.ReplicatedStorage.Fx.Dust:Clone()
	aura.Anchored = false

	local weld = Instance.new("Weld")
	weld.Part0 = humanoidRootPart
	weld.Part1 = aura
	weld.Parent = aura
	aura = game.ReplicatedStorage.Fx.Dust:Clone()
	aura.Anchored = false

	weld = Instance.new("Weld")
	weld.Part0 = humanoidRootPart
	weld.Part1 = aura
	weld.Parent = aura
	aura.Parent = workspace

	for _,part in next, aura.Attachment:GetChildren() do
		part:Emit(0.5)
		part.Enabled = true
		task.delay(0.5, function() part.Enabled = false end)
	end
	task.delay(1, function() aura:Destroy() end)
end

local function Apple()
	for i=1,5 do
		coroutine.wrap(function()
			local line = Instance.new("Part")
			line.Size = Vector3.new(0,0,0)
			line.CFrame = CFrame.new(humanoidRootPart.Position, humanoidRootPart.Position + character.Humanoid.MoveDirection)
			line.CFrame *= CFrame.new(math.random(-4,4),math.random(-4,4),math.random(-4,4))
			line.Anchored = true
			line.CanCollide = false
			line.CanTouch = false
			line.Transparency = 1

			line.Parent = workspace

			TweenService:Create(line, TweenInfo.new(0.2,Enum.EasingStyle.Exponential,Enum.EasingDirection.Out,0,false,0),{Size = Vector3.new(.05,.05,5);Transparency = 0}):Play()

			task.wait(.3)
			TweenService:Create(line, TweenInfo.new(0.3,Enum.EasingStyle.Sine,Enum.EasingDirection.Out,0,false,0),{Size = Vector3.new(0,0,7);Transparency = 1}):Play()
			task.delay(1, function() line:Destroy() end)
		end)()
	end
end

function onKeyPress(input)
	if input.KeyCode == Enum.KeyCode.F and not abilityOnCooldown then

		-- Get the target location for the ability
		local targetLocation = character:GetPrimaryPartCFrame()
		targetLocation = targetLocation + targetLocation.lookVector * 30

		-- Set the character's transparency to full
		setModelTransparency(character, 1)

		-- Create a tween to move the character to the target location
		local tween = TweenService:Create(humanoidRootPart, TweenInfo.new(0.5), {CFrame = targetLocation})

		-- Connect to the Touched event of the humanoid root part
		humanoidRootPart.Touched:Connect(function(part)
			-- Check if the part that was touched is the player's character to skip him
			humanoidRootPart.Touched:Connect(function(part)
				if part.Parent == character then
					createEffect()
					Apple()
					setModelTransparency(character, 0)
				end
				end)
			end)

		-- Connect to the Completed event of the tween to reset the character's transparency and set the ability on cooldown
		tween.Completed:Connect(function()
			setModelTransparency(character, 0)
			wait(5)
			abilityOnCooldown = false
		end)

		-- Play the tween
		tween:Play()

		-- Set the ability on cooldown
		abilityOnCooldown = true

		-- Play the flash step particle effect could be put into CreateEffect but i'm ■■■■■■■■ ok
		flashStepParticle:Emit(0.5)
		flashStepParticle.Enabled = true
		task.delay(0.5, function() flashStepParticle.Enabled = false end)

		-- Create the visual effect
		createEffect()
	elseif input.KeyCode == Enum.KeyCode.F and abilityOnCooldown then
	end
end



-- Connect to the player's key press event
game:GetService("UserInputService").InputBegan:Connect(onKeyPress)

Well I’m not too good at scripting but I think that rather than using .Touched event that uses a lot of system resources (which lags you out) you can use a raycast to check if there’s a thing too close to the player in it’s flash-stepping direction! Maybe like cast it from player.character.CFrame.LookVector and length of like 1 stud or lower can be a good idea. This will save you a lot of system resources and hopefully you get help from this!
Well I’m assuming you know how to do raycasts since you are doing advanced stuff but just in case:
A intro to roblox raycasts

The reason is that .Touched event will check every single instance in workspace that touches the player at the same time, in your case the npc’s all body parts and stuff like accessories, and that cause A LOT of lag. And using .Touched is not accurate and may cause some bugs and glitches over time. But raycast, in turn, uses very less server resource and is very accurate. Btw I’m currently doing a flashstep like ability and your script actually helps me out!