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.