Giter Site home page Giter Site logo

spatie / laravel-mix-preload Goto Github PK

View Code? Open in Web Editor NEW
167.0 7.0 9.0 39 KB

Add preload and prefetch links based your Mix manifest

Home Page: https://spatie.be/open-source

License: MIT License

PHP 100.00%
laravel mix preload performance css javascript

laravel-mix-preload's Introduction

Add preload and prefetch links based your Mix manifest

Latest Version on Packagist Build Status Total Downloads

<head>
    <title>Preloading things</title>

    @preload
</head>

This package exposes a @preload Blade directive that renders preload and prefetch links based on the contents in mix-manifest.json. Declaring what should be preloaded or prefetched is simple, just make sure preload or prefetch is part of the chunk name.

If this is your mix manifest:

{
    "/js/app.js": "/js/app.js",
    "/css/app.css": "/css/app.css",
    "/css/prefetch-otherpagecss.css": "/css/prefetch-otherpagecss.css",
    "/js/preload-biglibrary.js": "/js/preload-biglibrary.js",
    "/js/vendors~preload-biglibrary.js": "/js/vendors~preload-biglibrary.js"
}

The following links will be rendered:

<link rel="prefetch" href="/css/prefetch-otherpagecss.css" as="style">
<link rel="preload" href="/js/preload-biglibrary.js" as="script">
<link rel="preload" href="/js/vendors~preload-biglibrary.js" as="script">

Not sure what this is about? Read Addy Osmani's article Preload, Prefetch And Priorities in Chrome.

Support us

We invest a lot of resources into creating best in class open source packages. You can support us by buying one of our paid products.

We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on our contact page. We publish all received postcards on our virtual postcard wall.

Installation

You can install the package via composer:

composer require spatie/laravel-mix-preload

Usage

Add a @preload directive to your applications layout file(s).

<!doctype html>
<html>
    <head>
        ...
        @preload
    </head>
    <body>
        ...
    </body>
</html>

You can determine which scripts need to be preloaded or prefetched by making sure preload or prefetch is part of their file names. You can set the file name by creating a new entry in Mix, or by using dynamic imports.

Adding a second entry

By default, Laravel sets up Mix with a single app.js entry. If you have another script outside of app.js that you want to have preloaded, make sure preload is part of the entry name.

mix
    .js('resources/js/app.js', 'public/js');
    .js('resources/js/preload-maps.js', 'public/js');

If you want to prefetch the script instead, make sure prefetch is part of the entry name.

mix
    .js('resources/js/app.js', 'public/js');
    .js('resources/js/prefetch-maps.js', 'public/js');

Using dynamic imports with custom chunk names

If you want to preload a chunk of your application scripts, make sure preload is part of the chunk name. You can use Webpack's magic webpackChunkName comment to set the module's chunk name.

import('./maps' /* webpackChunkName: "preload-maps" */).then(maps => {
    maps.init();
});

The same applies to prefetching.

import('./maps' /* webpackChunkName: "prefetch-maps" */).then(maps => {
    maps.init();
});

Testing

composer test

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security

If you've found a bug regarding security please mail [email protected] instead of using the issue tracker.

Postcardware

You're free to use this package, but if it makes it to your production environment we highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using.

Our address is: Spatie, Kruikstraat 22, 2018 Antwerp, Belgium.

We publish all received postcards on our company website.

Credits

License

The MIT License (MIT). Please see License File for more information.

laravel-mix-preload's People

Contributors

adrianmrn avatar brendt avatar bumbummen99 avatar freekmurze avatar laravel-shift avatar mikemand avatar patrickomeara avatar riasvdv avatar rubenvanassche avatar sebastiandedeyne avatar vlradstake avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

laravel-mix-preload's Issues

Add ability to specify which chunk to add

My use case for not relying on webpack's built-in preloading is to support dynamic route-based preloading. On the server, I would want to check the requested route and map that to the top-level component for that page, dynamically adding a preload link for it. This feature would reduce the number of roundtrips removing any cost associated with chunking out the landing pages.

So I would have:

const HomePage = Loadable(() => import(
    /* webpackChunkName: "preload-HomePage" */
    './HomePage'
));

Route to component json

{
   "/home": "preload-HomePage"
}

And then in my blade:

<head>
        ...
        @preload($routeToComponentMap[$path])
</head>

I know @preload already takes a parameter, so we would have to figure out a slightly different pattern. Maybe an additional directive, so missing paths can be handled gracefully as well?

Happy to take an initial pass at adding this if it is desirable to be part of this package, and you can give me some guidance on how to solve the previous paragraph. If not, do you have a suggestion for a different library that would help solve this? Thanks!

