Laravel Model Caching - Performance Boost Tutorial (ok)

https://www.itsolutionstuff.com/post/laravel-model-caching-performance-boost-tutorialexample.html

C:\xampp\htdocs\reset\app\Models\User.php

<?php
namespace App\Models;
use GeneaLabs\LaravelModelCaching\Traits\Cachable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable {
  // use HasApiTokens, HasFactory, Notifiable;
  use HasApiTokens, HasFactory, Notifiable, Cachable;
  /**
   * The attributes that are mass assignable.
   *
   * @var array<int, string>
   */
  protected $fillable = [
    'name',
    'email',
    'password',
  ];
  /**
   * The attributes that should be hidden for serialization.
   *
   * @var array<int, string>
   */
  protected $hidden = [
    'password',
    'remember_token',
  ];
  /**
   * The attributes that should be cast.
   *
   * @var array<string, string>
   */
  protected $casts = [
    'email_verified_at' => 'datetime',
  ];
}

C:\xampp\htdocs\reset\routes\web.php

<?php
use Illuminate\Support\Facades\Route;
// use App\Http\Controllers\ModelCacheController;
use App\Http\Controllers\UserController;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
    return view('welcome');
});
// Route::controller(ModelCacheController::class)->group(function () {
//   Route::get('/', 'index');
// });
// Auth::routes();
// Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home');
Route::get('users', [UserController::class,'index']);

C:\xampp\htdocs\reset\app\Http\Controllers\UserController.php

<?php
namespace App\Http\Controllers;
use App\Models\User;
class UserController extends Controller {
  /**
   * The application's index
   *
   * @var array
   */
  public function index() {
    $users = User::where('id', 1)->get();
    $users = User::where('id', 5)->get();
    $users = User::get();
    return view('users', compact('users'));
  }
}

C:\xampp\htdocs\reset\resources\views\users.blade.php

<!DOCTYPE html>
<html>
<head>
  <title>User List</title>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" crossorigin="anonymous">
</head>
<body>
<div class="container">
  <h1>User List- ItSolutionStuff.com</h1>
  <table class="table table-bordered">
    <tr>
      <th>Id</th>
      <th>name</th>
      <th>email</th>
    </tr>
    @foreach($users as $user)
    <tr>
      <td>{{ $user->id }}</td>
      <td>{{ $user->name }}</td>
      <td>{{ $user->email }}</td>
    </tr>
    @endforeach
  </table>
</div>
</body>
</html>

Lấy một bài viết khác để làm ví dụ

C:\xampp\htdocs\reset\app\Models\City.php

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class City extends Model {
  use HasFactory;
  public $table    = 'city';
  public $fillable = [
    'name',
    'desc',
  ];
  public function companies() {
    return $this->hasMany(City::class);
  }
}

C:\xampp\htdocs\reset\app\Models\Company.php

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Company extends Model {
  use HasFactory;
  public $table = 'company';
  public function city() {
    return $this->belongsTo(City::class);
  }
}

C:\xampp\htdocs\reset\database\migrations\2022_05_14_184238_create_entities.php

<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateEntities extends Migration {
  /**
   * Run the migrations.
   *
   * @return void
   */
  public function up() {
    Schema::create('company', function (Blueprint $table) {
      $table->increments('id');
      $table->string('name');
      $table->string('desc');
      $table->integer('city_id');
      $table->timestamps();
    });
    Schema::create('city', function (Blueprint $table) {
      $table->increments('id');
      $table->string('name');
      $table->string('desc');
      $table->timestamps();
    });
  }
  /**
   * Reverse the migrations.
   *
   * @return void
   */
  public function down() {
    Schema::dropIfExists('company');
    Schema::dropIfExists('city');
  }
}

C:\xampp\htdocs\reset\app\Http\Controllers\ModelCacheController.php

<?php
namespace App\Http\Controllers;
use App\Models\Company;
class ModelCacheController extends Controller {
  /**
   * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
   */
  public function index() {
    $view      = view('welcome');
    $companies = Company::all();
    $view->with('companies', $companies);
    return $view;
  }
}

C:\xampp\htdocs\reset\resources\views\welcome.blade.php

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Laravel</title>

    </head>
    <body class="antialiased">
        <ul>
          @foreach($companies as $company)
            <li>
              {{ $company->name }}
              {{ $company->city->name }}
            </li>
          @endforeach
        </ul>
    </body>
</html>

C:\xampp\htdocs\reset\routes\web.php

<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\ModelCacheController;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
    return view('welcome');
});
Route::controller(ModelCacheController::class)->group(function () {
  Route::get('/', 'index');
});
// Auth::routes();
// Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home');

