Laravel

Laravel App - Code Optimizations Tips

Last month we started working on one of our internal project called InfyTracker, which we were planning to use as a simple time tracker and very little of project management or task reporting.

We have also published it as an open source project to our Github account so other people from the community can use it. It's still in alpha stage and we are still working on it and making tons of improvements. But, While building this project, we found a few things that we think might be useful to optimize the app or can be used in other projects. Also, I think lots of developers even do not realize these things.

So I planned to share it with the community where I will be discussing them in a detail with solutions we used. So here are the things/mistakes that we found during our project development.

  1. Adding all stylesheets and scripts in a layout file
  2. Not separating out page level CSS or JS
  3. Not using laravel-mix

1. Adding all stylesheets and scripts in layout



What I've seen is, when we want to add a new library/package to the project, people generally go to the layout file and just insert a style and script tag there.

For e.g., I want to use moment-js in the app, so what I do, I go to my layout file and include moment-js script tag there via CDN. Even if I only need moment-js in few of my pages. same can be there for other libraries like datatables, even if we only need datatables in a few pages of the app.

The problem it creates is, even if we don't need them in most of our pages, those files are still included in our page and of course, the page takes more time to load.

2. Not separating out page level CSS or JS

Generally, we use lots of JS in our code. And for all page level JS/CSS, most of the developers put it in a blade file of the page at the bottom with some section of JS/CSS.

For e.g., I have used a datatable in my page, so I need to initialize datatable. so generally, I will have declared one section called scripts or bottom_js which will be yield in my layout file. That's what I have seen in lots of code.

But, there are two problems with that,

  1. When that page is loaded, your JS code is completely visible to the world and sometimes that's not good and secure
  2. It's not minified (and since it's sitting into your blade files, there is no way to minify it either)

3. Not using laravel-mix

In really few projects or very few expert developers use laravel-mix or use laravel-mix in the right way. When you do not use laravel-mix in your site, your JS/CSS files are not minified. It's completely visible to the world which can be sometimes dangerous and file sizes are big as well in large projects.

That's the three major things that we found while developing this project.


Here is the solution that we used to overcome these problems.

Solution 1. Adding all stylesheets and scripts in specific pages

To resolve this problem, we declared two sections in our layout file.

  1. stylesheets
  2. scripts

so all of our web pages which has a dependency for the third-party CSS/JS libraries will look like following,


@extends('layouts.app')
@section('stylesheets')
    <link rel="stylesheet" href="https://rawgit.com/fronteed/iCheck/1.x/skins/all.css">
@endsection

@section('content')
    ....content here....
@endsection

@section('scripts')
    <script src="https://cdnjs.cloudflare.com/ajax/libs/iCheck/1.0.2/icheck.min.js"></script>
@endsection

As per the above example, the iCheck library will be only added on pages where we are actually using iCheck instead of all of my web pages.

Solution 2. Separating out page level CSS or JS

To resolve this problem, we also declared two new sections in the layout file.

  1. page_css
  2. page_js

page_css section will contain page level CSS and page_js section will contain page level javascript like initializing datatable or checkboxes etc. Also, this all page level CSS and JS are not placed directly inside the blade file. But we go one step further.

Under the resources/assets folder, we have two folders,

  1. js - contains all page level JS for different blade files
  2. styles - contains all page level CSS for different blade files

We tried to follow the same folder structure for this that we used for our blade views.

Folder Structure

If you have multiple files then you can try to use names like index.js, edit.js, etc, just the same as your blade view names.

And in your blade view files, you can include them as a script or stylesheet. For e.g.


@section('page_js')
    <script src="{{ mix('assets/js/task/task.js') }}"></script>
@endsection

Note: Use of mix is explained in the next section. so you can just ignore that as of now. But the basic idea is, include them as a script or stylesheet with sections, instead of directly putting them in blade files.

Solution 3. Using laravel-mix

Laravel mix is a great tool for asset compilation. All of the page level JS/CSS files and other common JS/CSS should be compiled by laravel mix and should be copied to the public folder with versioning for cache busting. And then it will be included via mix helper in our blade views. (As explained in the above solution at the bottom of the section).

For e.g. our webpack.mix.js looks like the following, 


/* CSS */
mix.sass('resources/assets/style/sass/laravel/app.scss', 'public/assets/style/css/app.css')
   .sass('resources/assets/style/sass/style.scss', 'public/assets/style/css/style.css')
   .sass('resources/assets/style/sass/dashboard.scss', 'public/assets/style/css/dashboard.css')
   .version();

/* JS */
mix.js('resources/assets/js/custom.js', 'public/assets/js/custom.js')
   .js('resources/assets/js/users/user.js', 'public/assets/js/users/user.js')
   .js('resources/assets/js/task/task.js', 'public/assets/js/task/task.js')
   .version();

This will minify our code and make it secure in the production environment.

Hope this helps.