Preload all fonts in specific directory without "preload" in filename

Hello there,

I am using Tailwindcss to style my website. One part of it is the import of fonts right in app.css. Those fonts are purged if not needed and moved to public/fonts. Is it possible to use @preload to preload all these fonts, even if they do not include the preload string in the filename?

Support for Dynamic Imports?

Hi, thank you very much for this wonderful package!

Just wanted to ask if this supports Dynamic Imports? I see from the readme that it does, but wondering if anything's changed on the newer versions of Laravel / Laravel Mix, because @preload for me currently generates nothing

image

image

Right off the bat, I think the root cause is Laravel Mix doesn't add chunks to mix-manifest.json. I have a project with this webpack.config.js:

const path = require('path')

module.exports = {
  resolve: {
    alias: {
      '@': path.resolve('resources/js'),
    },
  },
  output: {
    publicPath: '/',
    chunkFilename: 'js/chunks/prefetch-[name].js?ver=[chunkhash]',
  },
}

So if I follow the readme, it should be generating prefetch links since it has prefetch in its name, but currently @preload generates nothing, and looking at the code it looks like it's because the chunks are not in mix-manifest.json. Below are the contents of my mix-manifest.json:

{
    "/js/app.js": "/js/app.js?id=c85f193bc1e82c1aabfe",
    "/css/app.css": "/css/app.css?id=efa1051801c9d36d1161"
}

Here is my webpack.mix.js, it's pretty standard:

mix.js('resources/js/app.js', 'public/js').vue()
  .postCss('resources/css/app.css', 'public/css', [
    require('postcss-import'),
    require('postcss-nested'),
    require('tailwindcss'),
    require('autoprefixer'),
  ])
  .webpackConfig(require('./webpack.config'))

if (mix.inProduction()) {
  mix.version()
}

Here are versions:

PHP: 8.0.2
Laravel: 8.28.1
Laravel Mix: 6.0.6
Laravel Mix Preload: 1.2.2

If this is because the behavior has changed for newer Laravel Mix, would you happen to know any workarounds?

How to configure location if mix-manifest.json is subdirectory within public ?

I publish all assets in a separate directory inside the public directory by using the following Laravel Mix config:

mix.setPublicPath("../public/build");
mix.setResourceRoot("/build");

Needless to say, I am getting the following error:

Facade\Ignition\Exceptions\ViewException
file_get_contents(/var/www/html/public/mix-manifest.json): failed to open stream: No such file or directory (View: /var/www/html/resources/views/app-bootstrapper.blade.php)

My public dir looks like:
public/build/mix-manifest.json
public/build/css/app.css
public/build/js/app.js
public/build/js/0.js

It would be nice to have a configurable option or a way to detect the public dir from the webpack.mix.js file.

I couldn't install this package with laravel 7.0

