aalaap's avatar

Large CSS and JS bundle size out of the box on Laravel 12 and no starter kit

On a fresh Laravel 12 project, I noticed that the bundled CSS was a rather large ~33kb and JS was ~35kb. I was using no Tailwind CSS classes in my "hello world" Blade view and no JavaScript either, so this was strange.

I took a few steps to bring down the CSS:

  1. Removed the default Tailwind CSS definition under the @if-@else block, where it includes the built CSS/JS if they exist or falls back to a full dump of Tailwind CSS
  2. Cleared the view cache and all the caches
  3. Manually deleted the compiled views in storage/framework/views

Only the last step actually brought down the built CSS file from ~33kb to ~10kb. That's still pretty high, so I looked around and found the issue. In app.css, this line is the first @source statement:

@source '../../vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php';

This folder contains tailwind.blade.php, which has a lot of Tailwind CSS classes used. Even if you're not using pagination anywhere, these classes get included in the bundle because they're mentioned here. Removing this line reduced the CSS bundle size down to ~4kb. That's still a lot more than what you see on Tailwind CSS Play, which is ~160 lines of uncompressed, beautified CSS, where as the file in my Laravel build is ~320 lines. Gzipped, this ~4kb is ~1.5kb, which is acceptable, but I really want to get to the bottom of this. Where are the styles for the following being picked up from? None of these are in my code anywhere.

  • static
  • container
  • hidden
  • table

And then there's the ~35kb JS bundle, which is pretty much all Axios. The Vite config includes the input entry for app.js, which means the boostrap.js file is included and that file has import axios from 'axios';. Why is this included by default in a plain, 'None' starter kit Laravel install? I don't have any forms with @csrf and definitely no AJAX requests anywhere. I can remove this, but why is it here by default?

The behaviour is the same whether APP_ENV is local or production.

Output:

$ npm run build

> build
> vite build

vite v7.1.1 building for production...
✓ 53 modules transformed.
public/build/manifest.json             0.31 kB │ gzip:  0.17 kB
public/build/assets/app-2EVGs6cX.css   4.44 kB │ gzip:  1.50 kB
public/build/assets/app-C0G0cght.js   35.48 kB │ gzip: 14.21 kB
✓ built in 236ms
0 likes
2 replies
Snapey's avatar

Your css will consist of all the classes found in all the blade views, whether you are using them or not

Your js will consist of all the scripts in package.json and all their dependencies, whether you are using them or not.

JussiMannisto's avatar

@Snapey

Your js will consist of all the scripts in package.json and all their dependencies, whether you are using them or not.

This part isn't correct. Vite eliminates dead code through tree shaking.

1 like

Please or to participate in this conversation.