How to optimize projectiles (Emerald Splash)

How do I optimize this? I currently use .Touche and the prolonged use of this move causes server to slow down. I want each bullet to have a hitbox, anyone has a solution to optimize this?

game.ReplicatedStorage.Projectiles.EMSplash.Event:Connect(function(plr, which,part, pos)
	local chr = plr.Character
	local hum = chr.Humanoid
	local theanimator = hum.Animator
	local humroot = chr.HumanoidRootPart
	local skindata = plr.PlrData.SkinData
	local ultvalue = plr.PlayerGui.UltimateFrame.UltValue
	local effectmoudle = require(game.ServerScriptService.Effects.EffectModule)
	local gamemodule = require(game.ServerScriptService.GameModule)
	local sprint = game.ReplicatedStorage.Sprint
	local repstor = game.ReplicatedStorage
	if which == "basic" then
		local bullet = game.ServerStorage.emsplash:Clone()
		bullet.Parent = workspace.ExtraStuff
		bullet.Name = plr.Name.." EMSplash"
		bullet.CanCollide = false
		bullet.CFrame = humroot.CFrame * CFrame.new(0, 0, -4)
		bullet.Anchored = false
		game.Debris:AddItem(bullet, 0.6)
		bullet:SetNetworkOwner(nil)
		local bodyvelo = Instance.new("BodyPosition", bullet)
		bodyvelo.MaxForce = Vector3.new(100000, 100000, 100000)
		bodyvelo.Position = humroot.CFrame * CFrame.new(math.random(-20, 20), math.random(-15, 15), -95).Position
		coroutine.resume(coroutine.create(function()
			while true do
				wait()
				if chr:FindFirstChild("Timestopper") or chr:FindFirstChild("StoppedTS") then
					bullet.Anchored = true
					repeat wait() until not chr:FindFirstChild("Timestopper") or chr:FindFirstChild("StoppedTS")
					bullet.Anchored = false
					local b = Instance.new('BodyVelocity')
					b.MaxForce = Vector3.new(100000, 100000, 100000)
					b.P = math.huge
					b.Velocity = humroot.CFrame.lookVector * 95
					b.Parent = bullet
				end
			end
		end))

		local touchedCache = {}  -- Store touched instances to avoid frequent processing

		bullet.Touched:Connect(function(hit)
			if not touchedCache[hit] then
				touchedCache[hit] = true

				if hit.Parent:FindFirstChild("Humanoid") and hit.Parent.Name ~= plr.Name then
					bullet:Destroy()
					game.ReplicatedStorage.DamageStuff.DamageBind1:Fire(false, chr, 0.5, 0, 1, "rbxassetid://566593606", 7, 5, "HGSplash", hit)
					--	DamageModule.DamageFunc(plr,15,0,0.6,"rbxassetid://9089387904",8,0,"Normal3",0.2,hit,false)
				end
			end
		end)
	end
	
	if which == "splash2" then
		coroutine.wrap(function()
			part.CFrame = CFrame.new(part.Position, pos.Position)
			local bullet = game.ServerStorage.emsplash:Clone()
			bullet.Parent = workspace.ExtraStuff
			bullet.Name = plr.Name.." EMSplash"
			bullet.CanCollide = false
			bullet.CFrame = part.CFrame
			bullet.Anchored = false
			game.Debris:AddItem(bullet, 0.6)
			bullet:SetNetworkOwner(nil)
			local bodyvelo = Instance.new("BodyPosition", bullet)
			bodyvelo.MaxForce = Vector3.new(100000, 100000, 100000)
			bodyvelo.Position = part.CFrame * CFrame.new(math.random(-20, 20), math.random(-20, 20), -95).Position
			coroutine.resume(coroutine.create(function()
				while true do
					wait()
					if chr:FindFirstChild("Timestopper") or chr:FindFirstChild("StoppedTS") then
						bullet.Anchored = true
						repeat wait() until not chr:FindFirstChild("Timestopper") or chr:FindFirstChild("StoppedTS")
						bullet.Anchored = false
						local b = Instance.new('BodyVelocity')
						b.MaxForce = Vector3.new(100000, 100000, 100000)
						b.P = math.huge
						b.Velocity = humroot.CFrame.lookVector * 95
						b.Parent = bullet
					end
				end
			end))

			local touchedCache = {}  -- Store touched instances to avoid frequent processing

			bullet.Touched:Connect(function(hit)
				if not touchedCache[hit] then
					touchedCache[hit] = true

					if hit.Parent:FindFirstChild("Humanoid") and hit.Parent.Name ~= plr.Name then
						bullet:Destroy()
						game.ReplicatedStorage.DamageStuff.DamageBind2:Fire(false, chr, 5, "Basic", 0, 1, "rbxassetid://566593606", 7, 3, hit, "HGSplash")
					end
				end
			end)
		end)()
	end
end)

try using this module

I would just raycast once at the start for each bullet and check if the raycast hits a player instead of using a touched connection because you dont really need a touched connection for every single bullet when the bullet would reach their target instantly anyways and the bullet is also at a constant velocity so a single raycast would sync with where ever the bullet is moving easily