Lazy loading routes and components
Why lazy loading
While building an application you will want to split your bundle into smaller pieces and load them only if user navigates to these pages. Especially if your application becomes large and affects performance.
Solution
Viewi offers you lazy loading for route components.
Imagine that you have LazyPostPage
that is registered under /lazy-post/{id}
route and has a lot of contents in its template:
$router->get('/lazy-post/{id}', LazyPostPage::class);
class LazyPostPage extends BaseComponent
{
 public ?PostModel $post = null;
 public string $error = '';
 public string $message = '';

 public function __construct(private HttpClient $http, public int $id)
 {
 }

 public function init()
 {
 $this->http
 ->get("/api/post/{$this->id}")
 ->then(function (?PostModel $post) {
 $this->post = $post;
 $this->message = 'Post has been read successfully';
 }, function () {
 $this->error = 'Server error';
 });
 }
}
<Layout title="Post {$post ? $post->name : ''}">
 <h1>Post {$post ? $post->name : ''}</h1>
 <!-- Many lines of code -->
</Layout>
To make this component lazy
just mark it with Viewi\Components\Attributes\LazyLoad
attribute:
<?php

namespace Components\Views\Pages;

use Viewi\Components\Attributes\LazyLoad;
use Viewi\Components\BaseComponent;

#[LazyLoad()]
class LazyPostPage extends BaseComponent
{
}
Lazy loading group
You can also provide your own name for lazy loading group to make it more custom. Plus this group name can be used for other components as well so you can combine them into one single bundle.
<?php

namespace Components\Views\Pages;

use Viewi\Components\Attributes\LazyLoad;
use Viewi\Components\BaseComponent;

#[LazyLoad("MyGroup")]
class LazyPostPage extends BaseComponent
{
}
<?php

namespace Components\Views\Pages;

use Viewi\Components\Attributes\LazyLoad;
use Viewi\Components\BaseComponent;

#[LazyLoad("MyGroup")]
class LazyDemoPage extends BaseComponent
{
}
You can group even child components if they are being used only within this group.
If group name is not provided, then the base class name of that component will be used as a name:
<?php
#[LazyLoad()]
class LazyPostPage extends BaseComponent
{
}
Will make the name as LazyPostPage
.
Bundle overview
Imagine that you have your LazyPostPage
component with lazy loading. After the build it will generate a separate bundle file and JavaScript sub project:
viewi.LazyPostPage.min.js
- contains the build of that group.
/viewi-app/js/app/LazyPostPage
- contains the autogenerated source for your lazy loading group.