Skip to content

perf: optimize css chunks#1375

Open
antfu wants to merge 14 commits intomainfrom
fix/css-optimization
Open

perf: optimize css chunks#1375
antfu wants to merge 14 commits intomainfrom
fix/css-optimization

Conversation

@antfu
Copy link
Collaborator

@antfu antfu commented Feb 11, 2026

Resolves #1239

This PR made the following two changes to optimize the css chunking:

  • Make the component and styles of Vue Data UI async on-demand
  • Separate the icons layer from the main UnoCSS entry and then it async
    • This would introduce a side-effect that the icons css become unblocking and might have flash-of-no-icons on first load. We could discuss if this would be worth it.

Deploy Preview: https://npmxdev-git-fix-css-optimization-npmx.vercel.app/

Before:
CleanShot 2026-02-11 at 18 18 07@2x

After:
CleanShot 2026-02-11 at 18 17 01@2x

@vercel
Copy link

vercel bot commented Feb 11, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
npmx.dev Ready Ready Preview, Comment Mar 18, 2026 0:21am
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
docs.npmx.dev Ignored Ignored Preview Mar 18, 2026 0:21am
npmx-lunaria Ignored Ignored Mar 18, 2026 0:21am

Request Review

@antfu antfu changed the title fix: try optimize css bundle perf: optimize css chunks Feb 11, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 11, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR integrates UnoCSS icon handling into the project. It adds dynamic loading of icon CSS in app/app.vue, creates a new transformer (transformerIconInlineBlock) to automatically append inline-block styling to icon classes matching the i-* pattern, and updates the UnoCSS configuration with pipeline exclusions for CSS-related files. Additionally, it removes vue-data-ui/style.css from the Nuxt configuration, disables UnoCSS autoImport in the main config while enabling it in the test environment, and updates dependency ignore lists to include UnoCSS virtual modules.

Possibly related PRs

Suggested labels

front

Suggested reviewers

  • danielroe
🚥 Pre-merge checks | ✅ 1
✅ Passed checks (1 passed)
Check name Status Explanation
Description check ✅ Passed The pull request description clearly relates to the changeset, detailing CSS optimisation efforts including async loading of Vue Data UI and UnoCSS icon layers.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/css-optimization
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Tip

You can enable review details to help with troubleshooting, context usage and more.

Enable the reviews.review_details setting to include review details such as the model used, the time taken for each step and more in the review comments.

@danielroe
Copy link
Member

this is amazing! I do think we need to move inline-block into the individual icons as otherwise there's now tiny layout shifts for every icon.

@alexdln
Copy link
Member

alexdln commented Mar 8, 2026

So, our style utilities weren't working in tests, and this PR fixed it, which is why a11y tests started crashing. For example, opacity-50 isn't working in production tests right now, and we actually have a number of elements that aren't being covered correctly by our tests. I will fix what I can with low changes here or disable some of them tomorrow

@danielroe
Copy link
Member

danielroe commented Mar 9, 2026

let's fix the styles-in-tests issue separately - probably the manual uno.css import is all that is needed.

(ie let's not split icon styles for now)

@codecov
Copy link

codecov bot commented Mar 9, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

📢 Thoughts on this report? Let us know!

@alexdln
Copy link
Member

alexdln commented Mar 9, 2026

Tests crashed with this setting. I haven't yet determined why exactly, but it changes the styles in tests

  content: {
    pipeline: {
      exclude: [/\.(css|postcss|sass|scss|less|stylus|styl)($|\?)/, /[/\\]node_modules[/\\]/],
    },
  },

I've removed it for now and think I can try exploring it in the next issue.


Also, the PR originally had a transformer for icons that hardcoded extra classes. This was done so that after changes, icons are loaded lazily and later, and their styles weights become heavier. But this doesn't suit us, since we do a lot of customization on top of icons (sizes, colors, etc.), and it wasn't stable for pseudo-classes.

Fixed it via Layers - looks like it's the only stable option. Overall, I don't see any reason why we shouldn't use it - it seems like it's already become a standard properties with almost perfect support


Also enabled styles autoimport in storybook env

presetWind4(),
presetIcons({
extraProperties: {
'display': 'inline-block',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

was there a reason we removed this?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I don’t know to be honest, but feels like it’s better without it anyway - we’ll always control it on our side and get more correct default styles (f.e. if div - display:block, if span - inline)

Copy link
Member

@alexdln alexdln Mar 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But I found why it was removed. Because you made it as a separate rule and removed it here. And then I converted it to layers (to avoid having a rule with !important sizes) and hadn't returned this rule 😬

wdyt? should we return it (it will be lazy loaded and can results in shifts if we haven't specified display on place, but it will have some default option)?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CSS Size and icons

4 participants