Thursday, 14 June, 2018 UTC


Summary

As your web application begins to grow in functionality and usage, the need to optimize it performance arises, so as to give your users a better experience when using your application. Come to think of it, nobody actually like slow applications. You tend to lose users with slow applications, which is bad for your business.
In this article, I will be sharing with you a few ways and techniques to optimize your Laravel application.
Routes caching
Routes caching will drastically decrease the amount of time it takes to register all of your application’s routes. To generate a route cache, we make use of the Artisan route:cache command:
    $ php artisan route:cache
Now, instead of loading routes from routes/web.php, the cached routes file will be loaded on every request. Because when new routes are added, you will need to generate a fresh route cache, the route:cache command should only be run during your project’s deployment.
To clear the route cache, you may use the route:clear command:
    php artisan route:clear
NOTE: Closure based routes cannot be cached. To use route caching, you must convert any Closure routes to controller classes.
Configuration caching
Just as with routes caching, we can also cache all our configuration files. We make use of the Artisan config:cache command, which will combine all of the configuration options for our application into a single file which will be loaded quickly by the framework.
    $ php artisan config:cache
As with the route:cache command, this command should only be run during your project’s deployment. The command should not be run during local development as configuration options will frequently need to be changed during the course of your application’s development.
NOTE: if you execute the config:cache command during your deployment process, you should be sure that you are only calling the env function from within your configuration files. Once the configuration has been cached, the .env file will not be loaded and all calls to the env function will return null.
Eager loading
A common problem when retrieving Eloquent relationships is the N + 1 query problem. Let’s consider this scenario: we have two models: Car and Owner, with some sort of relationship. Assume we want to retrieve all cars and their respective owners. To achieve that, we might have the following code:
    $cars = App\Car::all();

    foreach ($cars as $car) {
      echo $car->owner->name;
    }
This loop will execute one query to retrieve all of the cars in the database, then another query for each car to retrieve the owner. To further explain this, imagine we have 100 cars, this loop would run 101 queries: one for the original car, and an additional 100 queries to retrieve the owner of each car. This may seems like a few queries, obviously because we are using a small data set. But imagine a large data set and the number of queries that would be made on the database. Yeah, you get the picture.
To solve this problem, we make use of eager loading. So instead of the above code, we’ll have:
    $cars = App\Car::with('owner')->get();

    foreach ($cars as $car) {
      echo $car->owner->name;
    }
At the point of retrieving all the cars, we eager load the owner of the cars as well. With this, we have reduced this operation to just two queries.
Queues
Queues can also be used to improve the performance of an application. Imagine we have an application that seeds a welcome email to new users upon sign up, and this application makes use of third-party email service such as Mailgun for sending the mails. When a user fills and submits the sign up form, a new user record will be inserted into the database, then a call will be made to Mailgun to send the welcome email. The actual sending of the email can take a few seconds (or milliseconds as the case may be). So as not to make the users think the sign up process is slow, we can make use of queue by queuing the email sending to run as a background task. That way, our users will get a prompt response from the signup form, while the email sending process runs in the background. In code this might look like below:
    public function register(Request $request)
    {
      // validate form inputs
      $this->validator($request->all())->validate();

      // persist user to database
      $user = $this->create($request->all());

      // send welcome email
      Mail::to($user)->send(new WelcomeEmail($user));

      // log user in
      $this->guard()->login($user);

      return $this->registered($request, $user) ?: redirect($this->redirectPath());
    }
Aside from slightly increasing the performance of the application, it also improves the user experience.
Database caching
With caching backends like Redis and Memcached, we can also cache database results. Instead of having to retrieve the same set of results from the database over and over again. We could employ database caching, by first retrieving the records from the database and then caching it for later use. For example:
    $value = Cache::remember('users', $minutes, function () {
      return DB::table('users')->get();
    });
The code above will retrieve all users from the cache or, if they don’t exist, retrieve them from the database and add them to the cache.
For records you know are likely not to change, such as a record of countries in the world, we could store them in the cache forever:
    $value = Cache::rememberForever('countries', function() {
      return DB::table('countries')->get();
    });
With little or no calls to your database, you will see a great improvement in the performance of your application.
Assets bundling
Every Laravel applications comes with Laravel Mix by default. Laravel Mix provides a fluent API for defining Webpack build steps for your Laravel application using several common CSS and JavaScript pre-processors. We can use Laravel Mix to compile our application assets, such as scripts and styles. For example, we can concatenate several stylesheets into a single file:
    mix.styles([
      'public/css/vendor/normalize.css',
      'public/css/styles.css'
    ], 'public/css/all.css');
This will create all.css, which will contain styles from normalize.css and styles.css. This way, we just use all.css in our HTML, instead of having to include each of them (normalize.css and styles.css) individually. This will in turn reduce the number of HTTP requests needed to retrieve these files individually. So just one request instead of two. Because our application now needs to retrieve just one file, we notice slight increase in the speed of our application.
Assets minifying
As a result of assets compilation, we might end up with a large single file, which might not allow the application to benefit from the initial compilation. To resolve this, we can tell Laravel Mix to minify our assets:
    $ npm run production
This will run all Mix tasks and make sure our assets are production ready by minifying them. Once minified, the assets will become smaller in size, hence will be retrieved faster, which will in turn speed up the performance of our application.
Running the latest version of PHP
With the latest version of PHP, we have seen a significant improvement in performance of PHP itself. So as much as possible ensure your Laravel application is running on the latest version of PHP, so as to tap in into these improvements.
Laravel Debugbar
Though not an optimization technique, but a package. Laravel Debugbar is a package to integrate PHP Debug Bar with Laravel 5. It includes a ServiceProvider to register the debugbar and attach it to the output. It is a package that can be used to inspect the performance of your application. It is recommended to make use of this package while developing your application. Because with it, you can easily inspect how your application is running, and then improve accordingly.
Conclusion
In this article, we have seen various ways and techniques that we can use to optimize the performance of a Laravel application. Implement these techniques in your applications to see massive performance improvements. I hope you found this article helpful.
The post Optimizing the performance of a Laravel application appeared first on Pusher Blog.