Composer throws this error:

Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - Conclusion: remove laravel/framework v7.3.0
    - Conclusion: don't install laravel/framework v7.3.0
    - spatie/laravel-mix-preload 1.0.0 requires illuminate/support ^6.0 -> satisfiable by illuminate/support[6.x-dev, v6.0.0, v6.0.1, v6.0.2, v6.0.3, v6.0.4, v6.1.0, v6.10.0, v6.11.0, v6.12.0, v6.13.0, v6.13.1, v6.14.0, v6.15.0, v6.15.1, v6.16.0, v6.17.0, v6.17.1, v6.18.0, v6.18.1, v6.18.2, v6.18.3, v6.2.0, v6.3.0, v6.4.1, v6.5.0, v6.5.1, v6.5.2, v6.6.0, v6.6.1, v6.6.2, v6.7.0, v6.8.0].
    - spatie/laravel-mix-preload 1.0.1 requires illuminate/support ^6.0 -> satisfiable by illuminate/support[6.x-dev, v6.0.0, v6.0.1, v6.0.2, v6.0.3, v6.0.4, v6.1.0, v6.10.0, v6.11.0, v6.12.0, v6.13.0, v6.13.1, v6.14.0, v6.15.0, v6.15.1, v6.16.0, v6.17.0, v6.17.1, v6.18.0, v6.18.1, v6.18.2, v6.18.3, v6.2.0, v6.3.0, v6.4.1, v6.5.0, v6.5.1, v6.5.2, v6.6.0, v6.6.1, v6.6.2, v6.7.0, v6.8.0].
    - don't install illuminate/support 6.x-dev|don't install laravel/framework v7.3.0
    - don't install illuminate/support v6.0.0|don't install laravel/framework v7.3.0
    - don't install illuminate/support v6.0.1|don't install laravel/framework v7.3.0
    - don't install illuminate/support v6.0.2|don't install laravel/framework v7.3.0
    - don't install illuminate/support v6.0.3|don't install laravel/framework v7.3.0
    - don't install illuminate/support v6.0.4|don't install laravel/framework v7.3.0
    - don't install illuminate/support v6.1.0|don't install laravel/framework v7.3.0
    - don't install illuminate/support v6.10.0|don't install laravel/framework v7.3.0
    - don't install illuminate/support v6.11.0|don't install laravel/framework v7.3.0
    - don't install illuminate/support v6.12.0|don't install laravel/framework v7.3.0
    - don't install illuminate/support v6.13.0|don't install laravel/framework v7.3.0
    - don't install illuminate/support v6.13.1|don't install laravel/framework v7.3.0
    - don't install illuminate/support v6.14.0|don't install laravel/framework v7.3.0
    - don't install illuminate/support v6.15.0|don't install laravel/framework v7.3.0
    - don't install illuminate/support v6.15.1|don't install laravel/framework v7.3.0
    - don't install illuminate/support v6.16.0|don't install laravel/framework v7.3.0
    - don't install illuminate/support v6.17.0|don't install laravel/framework v7.3.0
    - don't install illuminate/support v6.17.1|don't install laravel/framework v7.3.0
    - don't install illuminate/support v6.18.0|don't install laravel/framework v7.3.0
    - don't install illuminate/support v6.18.1|don't install laravel/framework v7.3.0
    - don't install illuminate/support v6.18.2|don't install laravel/framework v7.3.0
    - don't install illuminate/support v6.18.3|don't install laravel/framework v7.3.0
    - don't install illuminate/support v6.2.0|don't install laravel/framework v7.3.0
    - don't install illuminate/support v6.3.0|don't install laravel/framework v7.3.0
    - don't install illuminate/support v6.4.1|don't install laravel/framework v7.3.0
    - don't install illuminate/support v6.5.0|don't install laravel/framework v7.3.0
    - don't install illuminate/support v6.5.1|don't install laravel/framework v7.3.0
    - don't install illuminate/support v6.5.2|don't install laravel/framework v7.3.0
    - don't install illuminate/support v6.6.0|don't install laravel/framework v7.3.0
    - don't install illuminate/support v6.6.1|don't install laravel/framework v7.3.0
    - don't install illuminate/support v6.6.2|don't install laravel/framework v7.3.0
    - don't install illuminate/support v6.7.0|don't install laravel/framework v7.3.0
    - don't install illuminate/support v6.8.0|don't install laravel/framework v7.3.0
    - Installation request for laravel/framework (locked at v7.3.0, required as ^7.0) -> satisfiable by laravel/framework[v7.3.0].
    - Installation request for spatie/laravel-mix-preload ^1.0 -> satisfiable by spatie/laravel-mix-preload[1.0.0, 1.0.1].


Installation failed, reverting ./composer.json to its original content.

and this my composer.json:

{
    "name": "laravel/laravel",
    "type": "project",
    "description": "The Laravel Framework.",
    "keywords": [
        "framework",
        "laravel"
    ],
    "license": "MIT",
    "require": {
        "php": "^7.2.5",
        "fideloper/proxy": "^4.2",
        "fruitcake/laravel-cors": "^1.0",
        "guzzlehttp/guzzle": "^6.5",
        "laravel/framework": "^7.0",
        "laravel/tinker": "^2.0",
        "laravel/ui": "^2.0",
        "orangehill/iseed": "^2.6",
        "spatie/laravel-fractal": "^5.7"
    },
    "require-dev": {
        "facade/ignition": "^2.0",
        "fzaninotto/faker": "^1.9.1",
        "mockery/mockery": "^1.3.1",
        "nunomaduro/collision": "^4.1",
        "phpunit/phpunit": "^8.5"
    },
    "config": {
        "optimize-autoloader": true,
        "preferred-install": "dist",
        "sort-packages": true
    },
    "extra": {
        "laravel": {
            "dont-discover": []
        }
    },
    "autoload": {
        "psr-4": {
            "App\\": "app/"
        },
        "classmap": [
            "database/seeds",
            "database/factories"
        ]
    },
    "autoload-dev": {
        "psr-4": {
            "Tests\\": "tests/"
        }
    },
    "minimum-stability": "dev",
    "prefer-stable": true,
    "scripts": {
        "post-autoload-dump": [
            "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
            "@php artisan package:discover --ansi"
        ],
        "post-root-package-install": [
            "@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
        ],
        "post-create-project-cmd": [
            "@php artisan key:generate --ansi"
        ]
    }
}

How can I achieve the installation?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.