C:\xampp\htdocs\reset\app\Http\Controllers\HomeController.php

<?php
namespace App\Http\Controllers;
class HomeController extends Controller {
  /**
   * Create a new controller instance.
   *
   * @return void
   */
  public function __construct() {
    // $this->middleware('auth');
  }
  /**
   * Show the application dashboard.
   *
   * @return \Illuminate\Contracts\Support\Renderable
   */
  public function index() {
    return view('home');
  }
}

C:\xampp\htdocs\reset\database\seeders\DemoSeeder.php

<?php
namespace Database\Seeders;
use App\Models\City;
use App\Models\Company;
use Faker\Factory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Seeder;
class DemoSeeder extends Seeder {
  /**
   * Run the database seeds.
   *
   * @return void
   */
  public function run() {
    Model::unguard();
    Company::truncate();
    City::truncate();
    for ($i = 0; $i <= 100; $i++) {
      $faker      = Factory::create();
      $city       = new City();
      $city->name = $faker->city;
      $city->desc = $faker->sentence();
      $city->save();
    }
    for ($i = 0; $i <= 1000; $i++) {
      $faker         = Factory::create();
      $company       = new Company();
      $company->name = $faker->company;
      $company->desc = $faker->sentence();
      $company->city()->associate(rand(1, 100));
      $company->save();
    }
  }
}

C:\xampp\htdocs\reset\database\seeders\DatabaseSeeder.php

<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder {
  /**
   * Seed the application's database.
   *
   * @return void
   */
  public function run() {
    // \App\Models\User::factory(10)->create();
    $this->call(DemoSeeder::class);
  }
}

Tạo dữ liệu :)

php artisan db:seed

Kết quả:

Sau khi đăng ký sử dụng cache Model con số không thể tin nổi 👍👍)

C:\xampp\htdocs\reset\app\Models\City.php

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use GeneaLabs\LaravelModelCaching\Traits\Cachable;
class City extends Model {
  // use HasFactory;
  use HasFactory, Cachable;
  public $table    = 'city';
  public $fillable = [
    'name',
    'desc',
  ];
  public function companies() {
    return $this->hasMany(City::class);
  }
}

C:\xampp\htdocs\reset\app\Models\Company.php

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use GeneaLabs\LaravelModelCaching\Traits\Cachable;
class Company extends Model {
  // use HasFactory;
  use HasFactory, Cachable;
  public $table = 'company';
  public function city() {
    return $this->belongsTo(City::class);
  }
}

Nhưng nhận thấy khi ta thay đổi bằng tay dữ liệu nó vẫn không thay đổi 😒😒😒

Giờ là lúc chúng ta nghiên cứu cách để xóa cache Model mỗi khi chúng ta cập nhật dữ liệu

Giờ chúng ta sử dụng cách xóa cache

php artisan modelCache:clear

Kết quả chúng đã thay đổi dữ liệu

Laravel Model Caching — Performance Boost

https://medium.com/@laravelbap/laravel-model-caching-performance-boost-ad2d8b4ada9e

Hoặc

http://laravel-bap.com/laravel-model-caching-performance-boost/?utm_source=medium_com&utm_medium=article

How to reduce 1002 MySQL queries in one page to 0 (zero) queries? In this tutorial, I will show how to use laravel model caching. This great library allows to fully cache entire eloquent objects and reduce queries to 0. Self-invalidating feature allows to regenerate data from database on model save, update, create etc..

You can read article with code highlight at Laravel-BAP.com

Where to use model caching?

If You have menu on each page, complex form with many drop-downs populated from database, lot data loaded in background (Language, Date Format, Time Format , Dictionaries etc) Cache it.

1. Create new application

Create a new application with composer. (Note: I have composer installed on Ubuntu, if you are using windows download composer.phar)

composer create-project — prefer-dist laravel/laravel modelcache

cd into project and install DebugBar and laravel-model-caching.

2. Installing required libs

Use artisan composer command to download libs. Don’t forget to publish vendors at the end.

— DebugBar will allow us to see queries to MySQLcomposer require barryvdh/laravel-debugbar –dev— Laravel Model Caching will allow us to cache entire modelscomposer require genealabs/laravel-model-caching

publish vendors

php artisan vendor:publish

3. Creating models

I will create 2 models Company and City. Company will have City as belongTo relation.

php artisan make:model Companyphp artisan make:model City<?phpnamespace App;use Illuminate\Database\Eloquent\Model;class City extends Model{public $table = ‘city’;public $fillable = [‘name’,‘desc’];public function companies(){return $this->hasMany(City::class);}}

