alpine-lazy-load-assets

1.2.1 • Public • Published

Alpine.js - lazy load assets

This package provides directives for lazy loading JavaScript and CSS assets in Alpine.js projects.

Note: This package is specifically designed for lazy loading css/js assets but does not handle lazy loading of Alpine components. You should use Async Alpine for that. However, it is the perfect companion to use alongside Async Alpine to lazy load all the assets required by your Alpine.js components.

Features

  • Lazily load CSS and JS files on-demand.
  • Prevent redundant loading of the same asset.
  • Saves loaded assets in Alpine global state to avoid reloading them, and to check asset existence.
  • Position scripts in head, body-start or body-end.
  • Optionally dispatch window events when assets have finished loading.

Installation

CDN

Laravel Filament users, see end of page.

<script 
    src="https://unpkg.com/alpine-lazy-load-assets@latest/dist/alpine-lazy-load-assets.cdn.js" 
    defer
></script>

NPM

npm install alpine-lazy-load-assets -D

To add the x-load-css and x-load-js directives to your project, register the plugin with Alpine.js.

import Alpine from "alpinejs";
import AlpineLazyLoadAssets from "alpine-lazy-load-assets";

Alpine.plugin(AlpineLazyLoadAssets);

window.Alpine = Alpine;
window.Alpine.start();

Livewire v3

import { Livewire, Alpine } from '../../vendor/livewire/livewire/dist/livewire.esm';
import AlpineLazyLoadAssets from "alpine-lazy-load-assets";

Alpine.plugin(AlpineLazyLoadAssets);

Livewire.start();

Usage

x-load-js

  • The x-load-js directive adds a <script> tag to the head or body of your document.
  • You can also position the script before or after an existing script. You don't have to supply a full path, the script searches for a script tag that contains the given value.
//appended to <head>
<div x-load-js="['/path/to/your/js/file.js']"></div>

//prepended to <body>
<div x-load-js.body-start="['/path/to/your/js/file.js']"></div>

//appended to <body>
<div x-load-js.body-end="['/path/to/your/js/file.js']"></div>

//position before an existing script. 
<div data-js-before="app.js" x-load-js="['/path/to/your/js/file.js']"></div>

//position after an existing script. 
<div data-js-after="app.js" x-load-js="['/path/to/your/js/file.js']"></div>

x-load-css

  • The x-load-css directive adds a <link> tag to the <head> of your document.
  • You can add a css link media attribute.
  • Warning: Please note that when the media attribute is added to an element with multiple CSS files, it will be applied to all of them.
  • You can also position the link before or after an existing css link. You don't have to supply a full path, the script searches for a css link that contains the given value.
<div x-load-css="['/path/to/your/css/file.css']"></div>

//or with media attribute
<div media="print" x-load-css="['/path/to/your/css/print-file.css']"></div>

//position before an existing css link.
<div data-css-before="app.css" x-load-css="['/path/to/your/css/file.css']"></div>

//position after an existing css link.
<div data-css-after="app.css" x-load-css="['/path/to/your/css/file.css']"></div>

Multiple files

Both directives support an array of files, allowing you to load multiple assets simultaneously.

Example from a Laravel project in combination with Async Alpine:

<div
    x-load-js="[
        'https://cdn.jsdelivr.net/npm/flatpickr/dist/l10n/{{ $locale }}.js'
    ]"
    x-load-css="[
        '{{ asset('bundles/AlpineFlatPicker/AlpineFlatPicker.css') }}',
        'https://cdn.jsdelivr.net/npm/flatpickr/dist/themes/{{ $theme }}.css'
    ]"
    x-ignore
    ax-load="visible"
    ax-load-src="{{ asset('bundles/AlpineFlatPicker/AlpineFlatPicker.js') }}"
    x-data="AlpineFlatPicker(...)"
>

Window events

Define a data-dispatch attribute with an event name, to the same element as the css or js directives to dispatch a window event when the asset has finished loading. The script will append -css or -js to the event name, depending on which directive is used.

  • The event will only be dispatched once for each file path, even if the directive is used multiple times on the same page.
<div
    data-dispatch="foo-loaded"
    x-load-js="['/path/to/your/js/file.js']"
    x-load-css="['/path/to/your/css/file.css']"
></div>

//listen for the event, observe the -css or -js suffix
<div x-on:foo-loaded-css.window="alert('the CSS file was loaded')"></div>
<div x-on:foo-loaded-js.window="alert('the JS file was loaded')"></div>

Global state, check if assets are loaded

The loaded assets are saved in lazyLoadedAssets global state, allowing you to check if an asset has already been loaded.

//in any Alpine component
$store.lazyLoadedAssets.check('path/foo.js'); //returns boolean

//you can check multiple files at once
$store.lazyLoadedAssets.check(['path/foo.js', 'path/bar.css']);

Example from a Laravel blade file

<div x-on:loaded-map-css.window="console.info($store.lazyLoadedAssets.check('{{ asset('bundles/EventGuideMap/EventGuideMap.css') }}'))"></div>

Laravel Filament

Filament v3

This package is included from Filament v3.0.0-alpha102. (No need to do anything).

If you are on an earlier version or for other reasons need to add this manually ... Add the following code to any service provider register() method.

$this->app->resolving(AssetManager::class, function () {
    FilamentAsset::register([
        Js::make('alpine-lazy-load-assets', 'https://unpkg.com/alpine-lazy-load-assets@latest/dist/alpine-lazy-load-assets.cdn.js'),
    ], 'app'); //change 'app' to a unique key suitable for your project
});

Filament v2

Add the following code to any service providers boot() method.

Filament::registerScripts([
    'https://unpkg.com/alpine-lazy-load-assets@latest/dist/alpine-lazy-load-assets.cdn.js',
], true);

Contributing

Contributions are welcome! If you find a bug, have an enhancement idea, or want to contribute in any other way, please open an issue or submit a pull request.

License

This project is licensed under the MIT License.

Readme

Keywords

Package Sidebar

Install

npm i alpine-lazy-load-assets

Weekly Downloads

276

Version

1.2.1

License

Apache-2.0

Unpacked Size

31.9 kB

Total Files

6

Last publish

Collaborators

  • tanthammar