How to compile Laravel Blade views on demand
During a CI/DI pipeline one of the common build stages is to minify the HTML.
To do this in Laravel, you may run gulp html minify to the location of the compiled views (by default storage/views).
You might think that that is all it takes, right? Well, it is not that easy. The reason for it is that the compiled views are outdated in many cases, and the user will see the old views.
The best solution would be first to clear all the current views and then compile all of them with the latest changes.
The first step is quite straightforward and can be done by the command provided by Laravel itself:
1 |
php artisan view:clear |
This article explains how to achieve the second step, compiling all the views in the storage folder (or anywhere you specified) on demand.
I have created a console command for this purpose. The code follows below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
<?php namespace App\Console\Commands; use DirectoryIterator; use Illuminate\Console\Command; use Illuminate\Foundation\Application; use Illuminate\View\Compilers\CompilerInterface; class ViewCompileCommand extends Command { /** * The console command name. * * @var string */ protected $name = 'view:compile'; /** * The console command description. * * @var string */ protected $description = 'Compile and cache specified views'; /** * @var Application */ private $app; /** * @var CompilerInterface */ private $compiler; /** * @var string */ private $viewPath; /** * Create a new config clear command instance. * * @param Application $app */ public function __construct( Application $app ) { parent::__construct(); $this->app = $app; $this->compiler = $this->app->make('blade.compiler'); $this->viewPath = config('view')['paths'][0]; } /** * Execute the console command. * * @return void */ public function handle() { $this->processDirectoryOfViews($this->viewPath); $this->info('Views were compiled and cached!'); } /** * @param string $realPath */ protected function processDirectoryOfViews(string $realPath) { foreach (new DirectoryIterator($realPath) as $fileInfo) { if ($fileInfo->isDot()) { continue; } if ($this->shouldExclude($fileInfo->getRealPath())) { continue; } if ($fileInfo->isFile()) { if ($fileInfo->getExtension() !== 'php') { continue; } $this->compiler->compile($fileInfo->getRealPath()); $this->info('Compiled: ' . $fileInfo->getRealPath()); $this->info('Output: ' . $this->compiler->getCompiledPath($fileInfo->getRealPath())); } else { $this->processDirectoryOfViews($fileInfo->getRealPath()); } } } /** * @param string $realPath * @return bool */ protected function shouldExclude(string $realPath) : bool { $toBeExcludes = [ realpath($this->viewPath . '/vendor/notifications') ]; return in_array($realPath, $toBeExcludes); } } |
Name the above file ViewCompileCommand.php and store it in the folder app/Console/Commands.
After that, register the command in the kernel.php at app.Console.Kernel.php by adding it to the commands array.
It should look like:
1 2 3 4 5 6 7 8 9 |
/** * The Artisan commands provided by your application. * * @var array */ protected $commands = [ ViewCompileCommand::class, //your other commands ]; |
Now that anything is setup, you can just run the following command in the console:
1 |
php artisan view:compile |
After that, and the views will get compiled into the storage folder.
I hope this tutorial was useful to your specific use case, and if not feel free to ask me in the comments for advice.
I could not find any information online on this topic and I had to be creative and provide my own solution. This is why I am sharing it, just in case someone else needs it.
On the next tutorial I will post a solution on how to speed up Laravel drastically by caching the compiled views in Redis or some other memory store, instead of locally.
In my dating site, this technique decreased the response time from 1s to under 100ms.