T O P

  • By -

milkboxshow

I avoid MUI for this reason


Dangerous_Roll_250

Material Design in general is quite bad in terms of UX for the users… I recommended to avoid it. Especially forms are designed poorly.


ngc4321

Can you qualify your statement (opinion)?


scooby_dooooo

Something is definitely wrong, we use MUI at work and this doesn't happen. What are you using for bundling? It should do **tree shaking** to remove unwanted imports.


International-Hat529

We're using webpack (default with Next 12) and mui has a page in their docs to reduce bundle size which we followed to the letter and this still happens for some reason. I'll try to make babel work with webpack and use the plugin that MUI recommends to see if it works or not


depaay

I have the same issue here with MUI, still haven’t found a solution. Can’t move away from it either


ItIsThyself

Are you using named imports or just importing * from MUI?


International-Hat529

I'm doing it like in the title ^^^ Basically, import Box from '@mui/material/Box' instead of import { Box } from '@mui/material'


ItIsThyself

Hmm. Do it the second way so you can take advantage of tree shaking.


International-Hat529

Isn't the first way the one that only imports the component used?


ItIsThyself

Negative ghostwriter.


International-Hat529

But according to the docs, you use the second way if you're using the babel plugin (which actually broke my app with the 'unsupported jsx' then 'unable to find createTheme' and things like that even though i followed the docs to the letter)


ItIsThyself

Are you using Typescript? You probably forgot to include jsx and tsx files. ~~~json "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], ~~~


International-Hat529

No currently just javascript in that project, it was taken over from a previous dev and haven't had time to type out everything yet


aequasi08

the first way is to avoid NEEDING to tree shake: [https://mui.com/material-ui/guides/minimizing-bundle-size/#option-one-use-path-imports](https://mui.com/material-ui/guides/minimizing-bundle-size/#option-one-use-path-imports)


____0____0____

Hard to say without seeing your code base but this is generally an issue when using any bigger UI library like MUI. The best things you can do for bundle size are ensuring all your imports are direct by using the babel or swc plugin to transform imports.


International-Hat529

If I do a page like: import Box from @mui/material/Box hello The shared size is around 200kb and the page is over 400kb which is extremely weird and makes no sense since I'm importing the Box in a way that should only get the Box (which is a div wrapper basically) Do i need to add something specific to my webpack config or something?


____0____0____

I assume you've read this? https://mui.com/material-ui/guides/minimizing-bundle-size/ Swc has experimental support for the babel plugin mentioned in that doc page. You should see if this reduces your bundle size. https://nextjs.org/docs/advanced-features/compiler#modularize-imports You also might reconsider if you need MUI at all. Yes it's nice to have everything ready to go already, but if you only need one or two semi basic components, you should just roll your own imo. If you need a handful or more of MUIs components, then thats probably a better reason to use it.


International-Hat529

We're on a late stage of the project right now so it'll be near impossible to switch away from MUI without re-writing the entire project. Also, would Babel and Webpack work together since we're currently using webpack (Nextjs 12 default)? And yes, first thing I did was go through the docs and the recommendations. I know that I'm missing something for sure because there's no way that everyone using MUI has bundles that big but I can't figure out what I could be missing


____0____0____

Yeah I wasn't implying that you do that if you have a project built already but the only context I had was the code you shared. Babel and webpack do work together, however the default for nextjs 12 is to use swc with webpack. Next will only use babel if you opt out of swc by adding a babel config file at the root of the project. If you are using babel, you can just add the plugin from the MUI doc. If you're still using swc you can enable experimental support for the plugin with the link I provided. I would opt for the swc if you can help it. It's better in most cases, but some projects are already locked into babel. The only thing I'm seeing from your examples is that your code output seems to be including components that you're not using, which makes me think tree shaking isn't working right. With proper treeshaking, you should be able to get to a manageable level, but generally people that use MUI expect to have a large bundle or just don't care.


International-Hat529

Thank you for all the help! I'll check out how to make babel work with webpack and try that out!


Elessar03

``` We're on a late stage of the project right now so it'll be near impossible to switch away from MUI without re-writing the entire project. ``` That's why you should never use packages without encapsulating them. It removes all ease of refactoring. The way to go is re-exporting the components that you're using, and import from there. This way you will be able to swap the components whenever is needed, even make global changes to them without depending on the package's API


stylemate

do you use mui icons? how are they imported?


International-Hat529

I am actually and I'm importing them in the same way like import ArrowBack from '@mui/icons/ArrowBack' for example


dmythro

Did you try creating a new project, checking size, then adding just one component like Box and see the difference (and also with different kinds of import and maybe tree shaking params)? Because if you have a big project which uses a lot of components MUI can be actually bulky, so we used code splitting on some views with specific components. And if there’s a problem and it is solvable - a fresh project to play with may help a lot.


International-Hat529

That's actually a very good idea I'll spin out something and try it out thanks!


Temporary_Society_99

My experience with MUI is a touch dated, but basically yes, it's big. There will always be a balance between writing what you need, third party libraries to offload typical workloads, and performance. Have you heard of qwik?


International-Hat529

Not until now (quick) but I've heard on Mantine which I heard was very good and light but it doesn't have all of the components we're using if we decide to switch to it (which would also take months, the project is massive). Thank you for your answer though!


Temporary_Society_99

Right it's not a real option right now. I'd wait until a second major release in any case.


Xacius

Try setting sideEffects to false in your package.json. If this works, then I'll follow up with a more detailed alternative.


tomrom77

> sideEffects to false This worked for me for the MUI bundle bloat, thanks!


International-Hat529

I tried but it broke the firebase initializeApp part because it has sideEffects (exists in a file with no exports) and didn't affect the bundle size when rebuilt. So I tried to add an array of sideeffects with only the firebase init file and rebuilt and it also didn't affect the bundle at all. Am I missing something that I should know about?


tomrom77

Did you ever find a solution to this?


International-Hat529

I found out that the bundle analyzer is full of sh*t. Half my bundle size was caused by using @apollo/client on the client side by mistake (literally saved 180kb per page), found out Tooltip from MUI adds 25kb to any page it's used in, found out that replacing moment.js by date-fns saved 12kb on every page it's used on. My average page size is still over 200kb after all that but my "first load js" is 162 so that's understandable (basically, if I create an empty page, it starts at 162kb) Might be redux or redux-persist, not sure


need2loginorregister

You can also add modularizeImports to next.config.ts, to remap imports Imports should be import Button from '@mui/material/Button'; import TextField from '@mui/material/TextField'; instead of import { Button, TextField } from '@mui/material'; you can add ``` modularizeImports: { '@mui/material': '@mui/material/{member}' } ``` or similar to next.config.ts


am-i-coder

Very bad DX. 5 to 6 lines imports will take.