FiveM Profiler คืออะไร หา Script กิน CPU อย่างไร? วิธีหา Resource ทำ FPS ตกและ Server Hitch

FiveM Profiler คือเครื่องมือสำหรับบันทึก Performance ของ Script เพื่อค้นหาว่า Resource, Thread, Function หรือบรรทัด Code ใดใช้เวลาประมวลผลสูงผิดปกติ โดยสามารถใช้ได้ทั้งฝั่ง Client เพื่อหา Script ที่ทำ FPS ตก และฝั่ง Server เพื่อวิเคราะห์ Server Hitch หรือ Resource ที่ใช้ CPU สูง

คำสั่งพื้นฐานคือ

profiler record 500

ใช้บันทึก Profile ประมาณ 500 Frames

ตรวจสถานะด้วย

profiler status

เปิดดูผลด้วย

profiler view

หรือบันทึกออกเป็น JSON

profiler saveJSON profile.json

จากนั้นจึงเปิด Profile แล้วไล่ดู

CPU spike
↓
resource tick
↓
thread
↓
file
↓
line
↓
Code ที่ใช้เวลาสูง

นี่ดีกว่าการเดาว่า Script ไหนกิน CPU จากความรู้สึกเพียงอย่างเดียว

① FiveM Profiler คืออะไร

Profiler เป็น Performance Debugging Tool ของ Cfx.re

หน้าที่คือบันทึกว่าในช่วงเวลาที่ Capture

อะไรทำงาน?
ทำงานนานเท่าไร?
Resource ไหน?
Thread ไหน?
File ไหน?
Line ไหน?

จากนั้น Developer สามารถหา Code ที่สร้าง

  • FPS Drop

  • Micro Stutter

  • Server Hitch

  • CPU Spike

  • Resource Tick สูง

ได้แม่นยำขึ้น

② Profiler ใช้ Client ได้ไหม

ได้

เปิด FiveM F8 Console แล้วใช้

profiler record 500

เหมาะสำหรับวิเคราะห์ปัญหา Client-side เช่น

FPS ลดเมื่อเข้าเมือง
เปิด Inventory แล้วกระตุก
อยู่ใกล้ Garage แล้ว FPS ตก
เข้า Zone แล้ว Script ใช้เวลาเพิ่ม

Profiler ช่วยไล่ถึง Resource และ Thread ที่เกี่ยวข้องได้

③ Profiler ใช้ Server ได้ไหม

ได้เช่นกัน

ใช้จาก FXServer Console

profiler record 500

เหมาะกับ

Server Hitch Warning
CPU Spike
Player จำนวนมากแล้ว Server หน่วง
Resource บางตัวประมวลผลนาน

Cfx.re ระบุว่า Profiler สามารถใช้ทั้ง Client และ Server

④ Profiler ต่างจาก Resmon อย่างไร

จำง่าย ๆ

Resmon
→ ดูว่า Resource ไหนน่าสงสัย

ส่วน

Profiler
→ เจาะว่าข้างใน Resource นั้น Code ตรงไหนใช้เวลาสูง

ตัวอย่าง

resmon
↓
พบ my_hud = สูง
↓
profiler
↓
client/main.lua
↓
Thread
↓
บรรทัดที่ใช้เวลาสูง

ดังนั้นสองเครื่องมือนี้ควรใช้ร่วมกัน

⑤ FiveM Resmon คืออะไร

Resource Monitor หรือ resmon ใช้ดู Resource Performance ฝั่ง Client

เปิดด้วย

resmon true

ปิดด้วย

resmon false

Resource Monitor แสดงข้อมูลอย่าง

CPU time
Memory usage
Resource

ช่วยหา Resource ที่ควรนำไป Profile ต่อ

⑥ Resmon ใช้ Server ได้ไหม

Cfx.re Documentation ปัจจุบันอธิบาย resmon เป็น Client Resource Monitor

ถ้าต้องวิเคราะห์ Server-side ให้ใช้

Server Profiler
txAdmin Monitoring
Server Console

ร่วมกันตามปัญหา

⑦ Resmon ขึ้น Access denied ทำอย่างไร

บาง Production Builds อาจพบ

Access denied for command resmon

Cfx.re ระบุว่าอาจต้องเปิด Developer Mode โดย Launch Client พร้อม Argument

+set moo 31337

ตาม Development Environment ที่ใช้งาน

ไม่ควรเปิดหรือเปลี่ยน Production Configuration แบบสุ่มหากไม่จำเป็น

⑧ คำสั่ง profiler record คืออะไร

รูปแบบ

profiler record <frames>

ตัวอย่าง

profiler record 500

เอกสาร Cfx.re ใช้ 500 Frames เป็นจุดเริ่มต้นที่เหมาะสำหรับ Capture ช่วงเวลาหนึ่ง

จำนวน Frames มากขึ้นหมายถึง Capture ยาวขึ้นและมีข้อมูลมากขึ้น

⑨ ทำไมเริ่มจาก 500 Frames

เพราะ Capture สั้นเกินไปอาจไม่ทันเจอปัญหา

เช่น

Profiler 10 frames
↓
ปัญหาเกิดหลังจากนั้น
↓
ไม่เจอ

500 เป็นเพียง Starting Point

