vercel / next.js

The React Framework
https://nextjs.org
MIT License
126.73k stars 26.94k forks source link

For Next.js 10.0 use Snowpack instead of Webpack as bundler #15152

Closed mysticaltech closed 4 years ago

mysticaltech commented 4 years ago

Feature request

Is your feature request related to a problem? Please describe.

I am developing a small SPA with Next.js 9.4.4 and on my optimized Macbook Pro 2012 i5 processor with 8GB, it takes a few minutes to hot reload / fast refresh.

A clear and concise description of what you want

I would love that the next major version of Next, i.e. 10.0 switches to a more modern bundler like Snowpack. In uses ESBuild underneath and the build times are just out-of-this-world fast, like millisecond range even for big projects.

Describe the solution you'd like

Replace Webpack by Snowpack. Yes I know, it's going to be painful but that is what major versions are all about, the benefits will be immense and it will make Next.js many folds stronger and better.

Describe alternatives you've considered

Vite is an alternative, but without deep analysis, it seems that Snowpack is better and is more widely used.

timneutkens commented 4 years ago

I am developing a small SPA with Next.js 9.4.4 and on my optimized Macbook Pro 2012 i5 processor with 8GB, it takes a few minutes to hot reload / fast refresh.

This sounds unexpected and unusual. It's likely changing bundlers will not solve the issue in your application. Can you share a reproduction? I also wonder if "minutes" is an exaggeration or not.

ljosberinn commented 4 years ago

Can confirm this is very most likely a setup issue. I'm occasionally developing on a Late 2011 MacBook Pro and hot reloading takes a few seconds on a medium sized project.

Timer commented 4 years ago

On macOS, a Fast Refresh should never really exceed 2-3 seconds with the p90 being under 1s. This might be slightly longer on older hardware (5+ years old).

If you have a project which reliably reproduces this taking longer than this threshold, please share it so we can fix it.

mysticaltech commented 4 years ago

@timneutkens Yes, "minutes" might be an exaggeration, but not far from it. And yes, I do have a custom setting in next.config.js that maybe could be causing this issue, @Timer brought my attention to this. Also, I am using one central React Context for my app, no idea if that could be contributing too. I wish I could share the source but it's a work related project, I'm not allowed. Going to close this issue and look more into my code.

ScriptedAlchemy commented 4 years ago

Webpack 5 build times are blisteringly fast. Rebuilds that took 10 seconds before now take a fraction of that. Even fresh builds are significantly faster with its new caching mechanisms.

mysticaltech commented 4 years ago

If that's the case, if Webpack is evolving in that direction (which would be the smart thing to do), then this issue is indeed irrelevant. Thanks for pointing that out @ScriptedAlchemy.

ScriptedAlchemy commented 4 years ago

No worries. Ive been using WP5 for a few months now and rebuild times are way Better. I believe we saw sub-second rebuilds in dev mode if memory serves

markschellhas commented 4 years ago

I think you're all missing the point, @mysticaltech has a great suggestion. Snowpack is really the future of module bundles and would indeed be, as @mysticaltech mentions, a great improvement.

And Next.js is getting famous for slow dev builds. I've been using Next.js for years and slow dev builds have consistently been an issue. Yes, setups affect builds but it's time to really get past having to reconfigure the codebase with every new Next.js release. Snowpack is a great new paradigm for 2020.

ScriptedAlchemy commented 4 years ago

Webpack 5 offers a significant amount of power and its builds are much faster. A prod build on a raspberry pi takes 20 seconds, used to take minutes

I'd argue that v5 with Module Federation is the future of app architecture and a new paradigm on its own. Which also solves slow builds at scale.

I'm not sure if snowpack has a intricate enough api. Snowpack is very appealing, but webpack has enterprise level apis to extend for anything.

mysticaltech commented 4 years ago

@markschellhas, yes true indeed, but I later realized that shifting away from Webpack completely for NextJS would be too "breaking" even for a major version release. People are doing complex setups in next.config.js, this needs to be backward compatible, or at best, migration must be easy enough.

It's a sad reality, but if Webpack 5 with module federation works, like @ScriptedAlchemy mentioned above, that would be awesome!

I am sure that sooner or later Webpack is going to inspire itself from Snowpack. The great thing about Golang is that it easily compiles down to binary formats that are easily reusable.

ScriptedAlchemy commented 4 years ago

V5 has lots of room for growth, api was designed to keep us on v5 for a longer time with now more breaking changes.

ESM is coming, if not already there (need to check the source)

Module federation lets me deploy code independent and webpack stitches it together at runtime. Behaves like a monolith, shares dependencies and all that. So instead of giant monoliths, we can break them down without losing the optimizations.

It's dynamic and at runtime. You simply use normal import statements and it'll get chunks from other bundles. Kind of like code splitting between many bundles.

It also makes stuff very modular. Easier to make a next powered header and do enterprise migrations to the platform.

