Is Using RunService.Heartbeat a good way to make raycasting bullets?

I have a gun testing game because i want to be able to get better at working on my guns and i figured out that you could make bullets by making a ray from the bullet really fast. However this is currently on the server and I’m not sure if its the most reliable way to do it, because it works just fine but it freezes for a quick second every once in a while and I’m not sure how it would act with a lot of people. (I’m currently typing this while im freezing cold and im shaking so tell me if there are mistakes)
bullet code:

game.Debris:AddItem(script.Parent, 10)
--script.Parent.CFrame = CFrame.new(script.Parent.Position, script.Parent.MousePosition.Value)
while game:GetService("RunService").Heartbeat:Wait() do
	local ray = Ray.new(script.Parent.Position, (script.Parent.CFrame.LookVector.Unit) * 4)--script.Parent.Position).Unit * 2)
	local part, position = game.Workspace:FindPartOnRayWithIgnoreList(ray, {script.Parent, game.Players:FindFirstChild(script.Parent.Name).Character, script.Parent.Parent})
	if not part then
		script.Parent.Position = position
	else
		if part.Parent:FindFirstChild("Humanoid") then
			part.Parent.Humanoid:TakeDamage(script.Parent.Damage.Value)
		elseif part.Parent.Parent:FindFirstChild("Humanoid") then
			part.Parent.Parent.Humanoid:TakeDamage(script.Parent.Damage.Value)
		end
		script.Parent:Destroy()
		break
	end
end

This code is inside the bullet which is inside serverstorage so the script can grab the bullet, put it in workspace and be done.