4. Creating Migrations

We also need to create migrations for database tables.

php artisan make:migration create_entities<?phpuse Illuminate\Database\Migrations\Migration;use Illuminate\Database\Schema\Blueprint;use Illuminate\Support\Facades\Schema;class CreateEntities extends Migration{/*** Run the migrations.** @return void*/public function up(){Schema::create(‘company’, function (Blueprint $table) {$table->increments(‘id’);$table->string(‘name’);$table->string(‘desc’);$table->integer(‘city_id’);$table->timestamps();});Schema::create(‘city’, function (Blueprint $table) {$table->increments(‘id’);$table->string(‘name’);$table->string(‘desc’);$table->timestamps();});}/*** Reverse the migrations.** @return void*/public function down(){Schema::drop(‘company’);Schema::drop(‘city’);}}

5. Creating Seeders

We need some data to run tests

php artian make:seeder DemoSeeder<?phpuse Illuminate\Database\Seeder;class DemoSeeder extends Seeder{/*** Run the database seeds.** @return void*/public function run(){\Illuminate\Database\Eloquent\Model::unguard();\App\Company::truncate();\App\City::truncate();for ($i = 0; $i <= 100; $i++) {$faker = \Faker\Factory::create();$city = new \App\City();$city->name = $faker->city;$city->desc = $faker->sentence();$city->save();}for ($i = 0; $i <= 1000; $i++) {$faker = \Faker\Factory::create();$company = new \App\Company();$company->name = $faker->company;$company->desc = $faker->sentence();$company->city()->associate(rand(1,100));$company->save();}}}

Update DatabaseSeeder.php and add our newly created seeder to default Laravel seeder.

<?phpuse Illuminate\Database\Seeder;class DatabaseSeeder extends Seeder{/*** Run the database seeds.** @return void*/public function run(){$this->call(DemoSeeder::class);}}

6. Controller, Views, and Routing

Create new controller, update view and route.