หากปัญหาเกิดเป็นช่วง ๆ อาจต้อง Capture ให้ครอบช่วงที่เกิดอาการจริง

⑩ ต้องเปิด Profiler ตอนมีปัญหาหรือไม่

ควร

ถ้า FPS ตกเฉพาะตอน

เปิด Inventory
เข้า Garage
เข้าเมือง
มีผู้เล่น 100 คน
เริ่ม Mission

ควร Record ขณะทำ Action นั้น

ไม่ใช่ Record ตอนยืนเฉย ๆ แล้วสรุปว่า Resource ไม่มีปัญหา

⑪ profiler status ใช้ทำอะไร

ใช้ดูสถานะการ Capture

profiler status

เช่น

กำลัง Recording หรือไม่
เก็บไปกี่ Frames แล้ว
Capture เสร็จหรือยัง

ช่วยยืนยันว่า Profiler ทำงานจริงก่อนเปิดดูผล

⑫ profiler view ใช้ทำอะไร

หลัง Capture เสร็จใช้

profiler view

เพื่อดู Profile

ฝั่ง Client สามารถเปิด Viewer ผ่าน Browser ตาม Workflow ของ Cfx.re

ฝั่ง Server เอกสารระบุว่าจะไม่ได้เปิด Chrome ให้อัตโนมัติแบบ Client และต้องใช้ URL ที่ Console ให้มา

⑬ profiler saveJSON คืออะไร

ใช้บันทึก Capture เป็นไฟล์ JSON

profiler saveJSON fivem-profile.json

ข้อดีคือ

เก็บหลักฐาน
เปรียบเทียบก่อน/หลัง
ส่งให้ Developer วิเคราะห์
เปิดภายหลัง

เหมาะกับปัญหาที่ต้องวิเคราะห์ละเอียด

⑭ Profile JSON เปิดอย่างไร

ตาม Cfx.re Guide สามารถใช้ Chrome Developer Tools

Flow โดยรวมคือ

saveJSON
↓
Chrome
↓
Developer Tools
↓
Performance
↓
Load Profile

แล้ววิเคราะห์ Timeline

⑮ Profiler แสดงอะไร

หนึ่งในสิ่งสำคัญคือ CPU Time Timeline

มักเห็น

Normal frames
Normal frames
CPU spike
Normal frames

CPU Spike ที่สัมพันธ์กับ FPS Drop หรือ Hitch เป็นจุดที่ควร Zoom เข้าไปดู

⑯ CPU Spike คืออะไร

เป็นช่วงที่ Processing Time สูงกว่าปกติอย่างชัดเจน

Concept

ปกติ
1–2 ms

บาง Frame
20 ms

Frame ที่ Spike อาจทำให้เกิด

Micro Stutter
FPS Drop
Server Hitch

แต่ไม่ควรตั้ง Threshold ตายตัวโดยไม่ดู Context

⑰ Frame Time สำคัญอย่างไร

Frame Time คือเวลาที่ใช้ประมวลผล Frame หนึ่ง

ถ้าเป้าหมาย 60 FPS

เวลาเฉลี่ยต่อ Frame ทั้งระบบประมาณ

16.67 ms

แต่ Script ไม่ควรใช้ Budget ทั้งหมดเพียง Resource เดียว

FPS จริงยังขึ้นกับ

Game
GPU
CPU
FiveM
Scripts
NUI
Streaming

ทั้งหมดรวมกัน

⑱ Profiler หา Resource Tick ได้อย่างไร

เมื่อ Zoom เข้า CPU Spike จะสามารถดู Resource Tick Events

Concept

CPU spike
↓
resource tick
↓
my_resource
↓
thread
↓
client.lua

จากนั้น Hover/Inspect เพื่อดูเวลาที่ Thread ใช้

⑲ Profiler บอก File และ Line ได้ไหม

ได้ในกรณีที่ข้อมูล Source Mapping/Runtime รองรับ

Cfx.re Guide แสดงตัวอย่างที่ Profiler สามารถชี้ไปถึง

client.lua
lines 29–34

ทำให้ Developer ไม่ต้องเดาทั้ง Resource

แต่สามารถเริ่มจาก Code Section ที่มีปัญหาได้เลย

⑳ หา Script กิน CPU ด้วยวิธีไหนเร็วที่สุด

ใช้ Flow นี้

① เปิด resmon
↓
② หา Resource ที่สูง
↓
③ profiler record
↓
④ ทำ Action ที่ทำให้ Lag
↓
⑤ profiler view
↓
⑥ หา CPU spike
↓
⑦ เปิด resource tick
↓
⑧ หา thread/file/line
↓
⑨ แก้ Code
↓
⑩ Profile ใหม่

นี่เป็น Workflow ที่มีหลักฐานมากกว่าการสุ่มปิด Resource

㉑ อย่า Optimize ก่อนวัด

ตัวอย่างไม่ดี

FPS ตก
↓
เดาว่า Garage
↓
เขียน Garage ใหม่

แต่ Profiler อาจพบว่า Resource จริงคือ

custom_hud

ที่มี Loop ทุก Frame

ดังนั้น

Measure
↓
Find
↓
Fix
↓
Measure Again

ควรเป็นหลัก