I've had MF in production since February, before it was even in a webpack beta npm release.

It's also a key reason I'm advocating for v5 over another bundler. There's nothing else that has this capability. At scale it's desperately needed. If I'm able to port it to other bundlers in full, then we could have more options (maybe)

ESM doesn't support the capabilities of MF either, nor does import maps.

You could enable modern bundles experiment in next for dev, also that would cut out a bunch of Babel transpiles- in my experience, sass and Babel are the slowest loaders. Babel accounts for like 70% of compile time. So if you use modern bundles it'll ship as esm, granular chunks which are faster to rebuild compared to 200kb page or something

https://github.com/module-federation/module-federation-examples

ScriptedAlchemy commented 4 years ago

We could use this. Replace Babel loader with esbuild. Much faster. I don't think webpack is the biggest slow part. I'd love to see if this improves. I'll be trying it tomorrow. https://github.com/privatenumber/esbuild-loader

mysticaltech commented 4 years ago

Oh wow, yes that seems like something that could seriously be good. If I am not mistaken snowpack itself uses esbuild behind the scenes.

ScriptedAlchemy commented 4 years ago

Yep that's where it's speed is in part (it does pass transforms too)

What I do is configure both es and Babel loaders so my macros still work but stuff like node modules or other files that don't depend on Babel.

Then webpack cache should cover faster builds and rebuilds. Once the cache is warmed, even prod builds are pretty fast

rizrmd commented 3 years ago

I just tried using esbuild in nextjs, currently failed to build because of ReferenceError: React is not defined. Cross posted this issue on esbuild-loader as per https://github.com/privatenumber/esbuild-loader/issues/62. And yeah, the speed improvement is very noticable as you expect.

dchambers commented 3 years ago

I'd argue that v5 with Module Federation is the future of app architecture and a new paradigm on its own. Which also solves slow builds at scale.

This issue would seem to imply that Webpack's Module Federation feature becomes irrelevant given browser-native ES Module support?

paambaati commented 3 years ago

@ScriptedAlchemy Did you have success running Next.js with esbuild-loader? There’s been some partial work at https://github.com/privatenumber/esbuild-loader/issues/62, but I’d love it if you can bring your Webpack expertise here and see if esbuild-loader can be made to work.

brillout commented 3 years ago

If you want to use Vite, check out vite-plugin-ssr. (Snowpack and Vite have similar philosophies.)

It's a little SSR tool that has a similar interface than Next.js but built on top of Vite. It's tiny: only 1.3 kLOC(!) thanks to Vite's native SSR support. This means that it will soon become a rock-solid tool (there is nothing complex in its implementation, all nifty stuff is done by Vite).

Thanks to its simple design that has clear separation of concerns, thoughts like "Hm, I'm not sure how to integrate this tool with Next.js", "Hm, I'm not sure if I can achieve that with Next.js", or "I feel like Next.js is limiting me" will vanish. While you have slightly more boilerplate (only two files that define how your pages are rendered), you keep control over your stack in a simple and straighforward manner.

(Author here, if that wasn't obvious already :D.)

motevallian commented 3 years ago

Webpack 5 offers a significant amount of power and its builds are much faster. A prod build on a raspberry pi takes 20 seconds, used to take minutes

I'd argue that v5 with Module Federation is the future of app architecture and a new paradigm on its own. Which also solves slow builds at scale.

I'm not sure if snowpack has a intricate enough api. Snowpack is very appealing, but webpack has enterprise level apis to extend for anything.

I don't think you got the point with respect to SnowPack. All it says is "Bundling is optional". Talking about WebPack 5 being faster, sounds like I have a rhino which I am putting on an F1 car to go faster. Why do we keep over complicating things? Standard import modules are here in most (or better saying all live) browsers, why do I need to bundle things in dev time and try to improve the performance of the bundling when I can completely avoid the whole thing.

And not surprisingly SnowPack does not reinvent the wheel, it still makes the full power of WebPack available. It just makes it OPTIONAL for you so if you do not need it you do not use it.

markschellhas commented 3 years ago

@brillout Unashamedly plugging your software as an alternative... I love it! Thanks for the tips, will check it out 👍

brillout commented 3 years ago

@markschellhas ;-) Let me know if you have any question about vite-plugin-ssr.

amittal-quot commented 3 years ago

I just tried using esbuild in nextjs, currently failed to build because of ReferenceError: React is not defined. Cross posted this issue on esbuild-loader as per privatenumber/esbuild-loader#62. And yeah, the speed improvement is very noticable as you expect.

This issue is fixed by manually importing React in all jsx files

richardokonicha commented 3 years ago

Is there an existing guide to help me set up snowpack with nextjs, dev builds are getting considerably slower as my project grows in size, I feel no matter how fast webpack gets it would still face these issues as the project grows in size since it needs to rebuild every time a change is made. I see this becoming a problem moving forward. Can someone point me in the right direction?

