عندما نفكر في تحسين أداء وسرعة الموقع، أهم عامل يجب القيام به هو عمل Caching للبيانات الراجعة من جمل eloquent، ومن روائع لارافيل أنها تأتي بمجموعة من المكتبات المثبته مسبقا للقيام بعملية caching بشكل سهل.
لفرض أننا نريد أن نقوم بإستخراج جميع مؤلفين الكتب والكتب التابعة لهم والتعليقات على هذه الكتب من قاعدة بيانات تحتوي على 200 مؤلف و 1500 كتاب و 3000 تعليق
ملاحظة يجب تثبيت باكيج laravel_debuger لقياس الأداء
composer require barryvdh/laravel-debugbar --dev
in eloquent
public function index(){ $authors= Author::select('id','title') ->with(['book' => function ($q) { $q->select('id', 'title','author_id') ->with('book_comment:id,comment,book_id'); }]) ->get(); return view('books',compact('authors')); }
نلاحظ أن إستخراج البيانات أخذ وقت 366ms وجملة sql على يسار الصورة
ولتحسين الوقت وتحسين أداء الموقع، يمكننا إستخدام cache من خلال دالة cache()->remember وهي تأخذ معلمات (إسم للكاش (اي اسم)، وقت الكاش، جملة eloquent).
public function index(){ $authors=cache()->remember('home_page_authors',60 * 60 * 60,function(){ return Author::select('id','title') ->with(['book' => function ($q) { $q->select('id', 'title','author_id') ->with('book_comment:id,comment,book_id'); }]) ->get(); }); return view('books',compact('authors')); }
نلاحظ من الصوره أن وقت جلب البيانات أصبح 120ms بدلا من 366ms، وعلى يسار الشاشة نلاحظ أنه لم يكن هناك أي إستعلام من قاعدة البيانات.
كيف يمكن مسح الكاش
يمكن مسح الكاش من خلال cache()->forget ومن ثم إسم الكاش الذي قمنا بتحديده مسبقاً
public function index(){ cache()->forget('home_page_authors'); $authors=cache()->remember('home_page_authors',60 * 60 * 60,function(){ return Author::select('id','title') ->with(['book' => function ($q) { $q->select('id', 'title','author_id') ->with('book_comment:id,comment,book_id'); }]) ->get(); }); return view('books',compact('authors')); }
كيف يعمل cache
بداخل المجلد config يوجد ملف بإسم caching به مجموعة من drivers لعملية الكاش، وبالوضع الإفتراضي يتم تخزين الكاش في ملف.
'default' => env('CACHE_DRIVER', 'file'),
الملف الذي يتم تخزين البيانات به يوجد في المسار storage->framework->cache->data وبها يتم إنشاء مجلدات وملفات الكاش.
مثاال أخر على عمل cache مع تمرير باراميتر.
public function snippetsDetails($id){ $snipp = cache()->rememberForever('snipp.'.$id, function() use($id) { return Snippet::select( 'id', 'text', )->where('active', 1) ->where('id',$id) ->firstOrFail(); }); }
كما نلاحظ هنا أنه تم تحديد مده الكاش rememberForever وليس مدة معينة.
لكن السؤال هنا ماذا لو كنا نمرر slug لكل مقال حتى تكون الروابط صديقة لمحركات البحث، فإن الزوار سوف يشاهدون المحتوى القديم من الكاش، هذا صحيح لكن يمكننا معالجة ذللك من خلال الموديل حيث يمكننا إدارة عمليه الكاش عند التعديل والحذف، وذلك من خلال إضافة دالة boot بداخل الموديل
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Snippet extends Model { public static function boot(){ parent::boot(); static::updating(function ($instance) { // update cache content Cache::put('snipp.'.$instance->slug,$instance); }); static::deleting(function ($instance) { // delete post cache Cache::forget('snipp.'.$instance->slug); }); } }
كيف يمكن عمل cache لدوال appServiceProvider
عمل cache لدوال share
$setting = cache()->remember('site_setting', 3600, function () use ($name_site, $desc_site, $keyword) { return Settings::select( '' . $name_site . ' as site_name', ''.$desc_site.' as site_desc', ''.$keyword.' as site_keyword')->first(); }); View::share('settings', $setting);
عمل cache لدوال composer
View::composer(['front.index','front.history'], function ($view){ $education = cache()->remember('education', 60 * 60 * 60, function () { return Education::select( 'title_' . LaravelLocalization::setLocale() . ' as title', 'from_date', 'to_date' )->where('active',1)->get(); }); $view->with('education', $education); });
الله يعطيك العافية
شكرا جزيلا لهذه المعلومات القيمة
روعه
معلومات قيمة جدا
مقال رائع جدا
شرح رائع وبسيط جدا عاشت ايدك
شرح جميل
اخر نقطتين بالنسبه لعمل كاش ل appServiceProvider و composer ممكن شرح اكتر ليهم يعني ايه فايدتهم واكتبهم فين بالظبط مثلاً
زائر
Amazing