㉒ Loop เป็นสาเหตุ Script กิน CPU บ่อยไหม

บ่อย

ตัวอย่าง

CreateThread(function()

    while true do

        Wait(0)

        -- heavy work

    end
end)

Wait(0) หมายถึงทำงานทุก Game Tick ของ Coroutine นั้น

ถ้างานข้างในหนัก ก็เกิด CPU Cost ทุก Frame

㉓ Wait(0) ผิดไหม

ไม่

มีงานบางอย่างต้องทำทุก Frame เช่น

DisableControlAction
DrawMarker บางรูปแบบ
Camera/Rendering logic

แต่ปัญหาคือใช้ Wait(0) กับสิ่งที่ไม่ต้องทำทุก Frame

เช่น

เช็ก Job
เช็ก Money
เช็ก Database State
ค้น Entity ทั้งเมือง

㉔ ใช้ Adaptive Sleep ช่วยอย่างไร

ตัวอย่าง

CreateThread(function()

    while true do

        local sleep =
            1000

        local ped =
            PlayerPedId()

        local coords =
            GetEntityCoords(
                ped
            )

        if IsNearGarage(
            coords
        ) then

            sleep =
                0

            -- interaction logic
        end

        Wait(
            sleep
        )
    end
end)

เมื่อ Player อยู่ไกล

Wait 1000

เมื่ออยู่ใกล้จึง

Wait 0

ช่วยลด Work ที่ไม่จำเป็น

㉕ Distance Check กิน CPU ได้ไหม

หนึ่ง Check ไม่หนักมาก

แต่ถ้าทำ

1 Player
×
500 locations
×
ทุก frame

จะกลายเป็น Work จำนวนมาก

ควรพิจารณา

Spatial filtering
Nearest location
Zones
Adaptive wait
Cache

ตามระบบ

㉖ Nested Loop ต้องระวัง

ตัวอย่าง

for i = 1, #players do

    for j = 1, #vehicles do

        -- comparison

    end
end

ถ้า

players = 200
vehicles = 1000

เท่ากับ

200,000 comparisons

ต่อรอบ

ถ้าทำบ่อยมาก CPU Cost จะเพิ่มอย่างรวดเร็ว

㉗ Dictionary/Table Lookup ช่วยได้ไหม

แทนการค้น Array ทุกครั้ง

for i = 1, #vehicles do

    if vehicles[i].plate
        == plate then
        ...
    end
end

อาจสร้าง Lookup Table

VehiclesByPlate[
    plate
] = vehicle

แล้วใช้

local vehicle =
    VehiclesByPlate[
        plate
    ]

ถ้า Use Case เหมาะสม

㉘ Native Calls กิน CPU ได้ไหม

Native Call หนึ่งอาจไม่ได้เป็นปัญหา

แต่ถ้าเรียกหลาย Native ต่อ

ทุก frame
×
ผู้เล่นจำนวนมาก
×
Entities จำนวนมาก

Cost รวมสามารถสูงได้

Profiler ช่วยบอกว่าช่วงไหนของ Thread ใช้เวลามาก

㉙ Native ที่เรียกซ้ำควร Cache ไหม

บางค่าที่ไม่เปลี่ยนตลอด Frame สามารถ Cache

ตัวอย่าง

local ped =
    PlayerPedId()

แล้วใช้ ped หลายครั้งใน Loop รอบนั้น

แทนเรียก

PlayerPedId()

สิบครั้งใน Code Block เดียวโดยไม่จำเป็น

แต่ไม่ควร Cache Handle แบบถาวรหากมันสามารถเปลี่ยนได้

㉚ GetEntityCoords ทุก Frame ผิดไหม

ไม่เสมอ

Gameplay หลายอย่างต้องใช้ Position ต่อ Frame

แต่ถ้า Resource มี 30 Threads แต่ละ Thread เรียก Position ของ Player เอง ก็อาจรวม Logic ได้

เช่นมี Central Position Cache ที่ Update ตาม Frequency เหมาะสม

ขึ้นกับ Precision ที่ Feature ต้องการ

㉛ Entity Scan กิน CPU ได้ไหม

มากได้

เช่น Resource ทำ

หา Vehicle ทั้งหมด
หา Ped ทั้งหมด
หา Object ทั้งหมด

ซ้ำ ๆ

ถ้าทำทุก Frameบน Server/Client ที่มี Entity จำนวนมาก Cost สามารถสูง

ควร Track Entity ที่ Resource สร้างเองแทน Scan โลกทั้งหมดเมื่อทำได้

㉜ อย่า Scan ทั้งโลกเพื่อหา Entity ตัวเดียว

ถ้า Resource เป็นผู้สร้าง Entity

เก็บ

Entity handle
Network ID
Database ID

ตาม Context ที่เหมาะสม

ดีกว่าทุกครั้งต้อง

วนหา Vehicle ทุกคัน
↓
เทียบ Plate

㉝ Event-driven ดีกว่า Polling เมื่อไร

ถ้าข้อมูลเปลี่ยนเฉพาะเมื่อ Event เกิด

เช่น

Job เปลี่ยน
Money เปลี่ยน
Vehicle spawned
Player loaded

ใช้ Event

State changed
↓
Handler

ดีกว่า

ทุก 100 ms
↓
เช็กว่าค่าเปลี่ยนหรือยัง

