If you wanna keep script in this state, i will explain what could be done better. Start off by:
Saving an function call in:
local dimension = getElementDimension(localPlayer)
Currently, you are returning it every frame, while you could save it in main scope and avoid calling it. By using onClientElementDimensionChange to store localPlayer's current dimension.
local dimension = 0
function onClientElementDimensionChange(_, newDimension)
dimension = newDimension
end
addEventHandler("onClientElementDimensionChange", localPlayer, onClientElementDimensionChange)
Saving an another function call:
local px, py, pz = getElementPosition(getElementByID("ped1"))
I'm assuming that custom element is created on script init, otherwise you would need to update it at the time it creates.
-- Main scope
local myPed = getElementByID("ped1")
-- Render scope
local px, py, pz = getElementPosition(myPed)
For next step, you could use custom implementation of getDistanceBetweenPoints3D which is faster from MTA (thanks @Sarrum)
local function getDistance3D(pFirstX, pFirstY, pFirstZ, pSecondX, pSecondY, pSecondZ)
pFirstX, pFirstY, pFirstZ = pFirstX - pSecondX, pFirstY - pSecondY, pFirstZ - pSecondZ
return (pFirstX * pFirstX + pFirstY * pFirstY + pFirstZ * pFirstZ) ^ 0.5
end
Another thing which most of scripters forget about is using tocolor in render, even if color doesn't change...
tocolor(3, 169, 252, 255) -- notice () - a function call which returns same color every frame
The solution will be to save it in local variable in main scope and later use it.
-- Main scope
local textColor = tocolor(3, 169, 252, 255)
-- Render scope
dxDrawText("Unknown", sx, sy, sx, sy, textColor, 2.02, "default-bold", "center", "center", false, false, false, false, false)
If color isn't static you could use, for example events or timers which will be ideal way to update it.
Other than that, you might use onClientElementStreamIn/onClientElementStreamOut to add/remove handler when ped appears or disappears from stream zone, as mentioned above by Dutchman101.