- Avoid monolithic stages; use the `needs:` keyword to create Directed Acyclic Graphs (DAGs) for faster, parallel execution.
- Utilize global `cache` strategically to share dependencies across jobs safely.
- Eliminate artificial bottlenecks caused by generic stages. Use the `needs:` keyword extensively to run independent jobs immediately.
- Differentiate between `cache` (for sharing node_modules/vendor dependencies between runs) and `artifacts` (for passing compiled binaries downstream to deployment jobs).
- Push docker images using the `$CI_REGISTRY_IMAGE` variable instead of hardcoding paths.