ในหลาย Use Case

㉞ ตัวอย่าง Polling ที่ไม่จำเป็น

CreateThread(function()

    while true do

        Wait(100)

        local job =
            GetCurrentJob()

        if job ~= lastJob then
            ...
        end
    end
end)

ถ้า Framework มี Event

job changed

ควรใช้ Event นั้นแทน

㉟ Event เยอะเกินไปกิน CPU ได้ไหม

ได้หาก Trigger ถี่มาก

เช่น

TriggerServerEvent
ทุก frame

จาก Client 100 คน

สามารถสร้าง

Network traffic
Server event handling
Serialization
Validation

จำนวนมาก

ต้อง Profile ทั้ง Client และ Server

㊱ TriggerServerEvent ทุก Frame ควรทำไหม

โดยทั่วไปไม่ควร

ถ้าต้อง Sync Data ความถี่สูง ต้องพิจารณา Architecture ใหม่

เช่น

ส่งเฉพาะเมื่อเปลี่ยน
Throttle
Batch
State Bag
Server-side calculation

ตาม Use Case

㊲ JSON Encoding กิน CPU ได้ไหม

ได้ถ้า Object ใหญ่หรือเรียกบ่อย

เช่น

Inventory 5,000 items
↓
json.encode
↓
ทุก 100 ms

จะสร้างทั้ง CPU และ Memory Allocation

ควรส่งเฉพาะ Delta หรือเปลี่ยน Frequency

㊳ Table Sort กิน CPU ได้ไหม

ถ้า Sort ข้อมูลจำนวนมากซ้ำทุก Frame

table.sort(
    largeTable,
    comparator
)

อาจหนัก

ถ้าข้อมูลเปลี่ยนเฉพาะตอนเพิ่ม/ลบ

Sort ตอนข้อมูลเปลี่ยนจะดีกว่า Sort ทุก Frame

㊴ String Operations มีผลไหม

มีเมื่อทำจำนวนมาก

เช่น

string.format
concatenation
pattern matching
JSON building

หลายหมื่นครั้งต่อ Tick

แต่ไม่ควร Micro-optimize String ก่อน Profiler บอกว่ามันเป็น Bottleneck จริง

㊵ Database Query ทำให้ Server Hitch ได้ไหม

Cfx.re ระบุว่า Hitch Warnings บางครั้งเกิดจาก

Underperforming SQL queries
Unoptimized loops

ดังนั้นหาก Server Profiler/Console ชี้ช่วง Database Activity ต้องตรวจ SQL ด้วย

แต่ต้องแยก

CPU-heavy code

ออกจาก

Database latency

เพราะวิธีแก้ต่างกัน

㊶ SQL ช้าควรแก้อย่างไร

จากบทความก่อนหน้า ใช้

Slow Query
↓
EXPLAIN
↓
Index
↓
Rows Examined
↓
Query Frequency
↓
N+1
↓
Cache

อย่าพยายามแก้ SQL ช้าด้วยการเพิ่ม Wait()

㊷ MySQL await กิน CPU เสมอไหม

ไม่ควรตีความว่า .await เท่ากับ Busy Loop

Coroutine ปัจจุบันจะรอ Result

แต่ถ้า Application ยิง Queries จำนวนมากหรือ Query ใช้เวลาสูง ก็ยังสร้าง Load และ Latency ให้ Server ได้

Profiler และ Slow Query Tools ควรใช้ร่วมกัน

㊸ Callback ซ้อนกันมีผลไหม

Callback Nesting เองไม่ได้แปลว่ากิน CPU

แต่ Architecture ที่ทำ

Callback
↓
Query
↓
Loop
↓
Callback
↓
Query

จำนวนมากต่อ Action อาจสร้าง Work มาก

ต้อง Profile Execution Path จริง

㊹ NUI กิน CPU ดูจาก Profiler อย่างเดียวพอไหม

ไม่เสมอ

NUI มี Browser Runtime ของตัวเอง

ถ้า Resource Lua เบา แต่

JavaScript loop
CSS blur
DOM updates
Video
Canvas

หนัก ปัญหาอาจอยู่ CEF/NUI

ใช้

NUI DevTools

ร่วมกับ Resmon/Profiler

㊺ NUI SendNUIMessage ถี่เกินไปมีผลไหม

มีได้

เช่น

60 messages/second
×
Payload ใหญ่
×
DOM render ใหม่ทุกครั้ง

แม้ Lua Thread ไม่หนักมาก Browser ก็อาจหนัก

ควร Profile End-to-end

㊻ GPU 100% แต่ Profiler ไม่พบ Script หนักทำอย่างไร

อาจเป็น GPU-bound ไม่ใช่ Script CPU-bound

Cfx.re มี

cl_drawperf true

สำหรับแสดง

FPS
Ping
Packet Loss
CPU Usage
GPU Usage
GPU Temperature

ถ้า GPU เต็มแต่ Script Time ต่ำ ปัญหาอาจเป็น Graphics/Rendering มากกว่า Lua Resource

㊼ cl_drawfps ใช้อะไร

ใช้เปิด FPS Counter

cl_drawfps true

ปิด

cl_drawfps false

ช่วยดูผลก่อน/หลัง Optimization แบบง่าย