php artisan make:controller ModelCacheController<?phpnamespace App\Http\Controllers;use App\Company;class ModelCacheController extends Controller{/*** @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View*/public function index(){$view = view(‘welcome’);$companies = Company::all();$view->with(‘companies’,$companies);return $view;}

Yes, ugly AF this should be done with(‘city’) eager-loading but this example shows how to use model cache.

Update Route

<?php/*Route::get(‘/’,[‘as’=>’welcome’,’uses’=>’ModelCacheController@index’]);

Update view

<!doctype html><html lang=”{{ app()->getLocale() }}”><head><meta charset=”utf-8"><meta http-equiv=”X-UA-Compatible” content=”IE=edge”><meta name=”viewport” content=”width=device-width, initial-scale=1"><title>Laravel</title><! — Fonts →<link href=”https://fonts.googleapis.com/css?family=Raleway:100,600" rel=”stylesheet” type=”text/css”></head><body><ul>@foreach($companies as $company)<li>{{ $company->name }}{{ $company->city->name }}</li>@endforeach</ul></body></html>

7. Testing

php artisan serve

Now what will happen when You will load localhost:8000 in the browser ?

What is happening? Because Laravel uses “lazy load” approach page is generating 1002 queries. (Yes, yes You can use “eager load” as I described in the previous article about performance but here I will show what we can do with caching).

8. Updating model

What I did. I added Cachable trait — with this all data from database will be stored in cache. Now if You will run again Your web app You will see 0 database queries.

<?phpnamespace App;use GeneaLabs\LaravelModelCaching\Traits\Cachable;use Illuminate\Database\Eloquent\Model;class City extends Model{use Cachable;public $table = ‘city’;public $fillable = [‘name’,‘desc’];public function companies(){return $this->hasMany(City::class);}}<?phpnamespace App;use GeneaLabs\LaravelModelCaching\Traits\Cachable;use Illuminate\Database\Eloquent\Model;class Company extends Model{use Cachable;public $table = ‘company’;public $fillable = [‘name’,‘desc’];public function city(){return $this->belongsTo(City::class);}}

Now when you will run localhost:8000 again.

Quite amazing, right?

9. Summary

  • I use this library for all my Laravel project where I need to get data from database and those data are mostly static. For example all dictionaries (Date Format, Time Format, Countries etc).

  • This library is self-invalidating models this means its refreshing cache when you will create, update, delete record via eloquent.

  • This library requires PHP 7.1.*

  • It’s better to use Redis in production.

You can read article with code highlight at Laravel-BAP.com

Laravel Model Caching - Performance Boost Tutorial

As we know, website performance is very important for site owner. If your website working smooth then traffic will be more and if you used eloquent cache then it's no longer load on server too. so in this post i will show you how to make mode caching and make performance boost you laravel application.

there are several ways to improve the performance of laravel website. As you know we almost looking to cache using htaccess and cache images, css, js and html file. if you cache css, js, html then it improve performance of website that i did in my previous tutorial, you can read from here: How to optimize Website Speed and Performance in Laravel?.

But if you have to fetch many records from a database and from many tables. so when you open link then more than one query always run on your web page. it takes time to fetch data from the database because it same process always when you load page, so basically it loads every time. At a long time when you have more data and mode visitors comes in our website then your server will be broken, but if you use laravel cache then it can save your server and improve page performance. Here we will use genealabs/laravel-model-caching package for model caching.

Laravel cache is very easy and simple way to use. Using Cache you will optimize your website page speed. So let's just follow bellow step and see how it works. We will use barryvdh/laravel-debugbar package also, this package will help to debug how many query fire on your page so you can see that. So just follow bellow step.

Step 1: Install Laravel 6 App

we are going to from scratch so, we need to get fresh Laravel 6 application using bellow command, So open your terminal OR command prompt and run bellow command:

composer create-project --prefer-dist laravel/laravel blog

Step 2: Installation Of barryvdh/laravel-debugbar Package

Now we will install barryvdh/laravel-debugbar composer package using by following command in our laravel 6 application. So let's run bellow command.

composer require barryvdh/laravel-debugbar --dev

Ok, after install package successfully, we will add service provider in app.php configuration file. So let's add as bellow:

config/app.php

<?phpreturn [	....	'providers' => [		....		Barryvdh\Debugbar\ServiceProvider::class,	],	'aliases' => [		....		'Debugbar' => Barryvdh\Debugbar\Facade::class,	]]

Then you can publish configuration files by following command:

php artisan vendor:publish --provider="Barryvdh\Debugbar\ServiceProvider"

Read Also: How to store all record in laravel Cache

Step 3: Installation Of genealabs/laravel-model-caching Package

Now we will install genealabs/laravel-model-caching composer package using by following command in our laravel 6 application. So let's run bellow command.

composer require genealabs/laravel-model-caching

Step 4: Update User Model

In this step, we will use GeneaLabs package class in User model So you have to update user model like as bellow:

app/User.php

<?phpnamespace App;use Illuminate\Notifications\Notifiable;use Illuminate\Foundation\Auth\User as Authenticatable;use GeneaLabs\LaravelModelCaching\Traits\Cachable;class User extends Authenticatable{    use Cachable;    use Notifiable;    /**     * The attributes that are mass assignable.     *     * @var array     */    protected $fillable = [        'name', 'email', 'password',    ];    /**     * The attributes that should be hidden for arrays.     *     * @var array     */    protected $hidden = [        'password', 'remember_token',    ];}

Step 5: Create Dummy Users

here we will create some dummy users records using factory. so you can run bellow command to create dummy users in your database.

php artisan tinkerfactory(App\User::class, 100)->create();

Step 6: Create Route

now will create one route for display users in view. so let's create one route as bellow listed:

routes/web.php

Route::get('users', 'UserController@index');

Step 7: Create Controller

we need to create new controller as UserController and then we will create index() on controller. we will get all users using User model and print in view:

app/Http/Controllers/UserController.php

<?phpnamespace App\Http\Controllers;use Illuminate\Http\Request;use App\User;class UserController extends Controller{		/**     * The application's index     *     * @var array     */    public function index()    {    	$users = User::where('id', 1)->get();    	$users = User::where('id', 5)->get();    	$users = User::get();    	return view('users',compact('users'));    }}

Step 8: Create Blade File

now at last we will create users.blade.php file and write code of display users lists. so let's create blade file:

resources/views/users.blade.php

<!DOCTYPE html><html><head>	<title>User List</title>	<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" crossorigin="anonymous"></head><body><div class="container">	<h1>User List- ItSolutionStuff.com</h1>	<table class="table table-bordered">		<tr>			<th>Id</th>			<th>name</th>			<th>email</th>		</tr>		@foreach($users as $user)		<tr>			<td>{{ $user->id }}</td>			<td>{{ $user->name }}</td>			<td>{{ $user->email }}</td>		</tr>		@endforeach	</table></div></body></html>

Now you are ready to run project, so let's check.

When you open first time page then it will load three queries as bellow:

Then again refresh and check, no longer query fired on server:

You can cache clear and check again:Read Also: Laravel 6 Install Vue JS Example

php artisan cache:clear

I hope it can help you....

Last updated