How to reduce NextJs bundle size? - javascript

I've just created my NextJS app, and the first load bundle size is about 1.5Mb. This is my first time using Nextjs, and from what I understand 1.2Mb is incredibly massive. I've attached an image of the yarn build and also of my package.json.
All pages in my app query from a database, and right now the pages are rendering as static html.
I've tried all the basic stuff, such as using ES6 imports(for components rendered conditionally), but none of that is working. I believe that the issue lies in that all my pages are first fetching data from the database (if I'm wrong please correct me), however I'm not too sure how to fix that.
I know I can fetch data directly from front end using useEffect, however I don't know if that will reduce the build size.
If someone has experience with NextJs, I'd really appreciate it if they could look at my project and let me know where I'm going wrong.
Thanks!
PACKAGE.JSON
"dependencies": {
"#chakra-ui/react": "^2.3.6",
"#emotion/react": "^11.10.4",
"#emotion/styled": "^11.10.4",
"#next/bundle-analyzer": "^13.0.2",
"dotenv": "^16.0.3",
"framer-motion": "^7.6.5",
"moralis-v1": "^1.11.0",
"next": "latest",
"react": "18.1.0",
"react-dom": "18.1.0",
"react-moralis": "^1.4.2",
"react-redux": "^8.0.4",
"web3uikit": "^0.1.159"
},
"devDependencies": {
"#types/node": "17.0.35",
"#types/react": "18.0.9",
"#types/react-dom": "18.0.5",
"autoprefixer": "^10.4.7",
"file-loader": "^6.2.0",
"postcss": "^8.4.14",
"tailwindcss": "^3.1.2",
"typescript": "4.7.2",
"url-loader": "^4.1.1"
}
}
Bundle:

The problem seems to be in _app.js. This file is shared by all other files and it's 1.03MB. So something in there is going wrong. You have to post the contents of that file to find the problem

Related

Slow Vite startup

Recently I started a new project in React v18 which uses Vite v4.1.1 as a build tool.
After installing a few libraries the initial load of the app (after running npm run dev) takes several minutes even though the Vite itself starts within a few seconds. After it, the HMR works fine and every change is reflected very fast.
I noticed that some dependencies take 1-2 minutes to fetch (in the network tab).
Network tab
In this picture, some deps are loaded from the cache but if they are not, react-router, mantime or react-query can take over a minute to load each. Here the main issue seems to be the main files of React app, which I understand even less.
Can someone explain why it takes so long and how to improve startup time?
I saw that it can be related with pre bundling but on the recent project, I didn't have such poor perf.
My deps:
"#emotion/react": "^11.10.5",
"#mantine/carousel": "^5.10.3",
"#mantine/core": "^5.10.3",
"#mantine/hooks": "^5.10.3",
"#tanstack/react-query": "^4.24.4",
"axios": "^0.27.2",
"embla-carousel-react": "^7.0.9",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.8.1",
"tabler-icons-react": "^1.56.0"
And dev deps:
"#types/react": "^18.0.27",
"#types/react-dom": "^18.0.10",
"#types/styled-components": "^5.1.26",
"#typescript-eslint/eslint-plugin": "^5.34.0",
"#typescript-eslint/parser": "^5.34.0",
"#vitejs/plugin-react": "^3.0.1",
"#vitejs/plugin-react-swc": "^3.1.0",
"autoprefixer": "^10.4.13",
"eslint": "^8.22.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-airbnb-typescript": "^17.0.0",
"eslint-config-prettier": "^8.5.0",
"eslint-config-standard-with-typescript": "^22.0.0",
"eslint-import-resolver-typescript": "^3.5.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-jsx-a11y": "^6.6.1",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-promise": "^6.0.0",
"eslint-plugin-react": "^7.30.1",
"eslint-plugin-react-hooks": "^4.6.0",
"postcss": "^8.4.21",
"prettier": "^2.7.1",
"sass": "^1.58.0",
"tailwindcss": "^3.2.6",
"typescript": "^4.7.4",
"vite": "^4.1.1",
"vite-plugin-eslint": "^1.8.1"
I've only come across the short note about dependency pre-bundling in docs but this doesn't cover my issue. Also saw an issue on GitHub that Tailwind can cause such a problem but I the problem persisted even before I installed Tailwind. For now have no idea what can cause such state of affair ¯\_(ツ)_/¯

ESLint works in one VSCode project but not another