แต่ FPS ตัวเลขเดียวไม่พอสำหรับระบุ Resource ต้นเหตุ

㊽ cl_drawperf มีประโยชน์อย่างไร

ช่วยแยกคร่าว ๆ ว่าอาการอาจเกี่ยวกับ

CPU
GPU
Network

มากน้อยอย่างไร

แล้วค่อยเลือก Tool

Script CPU
→ Profiler/Resmon

NUI
→ DevTools

Network
→ netgraph/metrics

GPU
→ Graphics investigation

㊾ Server CPU สูงต้องดู txAdmin ได้ไหม

ได้

txAdmin ปัจจุบันมี Monitoring สำหรับ

Server CPU
RAM
Server Threads Performance
Player Count

จึงใช้เป็นภาพรวมได้

ถ้าเห็น CPU Spike ช่วงหนึ่ง

ค่อยใช้ Server Profiler Capture ช่วงเดียวกันเพื่อหา Resource/Thread

㊿ Hitch Warning คืออะไร

Cfx.re อธิบาย Hitch Warning ว่าเป็นสัญญาณว่า Resource/Server Work บางอย่างใช้เวลานานกว่าที่ควร

ตัวอย่างสาเหตุ

SQL Query ช้า
Loop ไม่ Optimize
CPU-heavy Script Work

Profiler ถูกแนะนำให้ใช้เพื่อหาเหตุ

51 Hitch Warning ทุกครั้งเกิดจาก Resource เดียวไหม

ไม่จำเป็น

อาจเป็น

หลาย Resources รวมกัน
Database
CPU saturation
Server load

ดังนั้นต้อง Capture ช่วงที่เกิด Hitch จริง

อย่าปิด Resource ที่ชื่อโผล่ใน Consoleโดยไม่มีข้อมูลเพิ่ม

52 Profile ขณะ Server ว่างพอไหม

ไม่ ถ้าปัญหาเกิดตอนผู้เล่นเยอะ

ตัวอย่าง

10 Players
→ ไม่มีปัญหา

150 Players
→ Hitch

Profile ตอน Server ว่างอาจไม่พบ Bottleneck ที่ Scale ตาม Player Count

ต้องทดสอบ Workload ที่ใกล้เคียงปัญหาจริง

53 Profile Action แยกทีละอย่าง

ถ้าต้องการหา Garage Problem

ทำ

Record
↓
เปิด Garage
↓
Spawn Vehicle
↓
Stop

อย่า Capture ตอน

Garage
+
Inventory
+
Phone
+
Admin Menu
+
Teleport

ทั้งหมดพร้อมกันใน Development Test หากต้องการแยก Root Cause

54 Baseline คืออะไร

ก่อนแก้ควรบันทึก

Resmon
Profiler
FPS
CPU

ไว้

หลังแก้บันทึกอีกครั้ง

เช่น

Before
Thread = 3.5 ms

After
Thread = 0.4 ms

แบบนี้รู้ว่าการแก้มีผลจริง

55 อย่าใช้ Resmon ค่าเดียวตัดสิน Resource

Resource อาจแสดง Spike ชั่วคราวตอน

Load
Initialization
Player spawn

แต่เบามากระหว่าง Gameplay

ในทางกลับกัน Resource 0.1–0.2 ms ต่อเนื่องหลายตัวก็รวมเป็น Cost

ต้องดู Pattern ไม่ใช่ Screenshot หนึ่ง Frame

56 Memory สูงต้องดูด้วยไหม

Resmon แสดง Memory Usage ต่อ Resource ด้วย

ถ้า Memory เพิ่มขึ้นเรื่อย ๆ

เช่น

100 MB
↓
200 MB
↓
500 MB
↓
1 GB

อาจมี

Cache ไม่เคยลบ
Event data สะสม
Entity tracking table ไม่ Cleanup
Large NUI data

ต้องตรวจ Memory Lifecycle เพิ่มจาก CPU

57 Memory Leak Pattern ใน Lua

ตัวอย่าง

local History = {}

RegisterNetEvent(
    'event',
    function(data)

        History[
            #History + 1
        ] = data
    end
)

ถ้าไม่มี Limit/Cleanup

History โตตลอดอายุ Resource

CPU อาจปกติแต่ Memory เพิ่มต่อเนื่อง

58 Entity Tracking ต้อง Cleanup

เช่น

local Entities = {}

เมื่อ Entity ถูก Delete ควรเอาออกจาก Tracking Table หากไม่ต้องใช้ต่อ

ไม่เช่นนั้น Table อาจเก็บ Handles/Metadata เก่าจำนวนมาก

Profiler + Resource Monitor จึงควรดูทั้ง CPU และ Memory

59 Checklist FiveM Profiler

ก่อนสรุปว่า Script กิน CPU ตรวจ

