Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SWC emotion transform plugin #34687

Merged
merged 7 commits into from Mar 15, 2022
Merged

SWC emotion transform plugin #34687

merged 7 commits into from Mar 15, 2022

Conversation

Brooooooklyn
Copy link
Contributor

@Brooooooklyn Brooooooklyn commented Feb 22, 2022

CleanShot.2022-03-09.at.15.04.34.mp4

Close #30804

@ijjk

This comment has been minimized.

@ijjk

This comment has been minimized.

@ijjk

This comment has been minimized.

@ijjk ijjk added the examples Issue/PR related to examples label Mar 2, 2022
@ijjk

This comment has been minimized.

@ijjk

This comment has been minimized.

@Brooooooklyn Brooooooklyn marked this pull request as ready for review March 8, 2022 17:22
@ijjk

This comment has been minimized.

Copy link
Member

@padmaia padmaia left a comment

Choose a reason for hiding this comment

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

Could you add telemetry tracking of this feature? I'll work on adding better documentation, but these two PRs should help:

#30297
https://github.com/vercel/next-telemetry/pull/55

@ijjk
Copy link
Member

ijjk commented Mar 14, 2022

Stats from current PR

Default Build (Decrease detected ✓)
General Overall increase ⚠️
vercel/next.js canary vercel/next.js swc-emotion-plugin Change
buildDuration 18.2s 18.7s ⚠️ +496ms
buildDurationCached 7.3s 7.4s ⚠️ +69ms
nodeModulesSize 456 MB 456 MB ⚠️ +3.82 kB
Page Load Tests Overall decrease ⚠️
vercel/next.js canary vercel/next.js swc-emotion-plugin Change
/ failed reqs 0 0
/ total time (seconds) 3.612 3.743 ⚠️ +0.13
/ avg req/sec 692.05 667.85 ⚠️ -24.2
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.566 1.637 ⚠️ +0.07
/error-in-render avg req/sec 1596.65 1527.53 ⚠️ -69.12
Client Bundles (main, webpack)
vercel/next.js canary vercel/next.js swc-emotion-plugin Change
925.HASH.js gzip 179 B 179 B
framework-HASH.js gzip 42 kB 42 kB
main-HASH.js gzip 27.9 kB 27.9 kB
webpack-HASH.js gzip 1.44 kB 1.44 kB
Overall change 71.6 kB 71.6 kB
Legacy Client Bundles (polyfills)
vercel/next.js canary vercel/next.js swc-emotion-plugin Change
polyfills-HASH.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary vercel/next.js swc-emotion-plugin Change
_app-HASH.js gzip 1.36 kB 1.36 kB
_error-HASH.js gzip 192 B 192 B
amp-HASH.js gzip 309 B 309 B
css-HASH.js gzip 327 B 327 B
dynamic-HASH.js gzip 2.57 kB 2.57 kB
head-HASH.js gzip 351 B 351 B
hooks-HASH.js gzip 920 B 920 B
image-HASH.js gzip 5.09 kB 5.09 kB
index-HASH.js gzip 263 B 263 B
link-HASH.js gzip 2.26 kB 2.26 kB
routerDirect..HASH.js gzip 320 B 320 B
script-HASH.js gzip 387 B 387 B
withRouter-HASH.js gzip 319 B 319 B
85e02e95b279..7e3.css gzip 107 B 107 B
Overall change 14.8 kB 14.8 kB
Client Build Manifests
vercel/next.js canary vercel/next.js swc-emotion-plugin Change
_buildManifest.js gzip 460 B 460 B
Overall change 460 B 460 B
Rendered Page Sizes
vercel/next.js canary vercel/next.js swc-emotion-plugin Change
index.html gzip 531 B 531 B
link.html gzip 545 B 545 B
withRouter.html gzip 526 B 526 B
Overall change 1.6 kB 1.6 kB

