In this lesson, you will learn how to turn Profiler insights into actionable code improvements to eliminate performance bottlenecks.
When you run your game through the Unity Profiler (as we practiced in lesson 23), you often see "spikes" in the CPU graph. If a specific script is highlighted as a performance hog, it is usually because it is performing expensive operations unnecessarily inside the Update() method, which runs every single frame.
The "Caching" Strategy
A common bottleneck is calling GetComponent<T>() or GameObject.Find() inside Update(). These methods scan your scene or object hierarchy, which is extremely slow. Instead, use the Caching technique: fetch the reference once in Start() and store it in a variable.
Inefficient Code:
void Update() {
// This scans the hierarchy 60+ times per second!
GetComponent<Rigidbody>().AddForce(Vector3.up);
}
Optimized Code:
private Rigidbody rb;
void Start() {
// Cache the reference once at startup
rb = GetComponent<Rigidbody>();
}
void Update() {
rb.AddForce(Vector3.up);
}
Reducing Update Frequency
If your Profiler data shows that a script is doing too much work, ask yourself: Does this really need to happen 60 times a second?
If you are checking for a distance between the player and an enemy, you don't need frame-perfect precision. You can use a Coroutine to "throttle" the logic to run only 5 or 10 times per second using WaitForSeconds. This significantly reduces CPU overhead without the player ever noticing a difference in gameplay. By combining Profiler data with these simple structural changes, you move from "it works" to "it runs smoothly."
Key Takeaway: Never perform expensive searches or heavy calculations inside Update() if you can calculate them once in Start() or spread the load across time using Coroutines.