I have the ESLint installed globally in VSCode. In one of my React projects it is working. Later, I created a React Native projects using Expo and it isn't running there.
I saw that I had the following settings in my packages.json file for my React project:
"dependencies": {
"#next/font": "13.1.1",
"eslint": "8.31.0",
"eslint-config-next": "13.1.1",
"next": "13.1.1",
"react": "18.2.0",
"react-dom": "18.2.0"
}
I copied the
"eslint": "8.31.0",
"eslint-config-next": "13.1.1",
lines into my React Native project like so:
"dependencies": {
"expo": "~47.0.12",
"expo-status-bar": "~1.4.2",
"react": "18.1.0",
"react-native": "0.70.5",
"eslint": "8.31.0",
"eslint-config-next": "13.1.1"
},
but it still doesn't work, even after closing and reopening my React Native project.
I came across ESLint not working in VS Code?
I've tried running eslint in a terminal in VSCode, but I get the following error in both my React and React Native projects.
C:\Users\myuser\source\globomantics> eslint
eslint : The term 'eslint' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included,
verify that the path is correct and try again.
At line:1 char:1
+ eslint
+ ~~~~~~
+ CategoryInfo : ObjectNotFound: (eslint:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException

Angular7 External Jquery Plugin - Unexpected Identifier

I'm having a hard time converting a jquery template to angular7. The original template has its own assets folder that contains several .js files that I need to load in order to get it to work.
When I start the application up with: ng serve I get the following error in the browser:
import $ from 'jquery';
Uncaught SyntaxError: Unexpected identifier
tsconfig.json
"types": [ "jquery" ],
angular.json, under scripts
"scripts": ["./node_modules/jquery/dist/jquery.min.js",
"./node_modules/bootstrap/dist/js/bootstrap.js",
"./src/assets/js/SEVERAL_JS_FILES.js"]
package.json
"dependencies": {
"#angular/animations": "^5.2.0",
"#angular/common": "^5.2.0",
"#angular/compiler": "^5.2.0",
"#angular/core": "^5.2.0",
"#angular/forms": "^5.2.0",
"#angular/http": "^5.2.0",
"#angular/platform-browser": "^5.2.0",
"#angular/platform-browser-dynamic": "^5.2.0",
"#angular/router": "^5.2.0",
"bootstrap": "^4.1.3",
"core-js": "^2.4.1",
"rxjs": "^5.5.6",
"tslib": "^1.9.0",
"zone.js": "^0.8.19",
"popper.js": "^1.14.4",
"jquery": "^3.3.1",
},
Could someone help me to understand this better? I was thinking that I might use Babel or a separate package to handle this compilation.
Thanks.
I've managed to find a solution. It's quite simple but as Adrian commented earlier it's not advised. Thus said, I'm going to use Angular Ready plugins but just in case, here's the answer.
1 - Install Jquery.
npm install jquery — save
2 - Load in your angular.json or angular-cli.json under scripts.
"scripts": [ "../node_modules/jquery/dist/jquery.min.js" ]
3 - Download the Jquery plugin that you want via npm.
4 - Load the Jquery plugin min.js in your angular.json or angular-cli.json
5 - Consume your script in an external js file, not inside your typescript.

Issue after react native expo eject: No visible #interface for 'RCTAsyncLocalStorage' declares the selector 'initWithStorageDirectory:'

I just ejected from expo and everything went well but I'm now getting the following error when trying to run my ios app in Xcode :
No visible #interface for 'RCTAsyncLocalStorage' declares the selector
'initWithStorageDirectory:'
Here is part of my package.json
"dependencies": {
"axios": "^0.17.1",
"expo": "^23.0.6",
"lodash": "^4.17.4",
"moment": "^2.20.1",
"react": "16.0.0",
"react-native": "0.50.3",
"react-native-cloudinary": "^1.0.1",
"react-native-communications": "^2.2.1",
"react-native-elements": "^0.18.5",
"react-native-fetch-blob": "^0.10.8",
"react-native-gifted-chat": "^0.3.0",
"react-native-image-picker": "^0.26.7",
"react-native-image-to-base64": "^0.1.0",
"react-native-modal-datetime-picker": "^4.13.0",
"react-native-router-flux": "^4.0.0-beta.24",
"react-navigation": "^1.0.0-beta.22",
"redux-thunk": "^2.2.0"
}
I actually managed to fix it, this is how:
I updated my "react-native" dependency to the latest one available:
"https://github.com/expo/react-native/archive/sdk-23.0.0.tar.gz"
I removed all dependency that I had installed by mistake in my previous expo app that actually required react-native link using the npm uninstall --save command:
react-native-image-to-base64, react-native-cloudinary
Then I also had to remove them from the General > Linked Frameworks and Libraries
Now it works! I'm having issues with the Facebook Login now but at least it doesn't crash my app.
Good luck to you.
I feel really dumb for not realizing it sooner, but I had this issue when I forgot to run yarn after switching branches with a different Expo version.
Hope that saves someone else some debugging.

How to ditch Babel from Vue build chain?

I'm developing a Vue app solely for Chrome, which leads me to believe (please correct me if wrong) that I can write native ES6 and don't need to transpile.
The Vue CLI generates a package.json like this:
"devDependencies": {
"babel-core": "^6.0.0",
"babel-preset-es2015": "^6.0.0",
"babelify": "^7.2.0",
"browserify": "^13.0.1",
"browserify-hmr": "^0.3.1",
"cross-env": "^1.0.6",
"envify": "^3.4.1",
"http-server": "^0.9.0",
"npm-run-all": "^2.1.2",
"uglify-js": "^2.5.0",
"vueify": "^9.1.0",
"watchify": "^3.4.0"
},
"browserify": {
"transform": [
"vueify",
"babelify"
]
}
But if I remove the 4 references to Babel, I get compile errors on my very first file. So really I just have two questions:
1) Am I correct in thinking that I can ditch Babel?
2) How do I do it?
I don't think browserify can handle ES6 imports without Babel. Usually, you could just get away with using something like gulp to uglify and minify without transpiling, because browserify is intended to allow require to be used in the browser, but if the browser supports import then you don't really need it. Unfortunately, this means that you won't be able to use vueify, so you lose the ability to use single file components, so I guess it's down to whether you think that trade-off is acceptable.
You may be interested in this discussion on GitHub: https://github.com/substack/node-browserify/issues/1186

Categories

Resources