This is a proof of concept on how to implement a Load more style listing with Livewire.
There are a few articles online presenting one approach that can be summarized in this way:
- Start with a query loading the first N results (first page)
- When 'Load more' is clicked, the same query is run loading N*2 results (first and second pages)
- And so on, for all remaining pages
This works well for a small number of items/pages but is obviously not very efficient as the original DB query simply grows from page to page.
The solution presented here takes a different approach:
- On the initial page load, preload all item IDs and group them into chunks (pages)
- Start with a query loading the first chunk of results (first page)
- When 'Load more' is clicked, load the next chunk of results (next page)
Because Livewire nested components are not reactive (ie. not rerendered when the parent component is updated), this ensures that only the new chunk of items is handled on subsequent clicks to 'Load more'.
The main cost of this solution is querying all IDs upfront. This is most likely not an issue with a well indexed DB table. However, it does freeze the initial set of results, on the initial page load.
The demo introduces 2 Livewire components:
PostList
(class) (view) - Performs the inital query and handles the 'Load more' functionalityPostListItems
(class) (view) - Loads and displays the items for a single page
Check out the 'paginator' branch (diff) for a variation using a regular paginated query instead of the full list of IDs.
Prerequisites:
- PHP >= 8.0
- Composer
composer i
cp .env.example .env
touch database/database.sqlite
php artisan migrate --seed
php artisan serve