① ปัญหาเกิด Client หรือ Server?
② เปิด resmon แล้วหรือยัง?
③ Resource ไหนสูง?
④ Capture ตอนเกิดปัญหาจริงหรือไม่?
⑤ profiler record ใช้ Frames เพียงพอหรือไม่?
⑥ profiler status ยืนยัน Capture หรือไม่?
⑦ profiler view เปิด Profile แล้วหรือไม่?
⑧ CPU Spike อยู่ตรงไหน?
⑨ Resource Tick ตัวไหน?
⑩ Thread ไหน?
⑪ File ไหน?
⑫ Line ไหน?
⑬ Loop ใช้ Wait เหมาะหรือไม่?
⑭ มี Wait(0) ที่ไม่จำเป็นหรือไม่?
⑮ Nested Loop หรือไม่?
⑯ Scan Entities ทั้งโลกหรือไม่?
⑰ Native ถูกเรียกซ้ำหรือไม่?
⑱ Cache ค่าได้หรือไม่?
⑲ Polling เปลี่ยนเป็น Event ได้หรือไม่?
⑳ TriggerServerEvent ถี่เกินไปหรือไม่?
㉑ JSON/Sort/String Work หนักหรือไม่?
㉒ Query Database ถี่เกินไปหรือไม่?
㉓ Slow Query หรือไม่?
㉔ N+1 Query หรือไม่?
㉕ NUI Message ถี่เกินไปหรือไม่?
㉖ Browser JavaScript หนักหรือไม่?
㉗ GPU เป็น Bottleneck หรือไม่?
㉘ Memory เพิ่มต่อเนื่องหรือไม่?
㉙ Resource Cleanup เมื่อ Stop หรือไม่?
㉚ Profile หลังแก้อีกครั้งหรือยัง?

⑥⓪ ตัวอย่างหา Script กิน CPU แบบครบ

สมมติผู้เล่นแจ้งว่า

เข้าเขต Garage
↓
FPS จาก 100
↓
เหลือ 55

ขั้นที่ 1 — เปิด Resmon

F8

resmon true

พบว่า

com_garage

ใช้ CPU Time สูงขึ้นเมื่อเข้า Garage

ขั้นที่ 2 — Capture Profiler

ก่อนเดินเข้า Garage

profiler record 500

จากนั้นเดินเข้า Zone ที่ทำ FPS ตก

ขั้นที่ 3 — ตรวจสถานะ

profiler status

รอให้ Capture เสร็จ

ขั้นที่ 4 — เปิด

profiler view

หา CPU Spike ตรงจังหวะเข้า Garage

ขั้นที่ 5 — Zoom resource tick

พบ

com_garage
↓
client/main.lua
↓
garage detection thread

ขั้นที่ 6 — เปิด Code

สมมติพบ

CreateThread(function()

    while true do

        Wait(0)

        local ped =
            PlayerPedId()

        local coords =
            GetEntityCoords(
                ped
            )

        for i = 1, #Garages do

            for j = 1, #Vehicles do

                CheckGarageVehicle(
                    coords,
                    Garages[i],
                    Vehicles[j]
                )

            end
        end
    end
end)

สมมติ

Garages = 100
Vehicles = 500

ต่อ Frame อาจทำ

50,000 operations

ใน Nested Loop ก่อนนับ Native/Function Work ด้านใน

ขั้นที่ 7 — ปรับ Architecture

แยกการหา Garage ใกล้ Player ด้วย Loop ความถี่ต่ำ

local nearestGarage =
    nil

CreateThread(function()

    while true do

        Wait(1000)

        local ped =
            PlayerPedId()

        local coords =
            GetEntityCoords(
                ped
            )

        nearestGarage =
            FindNearestGarage(
                coords
            )
    end
end)

แล้ว Thread ต่อ Frameทำเฉพาะเมื่อ Player อยู่ใกล้

CreateThread(function()

    while true do

        local sleep =
            1000

        if nearestGarage then

            local ped =
                PlayerPedId()

            local coords =
                GetEntityCoords(
                    ped
                )

            if IsNearGarage(
                coords,
                nearestGarage
            ) then

                sleep =
                    0

                DrawGarageInteraction(
                    nearestGarage
                )
            end
        end

        Wait(
            sleep
        )
    end
end)

ตอนนี้

หา Garage ทั้งหมด
→ ทุก 1 วินาที

Rendering interaction
→ ทุก Frame เฉพาะตอนอยู่ใกล้

แทน Scan ทุก Garage × ทุก Vehicle ทุก Frame

ขั้นที่ 8 — Profile ใหม่

ใช้

profiler record 500

ทำ Scenario เดิมอีกครั้ง

จากนั้นเปรียบเทียบ

Before
↓
After

ถ้า CPU Time ลดลงจริงจึงถือว่า Optimization มีผล

ตัวอย่าง Server Profiler กับ Hitch Warning

สมมติ Server Console มี Hitch ตอน Player Save

Capture

profiler record 500

แล้ว Trigger Save Scenario

พบ Thread ของ

player_save

กินเวลาสูง

เปิด Codeพบ

for _, player in pairs(
    GetPlayers()
) do

    SavePlayer(
        player
    )
end

และ SavePlayer ทำหลาย Queries ต่อ Player

สมมติ 200 Players

200
×
5 Queries
=
1,000 Queries

ใน Save Cycle เดียว

Root Cause อาจเป็น

N+1 Database Pattern
Mass save burst
Query Design

ไม่ใช่ Lua Loop เพียงอย่างเดียว

จึงต้องใช้ Profiler + Database Slow Query Analysis ร่วมกัน

วิธีลด Mass Save Spike

พิจารณา