Default Build with SWC (Decrease detected ✓)
General Overall increase ⚠️
vercel/next.js canary vercel/next.js swc-emotion-plugin Change
buildDuration 21.9s 22.9s ⚠️ +963ms
buildDurationCached 7.7s 7.3s -389ms
nodeModulesSize 456 MB 456 MB ⚠️ +3.82 kB
Page Load Tests Overall decrease ⚠️
vercel/next.js canary vercel/next.js swc-emotion-plugin Change
/ failed reqs 0 0
/ total time (seconds) 3.707 3.664 -0.04
/ avg req/sec 674.45 682.37 +7.92
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.531 1.668 ⚠️ +0.14
/error-in-render avg req/sec 1633.1 1499.04 ⚠️ -134.06
Client Bundles (main, webpack)
vercel/next.js canary vercel/next.js swc-emotion-plugin Change
925.HASH.js gzip 178 B 178 B
framework-HASH.js gzip 42.3 kB 42.3 kB
main-HASH.js gzip 28.2 kB 28.2 kB
webpack-HASH.js gzip 1.45 kB 1.45 kB
Overall change 72.1 kB 72.1 kB
Legacy Client Bundles (polyfills)
vercel/next.js canary vercel/next.js swc-emotion-plugin Change
polyfills-HASH.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary vercel/next.js swc-emotion-plugin Change
_app-HASH.js gzip 1.35 kB 1.35 kB
_error-HASH.js gzip 179 B 179 B
amp-HASH.js gzip 313 B 313 B
css-HASH.js gzip 324 B 324 B
dynamic-HASH.js gzip 2.56 kB 2.56 kB
head-HASH.js gzip 351 B 351 B
hooks-HASH.js gzip 921 B 921 B
image-HASH.js gzip 5.23 kB 5.23 kB
index-HASH.js gzip 261 B 261 B
link-HASH.js gzip 2.33 kB 2.33 kB
routerDirect..HASH.js gzip 322 B 322 B
script-HASH.js gzip 388 B 388 B
withRouter-HASH.js gzip 317 B 317 B
85e02e95b279..7e3.css gzip 107 B 107 B
Overall change 15 kB 15 kB
Client Build Manifests
vercel/next.js canary vercel/next.js swc-emotion-plugin Change
_buildManifest.js gzip 458 B 458 B
Overall change 458 B 458 B
Rendered Page Sizes
vercel/next.js canary vercel/next.js swc-emotion-plugin Change
index.html gzip 533 B 533 B
link.html gzip 547 B 547 B
withRouter.html gzip 527 B 527 B
Overall change 1.61 kB 1.61 kB
Commit: 5d5f254

Copy link
Member

@kdy1 kdy1 left a comment

Choose a reason for hiding this comment

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

As there was no rust code change after my latest approval, I think it's fine

Copy link
Member

@timneutkens timneutkens left a comment

Choose a reason for hiding this comment

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

Only feedback I have is that this is missing an integration test to check for the hydration issue the transform solves similar to styled-components. You can have a look at test/development/basic/styled-components for inspiration.

@Brooooooklyn
Copy link
Contributor Author

@timneutkens

Only feedback I have is that this is missing an integration test to check for the hydration issue the transform solves similar to styled-components.

I believe the SSR feature of emotion does not rely on the transform plugin. The transform plugin just affects the component as selector sourceMap and minify features which are already covered by the snapshot tests on the Rust side.

Copy link
Member

@timneutkens timneutkens left a comment

Choose a reason for hiding this comment

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

Gotcha then this should be fine 👍

@timneutkens timneutkens merged commit 2e16d02 into canary Mar 15, 2022
@timneutkens timneutkens deleted the swc-emotion-plugin branch March 15, 2022 07:51
@karlhorky
Copy link
Contributor

karlhorky commented Mar 15, 2022

Wow, this is great, thanks @Brooooooklyn (and @kdy1 @timneutkens) !! 🙌

Super looking forward to using this! I guess this will be in v12.1.1-canary.12 (and eventually also v12.1.1)?

Also, will there be a migration guide? Edit: working migration guide below 👇


Migration guide from @emotion/babel-plugin to SWC Emotion Transform:

  1. Delete babel.config.js / .babelrc (as long as you only have Emotion config in there)
  2. Uninstall @emotion/babel-plugin
  3. Add the config in your next.config.js from the docs

