Replies: 1 comment 1 reply
-
Thanks for your feedback. The adapters are already code-split on framework internals. For example: if you're using Remix, there's nothing related to Next.js imported in your bundle when you import from nuqs/packages/nuqs/tsup.config.ts Lines 19 to 26 in c96f238 The core (hooks, parsers, serializer etc, everything you import from Note that in 2.0.1 we fixed an issue where all the optionalDependencies ( I see the point about not wanting to bundle the <RootLayout>
<LayoutA>
<NuqsAdapter>
<PageA/>
</NuqsAdapter>
</LayoutA>
<LayoutB>
<NuqsAdapter>
<PageB/>
</NuqsAdapter>
</LayoutB>
</RootLayout> The suggestion of importing core features from framework-specific imports was already discarded when we supported only Next.js app & pages routers, to avoid writing components that are locked to a particular framework. The idea with v2's compatibility with other frameworks is to keep components that use nuqs universal across supported frameworks, so they can be shared freely within the React community. The adapters are here to finish the job of integrating those components to a particular framework. |
Beta Was this translation helpful? Give feedback.
-
I've tried
nuqs
v2 and noticed the introduction of theAdapter
pattern, which adds an<NuqsAdapter>
component at the root of the application. While I understand the purpose behind it, I have concerns regarding its long-term impact on bundle size and web optimization, especially for web-based applications.Problem with the Adapter Pattern
Currently, the Adapter component is bundled with every page of the app, even if the page doesn't leverage the functionality of
useQueryState
or anynuqs
library features. The overhead might be negligible, but as time passes, this pattern might cause unnecessary bloat in the bundle, particularly if the adapter's internal logic grows.Web performance is a key concern, and we want to minimize the amount of JavaScript shipped to the client, especially when certain pages don't require those features.
Proposed Solution: Framework-Specific Submodules
Instead of using a monolithic Adapter that gets bundled with every page, I propose a framework-specific submodule approach. This would involve creating different builds for different frameworks (e.g., Next.js, Remix) and only importing what’s necessary based on the target framework. This way, we keep a single codebase but split it into multiple build targets that optimize for specific platforms.
Example Setup:
You could structure the Nuqs library to export specific modules for each target environment.
Example of Build Targets:
nuqs/next
: Optimized for Next.jsnuqs/remix
: Optimized for RemixUsing a build system like Tsup, you can set up conditional builds for each framework.
tsup.config.ts
example:Example
index.ts
with Static ImportsYou could then use framework-specific imports like so:
Build and Test Dead Code Elimination
When you run the build, Tsup will inject the FRAMEWORK_TARGET as a static value in the code, and the bundler will remove the unused branch, ensuring that only the target-specific code remains in the bundle.
For example:
FRAMEWORK_TARGET=nextjs tsup
, the conditionalif (process.env.FRAMEWORK_TARGET === 'remix')
will be removed, and only the Next.js code will be retained in the final bundle.FRAMEWORK_TARGET=remix tsup
, the conditionalif (process.env.FRAMEWORK_TARGET === 'nextjs')
will be eliminated.This would ensure that only the relevant code for each framework is included in the bundle, avoiding unnecessary Adapter overhead in pages that don’t need it.
Benefits:
I believe this could provide a more scalable solution, especially as Nuqs continues to evolve.
Beta Was this translation helpful? Give feedback.
All reactions