Batching
Stagger save
ลด Query ต่อ Player
Transaction
Prepared Query
Dirty-state save

ตาม Framework Architecture

อย่าทำ

Wait(0)

ระหว่างทุก Queryแล้วคิดว่าปัญหา Database หาย

Dirty State คืออะไร

แทน Save Player ทุกคนทุกครั้ง

Track ว่า Player ไหนมีข้อมูลเปลี่ยน

DirtyPlayers[
    source
] = true

แล้ว Save เฉพาะ Data ที่เปลี่ยน

เหมาะกับบาง Architecture

แต่ต้องมี Reliability Strategy กรณี Crash/Disconnect

ตัวอย่าง Polling → Event-driven

ก่อน

CreateThread(function()

    while true do

        Wait(100)

        local cash =
            GetCash()

        if cash ~= lastCash then
            updateHud(cash)
        end
    end
end)

หลัง

RegisterNetEvent(
    'player:cashChanged',
    function(cash)

        SendNUIMessage({
            action = 'cash',
            value = cash
        })
    end
)

ลด Polling 10 ครั้งต่อวินาทีเหลือเฉพาะตอนเงินเปลี่ยน

อย่ารวมทุกงานไว้ Thread เดียว

ตัวอย่าง

CreateThread(function()

    while true do

        Wait(0)

        UpdateHud()
        FindGarage()
        FindPlayers()
        CheckInventory()
        ScanVehicles()
        UpdateBlips()
        UpdateJob()
    end
end)

เมื่อ Profiler พบ Thread นี้หนัก จะไม่รู้ Architecture ได้ง่าย

ควรแยก Work ตาม

Frequency
Responsibility
Trigger

เช่น

Every Frame
Every 200 ms
Every 1 second
Event-driven

แบ่งงานตาม Frequency

ตัวอย่าง

Every Frame
→ Draw interaction

100–250 ms
→ Speed / nearby state

1 second
→ nearest zone search

Event-driven
→ money/job/inventory updates

Server event
→ authoritative actions

นี่มักดีกว่า Loop เดียวที่ทำทุกอย่างทุก Frame

profiler ช่วยหา Script ไหน ไม่ได้บอกวิธีแก้ทุกครั้ง

Profiler เป็น Diagnostic Tool

มันบอกว่า

ตรงไหนแพง

แต่ Developer ยังต้องถามว่า

ทำไมมันแพง?
ต้องทำบ่อยขนาดนี้ไหม?
ลดข้อมูลได้ไหม?
เปลี่ยนเป็น Event ได้ไหม?
Cache ได้ไหม?
Index Database ได้ไหม?

Optimization จึงต้องใช้ความเข้าใจ Architecture ร่วมด้วย

อย่าไล่ลดทุก Resource ให้ 0.00 ms

เป้าหมายไม่ใช่ทำตัวเลขสวย

Resource ที่ทำ Gameplay จริงย่อมใช้ CPU

สิ่งที่ต้องหา คือ

Work ที่ไม่จำเป็น
Work ที่ทำถี่เกิน
Algorithm ที่ Scale ไม่ดี
Blocking/Slow operations

อย่าเสียเวลา Micro-optimize Code ที่ใช้เวลาเล็กมากแต่ไม่ใช่ Bottleneck

คำถามที่พบบ่อยเกี่ยวกับ FiveM Profiler

FiveM Profiler คืออะไร

เป็นเครื่องมือวิเคราะห์ Performance เพื่อหา Resource, Thread, File และ Code ที่ใช้เวลาประมวลผลสูง

FiveM Profiler ใช้ Client ได้ไหม

ได้ ใช้ใน F8 Console

ใช้ Server ได้ไหม

ได้ ใช้จาก Server Console เพื่อวิเคราะห์ Server Hitches และ Resource Performance

เริ่ม Profiler อย่างไร

profiler record 500

500 คืออะไร

จำนวน Frames ที่ต้องการ Capture และเป็น Starting Point ที่ Cfx.re Guide ใช้

ตรวจสถานะอย่างไร

profiler status

เปิด Profile อย่างไร

profiler view

Save Profile ได้ไหม

ได้

profiler saveJSON profile.json

Profiler ดู Resource ได้ไหม

ได้ สามารถเจาะ Resource Tick/Thread ตาม Profile

Profiler บอก File ได้ไหม

ได้ตามข้อมูลที่ Capture/Runtime ให้

บอก Line ได้ไหม

Cfx.re Guide แสดงตัวอย่างที่สามารถชี้ File และ Line ของ Thread ที่มีปัญหาได้

Resmon คืออะไร

Resource Monitor สำหรับดู CPU และ Memory Usage ของ Resources ฝั่ง Client

เปิด Resmon อย่างไร

resmon true

Resmon ต่างจาก Profiler อย่างไร

Resmon ช่วยหา Resource ที่น่าสงสัย ส่วน Profiler ช่วยเจาะ Code ภายใน Resource

Server มี Resmon ไหม

เอกสารปัจจุบันอธิบาย Resmon เป็น Client Resource Monitor สำหรับ Server ให้ใช้ Profiler/Monitoring Tools

Hitch Warning คืออะไร

เป็นสัญญาณว่า Server/Resource Work บางอย่างใช้เวลานานผิดปกติ

