Apa itu Lazy Loading?
Lazy loading adalah teknik yang digunakan oleh ORM (Object-Relational Mapper) seperti Eloquent untuk menunda pemuatan data dari database hingga benar-benar diperlukan. Hal ini dapat meningkatkan performa aplikasi karena hanya memuat data yang dibutuhkan saat diakses.
$user = User::find(1);
$posts = $user->posts;
Dalam contoh ini, ketika Anda mengambil modelUser
,postingan
terkait tidak langsung dimuat dari database. Sebaliknya, postingan hanya diambil ketika Anda secara eksplisit mengakses properti$user->posts.
Ini adalah bagaiamana lazy loading beraksi.
Masalah dengan Lazy Loading
Meskipun lazy loading dapat meningkatkan performa, namun dapat juga menyebabkan query yang tidak disengaja. Jika suatu hubungan antara model tidak di-eager load, setiap kali hubungan tersebut diakses, akan dilakukan query tambahan ke database. Hal ini dapat mengakibatkan penurunan performa aplikasi, terutama pada aplikasi dengan data yang besar.
Sebagai contoh:
$users = User::all();
foreach ($users as $user) {
echo $user->posts->count();
}
Dalam kasus ini, jika Anda memiliki 100 pengguna, Laravel akan mengeksekusi 101 kueri: satu untuk mengambil semua pengguna dan 100 lagi untuk mengambil postingan untuk setiap pengguna. Hal ini sangat tidak efisien, terutama ketika kumpulan data bertambah.
MemahamipreventLazyLoading
Laravel menyediakan metodepreventLazyLoading
untuk mencegah terjadinya query yang tidak disengaja. Dengan mengaktifkan metode ini, Eloquent akan melakukan eager loading secara otomatis untuk semua hubungan yang didefinisikan dalam model.
MengaktifkanpreventLazyLoading
Untuk mengaktifkanpreventLazyLoading
secara global, Anda dapat menggunakan metodeboot
dalamAppServiceProvider
seperti berikut:
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Database\Eloquent\Model;
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
Model::preventLazyLoading();
}
}
Mengaktifkan preventLazyLoading dalam Lingkungan Tertentu
Jika Anda ingin mengaktifkanpreventLazyLoading
hanya pada lingkungan tertentu, Anda dapat menggunakan fungsienv
untuk memeriksa nilai variabel lingkungan:
Anda mungkin tidak ingin mencegahpreventLazyLoading
di semua lingkungan (misalnya, production). Untuk membatasi ini pada lingkungan tertentu seperti development atau testing, Anda dapat mengaktifkannya secara bersyarat:
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Database\Eloquent\Model;
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
if ($this->app->isLocal()) {
Model::preventLazyLoading();
}
}
}
MenanganiExceptionsLazy Loading
Jika Anda perlu melakukan query lazy loading pada model tertentu, Anda dapat menggunakan metodewithout
untuk menonaktifkanpreventLazyLoading
sementara:
$user = User::find(1)->without('posts')->first();
Atau ketikapreventLazyLoading
diaktifkan, Laravel akan melemparkanIlluminate\Database\LazyLoadingViolationException
setiap kali mendeteksi adanya lazy loading. Exceptions ini memberikan informasi yang berguna, seperti model dan relasi di mana yang menjalankan lazy loading.
Anda dapat menangani pengecualian ini dengan memperbaiki kode untuk menggunakan pemuatan yang bersemangat atau dengan secara eksplisit mengizinkan pemuatan yang malas jika diperlukan.
Menggunakan Eager Loading untuk Menghindari Lazy Loading
Cara terbaik untuk menghindari query yang tidak disengaja adalah dengan menggunakan eager loading untuk memuat hubungan yang diperlukan secara eksplisit:
$users = User::with('posts')->get();
foreach ($users as $user) {
echo $user->posts->count();
}
Dengan menggunakanwith('posts')
, Anda menginstruksikan Laravel untuk memuat postingan terkait untuk semua pengguna dalam satu kueri, sehingga mengurangi jumlah total kueri menjadi hanya dua: satu untuk pengguna dan satu untuk postingan.
Menggunakanload
untuk Eager Loading Bersyarat
Jika Anda hanya ingin memuat hubungan tertentu berdasarkan kondisi tertentu, Anda dapat menggunakan metodeload
:
$user = User::find(1);
if ($user->is_active) {
$user->load('posts');
}
Menonaktifkan preventLazyLoading untuk Model Tertentu
Jika Anda ingin menonaktifkanpreventLazyLoading
untuk model tertentu, Anda dapat menggunakan metodedisableLazyLoading
dalam model tersebut:
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
protected $preventLazyLoading = false;
}
Pendekatan ini memungkinkan Anda secara selektif mengizinkan lazy loading pada model tertentu sekaligus menonaktifkannya secara global.
Manfaat Menggunakan preventLazyLoading
Meningkatkan performa:Mencegah query yang tidak disengaja dapat meningkatkan performa aplikasi, terutama pada aplikasi dengan data yang besar.
Mempermudah debugging:Dengan mengaktifkan
preventLazyLoading
, Anda dapat lebih mudah mengidentifikasi dan memperbaiki query yang tidak disengaja.Menjaga konsistensi data:Mencegah query yang tidak disengaja dapat membantu menjaga konsistensi data dalam aplikasi Anda.
Dengan menggunakanpreventLazyLoading
, Anda dapat menghindari query yang tidak disengaja dan meningkatkan performa aplikasi Laravel Anda.