ianldgs commented 3 years ago

I agree with @konichar. Builds on CI appear to have gotten a bit better, ~1 min faster, however, even with webpack 5 my dev builds aren't a lot faster than they used to be with webpack 4. Also, CPU consumption seems higher, fans activating all the time.

brillout commented 3 years ago

@konichar @ianldgs @miso-belica any reason you don't use Vite? It does lazy-transpiling (like Snowpack) wich means dev time doesn't increase as your project grows. You can use vite-plugin-ssr which gives you a Next.js-like. Also keep an eye on https://github.com/vitejs/awesome-vite#ssr which will grow.

guide to help me set up snowpack with nextjs

You cannot use Next.js with anything other than webpack, and this will not change as Vercel (parent company of Next.js) recently hired webpack's author.

redbar0n commented 3 years ago

How to use a bit of esbuild with NextJS today: For a solution today, try esbuild-loader-examples. It shows how to use esbuild with NextJS, via esbuild-loader that lets you "harness the speed of esbuild in your Webpack build by offering faster alternatives for transpilation (eg. babel-loader/ts-loader) and minification (eg. Terser)". The speedup gains you'd be able to make are typically 2x, but some even report gains close to pure esbuild setups. (This is for build and not for dev/HMR. For development mode, try various runners / watchers)

ianldgs commented 3 years ago

So, since I got a notification from this topic...

NextJS 11 was released with some new build optimization: https://nextjs.org/blog/next-11#improved-performance

It mentions:

We've created a brand new implementation of the Babel loader for webpack, optimizing loading and adding an in-memory config caching layer.

I wonder how it's related to this issue. Anyone care to explain?

meglio commented 3 years ago

Webpack 5 build times are blisteringly fast. Rebuilds that took 10 seconds before now take a fraction of that. Even fresh builds are significantly faster with its new caching mechanisms.

Why would the web developers community accept "fraction of 10 seconds" while there are non-js examples where 100k+ source code projects are compiled from scratch in <1 second? (no multi-stage compilation, no cache - just from scratch).

Don't you feel miserable for saying "fraction of 10 seconds is good" while it can be just instant.

If a statically typed non-js builder can do faster builds, why not to use it.

frencojobs commented 3 years ago

I'm pretty sure Vercel have something up their sleeve regarding the performance. I heard they hired the main developer from SWC and there are already PRs migrating/porting internals of Next.js with/into SWC. Looks like Next.js gonna get a bit rusty and I can't wait for it.

Update: They did it :tada: https://nextjs.org/blog/next-11-1#adopting-rust-based-swc

meglio commented 3 years ago

It is still super slow... Why does a new programming language from Jonathan Blow compiles 100k lines of code from sracth in under 1 second, and here we can't achieve even one order of magnitude worse result after switching to SWC. Is this the limit? Why do we accept this terrible performance and say "it's okay, we'll live with it". Hey Next.js team, let's push further!

hanayashiki commented 3 years ago

I'm pretty sure Vercel have something up their sleeve regarding the performance. I heard they hired the main developer from SWC and there are already PRs migrating/porting internals of Next.js with/into SWC. Looks like Next.js gonna get a bit rusty and I can't wait for it.

Update: They did it 🎉 https://nextjs.org/blog/next-11-1#adopting-rust-based-swc

still slow. maybe because i'm using postcss and tailwindcss (jit mode though). it seems speeding up the transformer is not a key issue for some css-heavy projects

timneutkens commented 3 years ago

To be clear SWC is not being used in 11.1 yet as mentioned in the blogpost we're working on full compatibility with existing Next.js apps including all custom transforms Next.js has, e.g. tree-shaking getStaticProps/getServerSideProps, styled-jsx, and more. These transforms have all been ported to Rust.

There will be a beta very soon where you'll be able to opt-in to using SWC holding significant performance improvements.

At the same time we've been making large optimizations to Fast Refresh with webpack that will make Fast Refresh even faster than just enabling SWC, especially for large Next.js applications. Those optimizations will benefit all apps regardless of if you enable SWC or not.

In addition to performance optimizations we've also been working on performance measurement for all Next.js applications, we're now able to see exactly where every bit of time is spent during next build and next dev, including Fast Refresh. Using these measurements we've already large improvements to webpack internals and we're still working on more improvements.

Most importantly: this is just the beginning getting all Next.js apps to use the new Rust-based tooling by upgrading to the latest version with no code changes. We're working on even bigger improvements that will come to Next.js apps in the near future as well, stay tuned!

@hanayashiki could you (and others experiencing slow rebuilds) reach out to me on https://twitter.com/timneutkens, I've been investigating some apps using the new measurements and there seems to be a correlation with Tailwind that I'd like to investigate further.

balazsorban44 commented 2 years ago

This issue has been automatically locked due to no recent activity. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.