We have tested this and are using this in production now.

@Brooooooklyn
Copy link
Contributor Author

@karlhorky https://nextjs.org/docs/advanced-features/compiler#emotion

@karlhorky
Copy link
Contributor

karlhorky commented Mar 17, 2022

Great thanks @Brooooooklyn , I've updated the migration guide above, I guess the guide above is complete now...? I'll give it a shot.

@Brooooooklyn
Copy link
Contributor Author

I guess this is complete now...? I'll give it a shot.

Yes, you can try it with next@canary

@karlhorky
Copy link
Contributor

Ah, I mean my 3-step migration guide above is complete, which I'm not 100% sure about.

But I'll try it out, thanks!

@tills13
Copy link
Contributor

tills13 commented Mar 21, 2022

Hi, thank you so much for putting this together. I have identified something which I think should be supported but doesn't seem to be (as it's supported by the babel plugin).

When you wrap an existing component with styled, e.g. styled(SomeComponent) you cannot use it as a component selector. This functionality is (albeit briefly) described here: https://emotion.sh/docs/styled#styling-any-component

Unhandled Runtime Error
Error: Component selectors can only be used in conjunction with @emotion/babel-plugin.

Here's a minimal example page:

import styled from "@emotion/styled";

const TextWrapper = styled.span`
  color: red;
`;

const AltTextWrapper = styled(TextWrapper)`
  color: orange;
`;

const Container = styled.div`
  background: blue;

  /* fine */
  ${TextWrapper} {
    color: green;
  }

  /* problem */
  ${AltTextWrapper} {
    color: green;
  }
`;

export default function Index() {
  return (
    <Container>
      <TextWrapper>Test</TextWrapper>
      <AltTextWrapper>Test</AltTextWrapper>
    </Container>
  );
}

Note that the error is still present when wrapping a non-styled component e.g.

function SomeComponent({ className }) {
  return <div className={className}>SomeComponent</div>;
}

const WrappedSomeComponent = styled(SomeComponent)`
  color: yellow;
`;

...

const Container = styled.div`
  /* still a problem */
  ${WrappedSomeComponent} {
    color: green;
  }
`;

Since this is closed, if you'd like, I can file a separate issue to track this.

@karlhorky
Copy link
Contributor

@tills13 I think this is reported in the issue: #30804 (comment)

@tills13
Copy link
Contributor

tills13 commented Mar 21, 2022

@karlhorky yep. That's the same issue. Thanks.

@tills13
Copy link
Contributor

tills13 commented Mar 28, 2022

My build times have gotten worse since enabling this. Am I missing something? I'm running next@canary, I have

experimental: {
    emotion: true,
},

in my next.config.js, and yet

Before:

$ time npm run build

...

real    0m14.126s
user    0m30.508s
sys     0m3.625s

After:

$ time npm run build

...

real    0m22.176s
user    0m40.941s
sys     0m6.562s

System information: Windows 10 + WSL

@remarcable
Copy link

@tills13 This happened to me as well and surprised me a bit. Build times got worse when compiling Emotion using SWC.

Adding swcMinify: true to next.config.js resulted in a performance-boost and outperformed Babel+Terser.

@tills13
Copy link
Contributor

tills13 commented Mar 28, 2022

With swcMinify: true, I get performance on-par with Babel + Terser. Certainly not an expected result given the raw performance of Rust vs. JavaScript.

@kdy1
Copy link
Member

kdy1 commented Mar 29, 2022

Did you remove .babelrc?

@tills13
Copy link
Contributor

tills13 commented Mar 29, 2022

haha, yes. I was sure to remove the .babelrc. I edited it out, but the "before" had the NextJS warning about falling back to babel compilation because of the presence of a .babelrc and the "after" lacked that message.

@padmaia
Copy link
Member

padmaia commented Mar 30, 2022

@tills13 are those numbers you shared all with an empty cache? Would you mind sharing the .next/trace files for both scenarios? If there's any way you could provide the emotion styles you're defining, that would also be super helpful.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 30, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
examples Issue/PR related to examples type: next
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Port @emotion/babel-plugin to SWC
9 participants