npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

async-css-plugin

v1.1.10

Published

Minimal webpack plugin that transforms links to css files such that they are loaded asynchronously.

Downloads

1,194

Readme

Browsers load CSS files (stylesheets) synchronously such that rendering of a page is delayed until all linked stylesheets have been downloaded. This behavior is typically desired because unstyled HTML is not something you want your users to see.

However, synchronous CSS loading can also get in the way, namely when a framework like Vue bundles your single page application such that all stylesheets are linked in index.html, but none of those styles are necessary to render the page initially. One common example is when index.html is designed to quickly show a loading indicator, then load all required assets in the background to finally transition to the main page when everything is ready. With synchronous CSS downloads the rendering of the loading indicator can be delayed to the point where e.g. a mobile user is shown a white screen for many seconds before the indicator finally shows up.

This is where asynchronous CSS loading can lead to a manifold decrease of the time to First Paint and thus to a much better perceived responsiveness of your site.

Prerequisites

This plugin is designed for applications that are built using webpack. More specifically, your application must satisfy one of the following conditions:

  • Your application is built using webpack directly or a framework that allows for the configuration of webpack with webpack.config.js, like e.g. React.
  • Your application is built using a framework like Vue that "abstracts away" webpack.config.js but provides a different way to modify the webpack configuration.

NOTE: Unfortunately, this plugin does not seem to work with apps based on Angular, see this repo for more information. The steps still work with Angular v14, except for step 9, which can be safely skipped (with v14 css is always extracted, the extractCss setting is therefore no longer supported).

Getting Started

Installation

npm install async-css-plugin --save-dev

Configuration

AsyncCssPlugin configuration depends on how your project is set up, please see Prerequisites for more information.

webpack.config.js for webpack v4 & v5

If your project is configurable with webpack.config.js, it most likely already contains this file. For example, if you create a new React application with create-react-app and then run npm run eject, you'll find the file in the config folder. In this case you usually only need to add 2 lines of code:

// ... existing requires ...
const AsyncCssPlugin = require("async-css-plugin"); // added for async CSS loading

module.exports = {
    // ... existing options ...
    plugins: [
        // ... existing plugins ...
        new AsyncCssPlugin({ logLevel: "info" }), // added for async CSS loading
    ],
};

If you started with webpack directly, e.g. as described here, then you've probably already created webpack.config.js yourself. In this case, you first need to get webpack to generate HTML, with html-webpack-plugin. Moreover, for CSS to be generated into separate files it is recommended to use mini-css-extract-plugin and css-loader. You can add these dependencies as follows:

npm install html-webpack-plugin mini-css-extract-plugin css-loader --save-dev

Given the configuration recommendations for these plugins with added asynchronous CSS loading your webpack.config.js should minimally look something like this:

const AsyncCssPlugin = require("async-css-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
    entry: __dirname + "/index.js",
    output: {
        path: __dirname + "/dist",
        filename: "index_bundle.js",
    },
    module: {
        rules: [
            {
                test: /\.css$/i,
                use: [MiniCssExtractPlugin.loader, "css-loader"],
            },
        ],
    },
    plugins: [
        new HtmlWebpackPlugin(),
        new MiniCssExtractPlugin(),
        new AsyncCssPlugin({ logLevel: "info" }),
    ],
};

vue.config.js for Vue v3

If your Vue v3 project does not yet contain vue.config.js, please create one in the same folder as package.json. Otherwise, please adapt accordingly:

const AsyncCssPlugin = require("async-css-plugin");

module.exports = {
    chainWebpack: config => {
        config.plugin("async-css-plugin").use(AsyncCssPlugin, [{ logLevel: "info" }]);
    },
};

By default, Vue already generates separate .css files, so there should be no need to make additional changes in vue.config.js.

vue.config.js for Vue v2

If your Vue v2 project does not yet contain vue.config.js, please create one in the same folder as package.json. Otherwise, please adapt accordingly:

const AsyncCssPlugin = require("async-css-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
    chainWebpack: config => {
        config.plugin("html-webpack-plugin").use(HtmlWebpackPlugin);
        config.plugin("async-css-plugin").use(AsyncCssPlugin, [{ logLevel: "info" }]);
    },
};

Note that for Vue v2 it seems to be necessary to add HtmlWebpackPlugin even though the plugin is already used internally. In Vue v3 however, adding this plugin leads to an error during build, so the config must be different in v2 vs. v3.

Usage

Once webpack is configured as detailed above, stylesheet links in the generated HTML will look similar to the following:

<link href=app.cfadf482.css rel=stylesheet media=print onload="this.media='all'">

For details on why and how this works, please see The Simplest Way to Load CSS Asynchronously by the filament group.

As mentioned above, async CSS loading only makes sense when the CSS being loaded does not affect the currently visible page. It is your responsibility to show a different page (e.g. a loading indicator) while this happens, check out Net Worth for an example.

Options

The AsyncCssPlugin constructor accepts an (optional) Options object.

Credits

This plugin was inspired by async-stylesheet-webpack-plugin.