Mencegah Lazy Loading dengan Model::preventLazyLoading()
Untuk mencegah masalah N+1 query yang tidak disengaja dalam aplikasi Laravel, Anda dapat menggunakan fitur preventLazyLoading(). Fitur ini akan melempar pengecualian (exception) saat aplikasi mencoba melakukan lazy loading pada relasi yang belum dimuat (eager loaded), sehingga memaksa pengembang untuk menggunakan with() secara eksplisit.
Implementasi ini paling tepat dilakukan di dalam metode boot() pada AppServiceProvider agar berlaku di seluruh aplikasi selama lingkungan pengembangan (development).
Implementasi Kode
namespace App\Providers;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function boot(): void
{
// Aktifkan hanya di lingkungan lokal/development
Model::preventLazyLoading(!app()->isProduction());
}
}Tabel Perbandingan: Lazy Loading vs Eager Loading
| Fitur | Lazy Loading | Eager Loading |
|---|---|---|
| Eksekusi Query | Per relasi saat diakses | Sekaligus di awal |
| Performa | Buruk (N+1 Problem) | Optimal |
| Penggunaan | $user->posts | User::with('posts')->get() |
| Rekomendasi | Hindari di loop | Gunakan selalu |
Mengapa Harus Mencegah Lazy Loading?
Masalah N+1 terjadi ketika Anda mengambil 100 data user, lalu di dalam loop Anda memanggil $user->profile. Laravel akan menjalankan 1 query untuk user, dan 100 query tambahan untuk setiap profile. Dengan preventLazyLoading(), Laravel akan menghentikan eksekusi dan memberikan peringatan LazyLoadingViolationException, sehingga Anda sadar bahwa Anda perlu menambahkan User::with('profile')->get().
Tips Troubleshooting
- Gunakan di Development Saja: Jangan pernah mengaktifkan ini di lingkungan produksi karena akan menyebabkan error bagi pengguna akhir jika ada relasi yang terlewat.
- Custom Exception: Anda bisa menyesuaikan perilaku saat pelanggaran terjadi dengan memberikan callback ke dalam metode
preventLazyLoading(bool $shouldPrevent, ?callable $callback = null). - Eager Loading Spesifik: Jika Anda hanya ingin mencegah pada model tertentu, Anda bisa memanggil metode tersebut langsung di dalam model yang bersangkutan.