Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Critical Css Laravel Package

krisawzm/critical-css

Laravel package that speeds up page rendering by extracting and inlining critical CSS, so above-the-fold content paints immediately while the full stylesheet loads asynchronously.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install it as a build-time dependency. The package is a generator, not a request-time service, so prefer:

    composer require krisawzm/critical-css --dev
    

    If you need to generate on production hosts without Composer dev dependencies, install it normally but keep generation out of the request lifecycle.

  2. Publish and inspect the config first. Run:

    php artisan vendor:publish
    

    Pick the krisawzm/critical-css provider from the list, then read the published config file. That file is the contract for URLs, output paths, viewport dimensions, and any binary/Node path. Confirm the service provider is registered in config/app.php if the package predates Laravel package discovery.

  3. Verify the runtime dependency. This package is from the Laravel 5 era and typically shells out to a Node-based critical CSS tool. Check the README and command source for whether it expects critical, phantomjs, or another binary on PATH. Run the binary manually before debugging the Laravel side:

    which critical
    critical --version
    
  4. Start with one public page. Pick a simple, unauthenticated page such as /. Generate critical CSS for a single viewport, write it to a known path, and inspect the output before wiring it into Blade. This isolates package/config problems from layout problems.

  5. Where to look first, in order:

    • README.md for the exact command name and config keys.
    • The published config file for URL lists, storage paths, and viewport settings.
    • The package's console command class to see how it invokes the underlying tool.
    • The service provider for container bindings, facades, or Blade directives.
    • php artisan list to confirm the actual command signature.
  6. First useful integration. Generate CSS for the home page after your frontend assets are built, then inline it in your main layout with a fallback to the normal stylesheet. That single-page setup is enough to prove the pipeline before scaling to every route.

Implementation Patterns

Generate during deployment, never during a normal request. The typical production pattern is:

npm run production
php artisan cache:clear
php artisan criticalcss:generate   # check the real command name

Run this after assets exist and after the application is reachable at the URL the generator will crawl. On Forge, Envoyer, or a CI runner, put it in the deploy script and fail the deploy if generation fails for critical pages.

Use a view composer or middleware to inject the CSS. Keep the layout clean:

View::composer('layouts.app', function ($view) {
    $key = md5(request()->path());
    $path = storage_path("app/critical/{$key}.css");

    $view->with(
        'criticalCss',
        file_exists($path) ? file_get_contents($path) : null
    );
});

Then in the layout:

@if (! empty($criticalCss))
    <style>{!! $criticalCss !!}</style>
    <link rel="preload" href="{{ mix('css/app.css') }}" as="style"
          onload="this.onload=null;this.rel='stylesheet'">
    <noscript><link rel="stylesheet" href="{{ mix('css/app.css') }}"></noscript>
@else
    <link rel="stylesheet" href="{{ mix('css/app.css') }}">
@endif

Key generated files by route and asset version. A common mistake is generating once and never invalidating. Include the mix-manifest.json hash or the output CSS file's modification time in the cache key:

$assetHash = md5_file(public_path('css/app.css'));
$cacheKey  = md5(request()->path() . '|' . $assetHash);

Maintain a route-to-output map. For multi-page sites, keep an explicit config or array of important URLs, viewports, and output filenames. Do not crawl the entire site on every deploy. Prioritize the landing page, high-traffic templates, and anything with a distinct layout.

Keep a fallback path for every page. If the generated file is missing, stale, empty, or too large, render the normal stylesheet link. Critical CSS should be an optimization, not a hard dependency for rendering.

Disable or stub generation locally. Requests and deploys should not block on a headless browser. Use a local flag, a cached file, or a container binding that returns empty CSS in the local environment while still letting you run the artisan command manually.

Pair it with a proper full-CSS loading strategy. Inline critical CSS, then load the full CSS asynchronously with preload/onload and a <noscript> fallback. Also preload the main font files if typography is part of the above-the-fold experience.

Version the artifacts if you cannot run generation on the server. You can generate locally or in CI, commit the CSS files to a dedicated directory, and deploy them as static assets. This is often more reliable with an old Node toolchain than trying to reproduce the environment on every web node.

Gotchas and Tips

  • This package was last released in 2017. Expect Laravel 5.x assumptions: manual provider registration, older facade conventions, and possible PHP 8 incompatibilities. Test on your actual Laravel and PHP versions before planning around it. On modern Laravel, package discovery or typed signatures may fail outright.
  • The underlying Node toolchain is the real risk. Critical CSS generators from that era often depend on PhantomJS or an old critical release. Modern Node versions may not run them. Pin Node in CI or Docker, or treat this package as a thin wrapper you may need to replace while keeping the same Blade integration.
  • The generator must reach the page over HTTP. If your app is only available via a local socket, a container hostname, or HTTPS with a self-signed certificate, the crawl can fail. Set the base URL explicitly and test from the same environment that runs the command.
  • Authentication and CSRF will block protected pages. Generate only public pages, or supply the cookies/headers the underlying tool needs. Never create a public bypass route just to satisfy the generator.
  • Asset URLs must match the crawled URL. APP_URL, asset(), CDN domains, and http versus https mismatches can produce pages with missing CSS. Inspect the generated HTML or the tool's debug output when critical CSS comes back nearly empty.
  • CSS loaded by JavaScript or from a CDN may not be captured. The crawler sees the rendered page, but async loaders, client-side style injection, and cross-origin stylesheet timing can still cause missing rules. Verify the output contains the rules you expect.
  • Watch the inline size. Above-the-fold CSS should stay small, commonly under roughly 14 KB uncompressed. If it grows beyond that, cap it and fall back to the full stylesheet rather than blocking HTML parsing.
  • Responsive rules need separate checks. A single desktop viewport can miss mobile layout rules. Generate for representative widths, or confirm the tool's configuration keeps the media queries you need.
  • Critical CSS does not solve fonts or images. Add font-display, preload key fonts, and set explicit dimensions or placeholders for hero images to avoid layout shift.
  • Debug by running the underlying command directly. Copy the command from the package source or logs, run it with verbose output, and inspect stderr and exit codes. Laravel-level errors often hide a Node crash or timeout.
  • Increase process timeouts and limit concurrency. Headless browsers are slow and memory-hungry. Generate pages sequentially during deploy rather than firing many parallel jobs.
  • Check storage permissions. The web user and deploy user may differ. Generated files must be readable by PHP-FPM, and deploy scripts must be able to overwrite them.
  • Do not expose generation as a public route. Keep it behind artisan commands, deploy hooks, or an authenticated admin action. Generating CSS from arbitrary URLs is an easy way to create a server-side request forgery or resource exhaustion issue.
  • Use the package's extension points before forking. Check whether the generator is bound in the container or whether the command is configurable. If it is not, the cleanest upgrade path is often to keep your Blade injection and caching layer and replace only the generator with a maintained tool.
  • Clear stale artifacts. When routes are removed or layouts change, old critical CSS files linger. Add a cleanup step or write into a versioned directory and swap symlinks.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource