Zum Inhalt

Performance Best Practices

Guide for optimizing code performance in FiveM resources.


Distance Calculations

❌ Slow - GTA Native:

local distance = GetDistanceBetweenCoords(coords.x, coords.y, coords.z, v.coords.x, v.coords.y, v.coords.z, true)

✅ Fast - FiveM Native:

local distance = #(coords - v.coords)

The FiveM vector math is significantly faster and more readable.


Loop Optimization

Cache Frequently Used Values

❌ Bad:

for i = 1, #players do
    local player = players[i]
    local ped = GetPlayerPed(player)
    local coords = GetEntityCoords(ped)
    -- Using GetPlayerPed and GetEntityCoords repeatedly is expensive
end

✅ Good:

local playerPed = PlayerPedId()
local playerCoords = GetEntityCoords(playerPed)

for i = 1, #players do
    local player = players[i]
    -- Use cached values when possible
end

Use Citizen.Wait Wisely

❌ Bad:

Citizen.CreateThread(function()
    while true do
        Citizen.Wait(0) -- Runs every frame unnecessarily
        -- Code that doesn't need to run every frame
    end
end)

✅ Good:

Citizen.CreateThread(function()
    while true do
        Citizen.Wait(1000) -- Only run once per second
        -- Code that checks states periodically
    end
end)


Entity Checks

Local Player Checks

❌ Slow:

local playerPed = GetPlayerPed(-1)

✅ Fast:

local playerPed = PlayerPedId()

Entity Existence

❌ Slow:

if DoesEntityExist(entity) and not IsEntityDead(entity) then
    -- Multiple native calls
end

✅ Fast:

if Entity(entity).state.exists then
    -- Use statebags when appropriate
end


Table Operations

Pre-allocate Tables

❌ Bad:

local results = {}
for i = 1, 1000 do
    table.insert(results, i) -- Resizes array repeatedly
end

✅ Good:

local results = {}
for i = 1, 1000 do
    results[i] = i -- Direct assignment is faster
end

Local Variable Access

❌ Slow:

for i = 1, #bigTable do
    math.sqrt(bigTable[i]) -- Global lookup every iteration
end

✅ Fast:

local sqrt = math.sqrt -- Cache global function
for i = 1, #bigTable do
    sqrt(bigTable[i])
end


Network Events

Batch Updates

❌ Bad:

for i = 1, 100 do
    TriggerServerEvent('updateItem', i)
end

✅ Good:

local batch = {}
for i = 1, 100 do
    batch[#batch + 1] = i
end
TriggerServerEvent('updateItems', batch)

Use Statebags for Frequent Updates

❌ Bad:

-- Triggering events every frame
TriggerClientEvent('updatePosition', -1, coords)

✅ Good:

-- Use entity state bags for synchronized state
Entity(entity).state.position = coords


General Tips

  1. Avoid pairs() for arrays - Use numeric for loops with #table instead
  2. Cache GetEntityCoords() - Don't call it multiple times in the same frame
  3. Use zone systems - Check proximity before doing expensive operations
  4. Profile your code - Use profiler start and profiler view commands
  5. Minimize network traffic - Only send data that changed
  6. Use locals - Local variables are faster than globals
  7. Avoid string concatenation in loops - Use table.concat() instead

Profiling Commands

profiler start <resourceName>  # Start profiling a resource
profiler view                  # View profiling results
profiler dump                  # Dump detailed profiling data