SQL Query ทำให้ Hitch ได้ไหม

ได้ Cfx.re ระบุ Slow SQL Queries เป็นหนึ่งในสาเหตุที่พบได้

Loop ทำให้ Hitch ได้ไหม

ได้ โดยเฉพาะ Unoptimized Loops

Wait(0) กิน CPU ไหม

หมายถึง Coroutine ทำงานทุก Tick จึงต้องระวัง Work ที่อยู่ข้างใน

Wait(0) ต้องห้ามไหม

ไม่ งานบางประเภทต้องทุก Frame แต่ควรใช้เฉพาะที่จำเป็น

Adaptive Wait ดีไหม

ดีสำหรับ Logic ที่ต้องทำถี่เฉพาะบาง State เช่น Player อยู่ใกล้ Interaction

Event ดีกว่า Loop ไหม

ถ้าข้อมูลเปลี่ยนจาก Event ชัดเจน Event-driven มักลด Polling ที่ไม่จำเป็น

Query Database ทุก Tick ได้ไหม

ไม่ควร

NUI กิน CPU ดูจาก Profiler ได้ทั้งหมดไหม

ไม่เสมอ Browser-side Work ควรตรวจด้วย NUI DevTools เพิ่ม

GPU 100% ใช้ Profiler แก้ได้ไหม

Profiler เน้น Script CPU Timing หากเป็น GPU-bound ต้องวิเคราะห์ Graphics/GPU เพิ่ม

ดู CPU/GPU FiveM อย่างไร

สามารถใช้

cl_drawperf true

ตาม Client Console Commands ปัจจุบัน

ดู FPS อย่างไร

cl_drawfps true

Server CPU ดูที่ไหน

txAdmin มี CPU/RAM และ Server Threads Monitoring และสามารถใช้ Profiler เจาะ Resource ต่อ

Memory Resource ดูได้ไหม

Resmon แสดง Memory Usage ของ Resources ฝั่ง Client

Profile ควรทำตอน Server ว่างไหม

ควร Profile ตอน Reproduce ปัญหาที่ต้องการวิเคราะห์ ถ้าปัญหาเกิดเฉพาะตอนผู้เล่นเยอะต้อง Capture ภายใต้ Workload ที่เหมาะสม

แก้แล้วต้อง Profile ใหม่ไหม

ควรเสมอ เพื่อยืนยันว่าการแก้ลด Cost จริงและไม่ย้ายปัญหาไปจุดอื่น

สรุป FiveM Profiler คืออะไร หา Script กิน CPU อย่างไร

วิธีหา Resource ที่ทำ FiveM กระตุกอย่างถูกต้องควรเริ่มจาก การวัด

ฝั่ง Client เริ่มได้ด้วย

resmon true

เมื่อพบ Resource ที่น่าสงสัย ใช้

profiler record 500

ตรวจสถานะ

profiler status

แล้วเปิดผล

profiler view

หรือเก็บไฟล์

profiler saveJSON profile.json

จากนั้นไล่

CPU Spike
↓
Resource Tick
↓
Thread
↓
File
↓
Line
↓
Code

เมื่อเจอ Code แล้วจึงพิจารณาว่า Bottleneck มาจาก

Wait(0) ที่ไม่จำเป็น
Nested Loop
Entity Scan
Native Calls จำนวนมาก
Polling
Events ถี่เกิน
JSON/Sort
Database Queries
N+1
NUI Messages
Memory Growth

และหลังแก้ต้องทำ Scenario เดิมแล้ว Profile ใหม่

Before
↓
Optimization
↓
After

เพื่อดูว่าดีขึ้นจริงหรือไม่

สำหรับ Developer ที่เรียน FiveM กับ comsiam สิ่งที่ควรจำคือ อย่าเริ่ม Optimize จาก Script ที่คุณคิดว่าน่าจะช้า ให้เริ่มจาก Resource ที่เครื่องมือชี้ว่าช้าจริง

หลักสำคัญจาก comsiam อีกข้อคือ Performance ที่ดีไม่ได้มาจากการใส่ Wait(1000) ทุก Loop แต่เกิดจากการออกแบบให้แต่ละงานทำตามความถี่ที่มันต้องการจริง — งาน Render จึงทำทุก Frame, งานตรวจ Zone ทำเป็นช่วง, ส่วน Money/Job/Inventory เปลี่ยนไปใช้ Event-driven เมื่อเหมาะสม

หัวข้อถัดไปคือ FiveM Resmon สูงแก้อย่างไร ลด Script กิน CPU และ Memory ซึ่งจะต่อจาก Profiler โดยตรง และรวมวิธีลด ms ของ Resource ตั้งแต่ Threads, Wait, Natives, Entity Scan, Events, NUI, Database, Memory Cache ไปจนถึง Checklist Optimization ก่อนนำ Script ขึ้น Production

Comments

Popular posts from this blog

FiveM ยังน่าเล่นไหม? Enhanced เปลี่ยน FiveM แค่ไหน

FiveM คืออะไร เล่นอย่างไร สำหรับมือใหม่ เริ่มต้นตั้งแต่ศูนย์

วิธีตั้ง Admin Permission ด้วย add_ace และ add_principal FiveM แบบละเอียด