{"resource":{"author":{"id":"h2so9H8jPMmgUKGghoNl","name":"Yomesh Gupta","username":"yomeshgupta"},"content":{"link":"https://devtools.tech/quick-guide-to-code-splitting-using-react-lazy-and-suspense/","difficulty":2,"domain":2,"type":1,"isInternal":true,"body":"It is the time of Single Page Applications. We bundle our code, send it to the client and live happily ever after. However, as soon as our app grows, our bundle will grow in size and happiness will turn into nightmares. Users with weak connections will have to wait forever for our app to get up and running. This is not a good user experience at all.\n\n## What are we going to build?\n\nSo, we discussed the problem statement above. Before going to the solution, let's see what are we going to build in this blog post.\n\n<iframe width=\"560\" height=\"315\" src=\"https://www.youtube-nocookie.com/embed/prKmtu6gjKk\" frameborder=\"0\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen></iframe>\n\nAs we can see in the video, we are going to examine an app that serves different Login Page UIs to different users depending upon their network connection type. It means that users with a strong connection will see a full heavy animated login UI else users with a weak connection will see a bare-bones login form. We are not going to send all the code at the initial load rather we lazy load the components as per different conditions.\n\nTo see the live demo click [here](https://react-conditional-rendering.netlify.com \"React Suspense Demo Link\").<br />\nTo see the code, check out this [Github Repo](https://github.com/yomeshgupta/react-conditional-rendering \"Github Repo Link\").\n\n## What is Code Splitting?\n\nComing back to the above-mentioned problem statement, it can be solved in many ways. One of them is `Code Splitting`. As the name suggests, it is a way to create smaller chunks of the code that can be lazy-loaded on demand. It can dramatically improve the user experience and performance of our app. We won't be reducing the overall code but we would be reducing the initial code sent to the client and load more as the user navigates to different parts of our application.\n\nCode Splitting is provided by various bundlers like [Webpack](https://webpack.js.org/guides/code-splitting/ \"Webpack Code Splitting link\"), [Rollup](https://rollupjs.org/guide/en/#code-splitting \"Roll up Code Splitting link\") and [Browersify](https://github.com/browserify/factor-bundle \"Browersify Code Splitting link\"). However, in this blog post, we are going to talk about code splitting provided by React out of the box. We are not going to look into Route based Code Splitting, we would be more interested in Component-based Code Splitting.\n\n### React.lazy and Suspense\n\nReact 16.6 brought many new features like React.lazy and Suspense. They together provide native support for the lazy loading of the components. Before this, there were third party libraries like [React Loadable](https://github.com/jamiebuilds/react-loadable \"React Loadable Library Link\") for a situation like this. It is important to note that React.lazy and Suspense are not yet available for server-side rendering so react-loadable might be a better option if you want SSR.\n\nReact.lazy is a function that takes another function as an argument that must call a dynamic import. It returns a promise which resolves to a module with a default export containing the React component we want to lazy load.\n\n```js\nconst LoginAdvanced = React.lazy(() => import(\"./LoginAvanced\"));\n```\n\nAs you can see above, we are passing a function that dynamically imports `LoginAdvanced`. Now, we can use this component inside Suspense.\n\n```js{3-5}\nfunction App() => {\n  return (\n    <Suspense fallback={<Loader />}>\n      <LoginAdvanced />\n    </Suspense>\n  );\n}\n```\n\nSuspense takes a fallback component which allows us to display any React element while waiting for the component to load. In our case, `Loader` will be shown while we wait for `LoginAdvanced` to finish loading.\n\nWe would have different bundles now -\n\n1. `vendor.js` - Containing all the third-party library code. Part of initial load.\n2. `bundle.js` - Containing critical code for the initial render of the app.\n3. `loginAdvanced.js` - Fetched on demand.\n\n![Different Renders](https://ik.imagekit.io/devtoolstech/quick-guide-to-code-splitting-using-react-lazy-and-suspense/bundles_XgE_CcZCz.webp?ik-sdk-version=javascript-1.4.3&updatedAt=1642918767232)\n\n## Usecase\n\nUsing the technique discussed so far, we can improve the performance of our apps and provide a better user experience. Let's see one example where we can apply this to dynamically fetch bundles and adaptively render UI.\n\nSuppose, we want some sort of mechanism where we show different UIs to different users based on triggers like their internet speed and likes. Google Chrome Labs team recently published a collection of React hooks that can be used for adaptive loading of the UI based on certain triggers. Check out the announcement [here](https://twitter.com/addyosmani/status/1194158823948177408?lang=en \"Addy Osmani React Adaptive Hooks Twitter Status Link\") and hooks [here](https://github.com/GoogleChromeLabs/react-adaptive-hooks \"Google Chrome Labs React Hooks Github Repo Link\").\n\n```js\nimport React, { Suspense, lazy } from 'react';\nimport { useNetworkStatus } from 'react-adaptive-hooks/network';\n\nconst LoginBasic = lazy(() => import(/* webpackChunkName: \"loginBasic\" */ './LoginBasic'));\nconst LoginAdvanced = lazy(() => import(/* webpackChunkName: \"loginAdvanced\" */ './LoginAdvanced'));\n\nfunction App() {\n  const { effectiveConnectionType } = useNetworkStatus();\n\n  return (\n    <Suspense fallback={<Loader />}>\n      {effectiveConnectionType === '4g' ? <LoginAdvanced /> : <LoginBase />}\n    </Suspense>\n  );\n}\n...\n```\n\nWe are importing the `useNetworkStatus` hook which will provide us with the type of user's internet connection. If it is a strong connection then we would render a full-fledged login page else a bare-bones login form. We are putting all this into Suspense and lazy loading our components which will allow us to create different bundles for different UIs and fetch them dynamically.\n\nSince we are showing a lighter version to weak connection users, it will lead to lower page load times, better performance and experience. This can be applied to any part of your app. Maybe you want different versions of the listing page, user feed or can be even applied for A/B testing. However, there are cons to this approach too. Any change or addition in functionality needs to be replicated across different versions.\n\n<iframe width=\"560\" height=\"315\" src=\"https://www.youtube-nocookie.com/embed/prKmtu6gjKk\" frameborder=\"0\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen></iframe>\n\nTo see the live demo click [here](https://react-conditional-rendering.netlify.com \"Demo Link\").<br />\n\n- Go to demo and open devtools.\n- Go to the Network tab.\n- Try using the web app with throttling the network speed and without it.\n- You will see different bundles being loaded as per demand and different UI being rendered.\n\nTo see the code, check out this [Github Repo](https://github.com/yomeshgupta/react-conditional-rendering \"Github Repo Link\").\n","languages":[],"editorConfig":{}},"stats":{"views":9181,"used":0,"likes":0},"description":"","published":true,"isActive":true,"tags":["reactjs","frontend","javascript","lazy","suspense","ui","ux","lazy load"],"slug":"quick-guide-to-code-splitting-with-reactlazy-and-suspense---rid---uI6O7GwFqk2sXtEJI5Ej","isPremium":false,"categories":[],"requires":[],"_id":"5f1ddbeccbec5f7ffc0c2fb0","title":"Quick Guide to Code Splitting with React.lazy and Suspense","resourceId":"uI6O7GwFqk2sXtEJI5Ej","createdAt":1595792364763,"modifiedAt":1643032008410},"currentUser":null,"isOwner":false,"recommendations":{"questions":[{"_id":"636cdb1620622762d08cfe50","content":{"languages":["javascript"],"difficulty":1},"tags":["javascript","frontend","coding","devtools tech","interview questions","interview preparation","mcq","programming paradigm","tooling","mdn","js paradigm","programming questions"],"slug":"what-is-the-paradigm-of-javascript-language---qid---MALYnvxIvkLPYvYuEFjj","title":"What is the paradigm of JavaScript language?","questionId":"MALYnvxIvkLPYvYuEFjj"},{"_id":"636d3c2f20622762d08d016e","content":{"languages":["javascript"],"difficulty":1},"tags":["javascript","frontend","coding","devtools tech","interview questions","interview preparation","mcq","programming paradigm","tooling","mdn","js paradigm","programming questions","switch case","comparison"],"slug":"how-the-comparison-happens-with-switch-cases-in-javascript---qid---Dq9nqwLRz1czCqtsFrm0","title":"How the comparison happens with switch cases in JavaScript?","questionId":"Dq9nqwLRz1czCqtsFrm0"},{"_id":"62dfadbc77f9961d5b7bf558","content":{"languages":["react","html"],"difficulty":1},"tags":["javascript","ui based","machine coding","coding challenge","frontend practice","css","styling","devtools tech","dictionary","frontend masters","frontend challenge","devkode","codedamn","egghead"],"slug":"build-a-dictionary-app-or-react-js-or-frontend-coding-challenge---qid---rnrC8DZ3wOanc86iJ5hK","title":"Build A Dictionary App | React.js | Frontend Coding Challenge","questionId":"rnrC8DZ3wOanc86iJ5hK"},{"_id":"5f521c836d3cda64e470c3eb","content":{"difficulty":4,"languages":"javascript"},"tags":["javascript","prototype","frontend fundamentals","prototype chain"],"slug":"what-would-be-the-output-different-ways-of-prototype-calls---qid---oRjYJXGzxi50NhQNWZ8g","title":"What would be the output? (Different ways of Prototype calls)","questionId":"oRjYJXGzxi50NhQNWZ8g"},{"_id":"66228b6d4079503047f670ed","content":{"languages":["react","html"],"difficulty":2},"tags":["javascript","frontend","ui","atlassian","ux","devtools tech","coding","frontend challenge","blog","tutorials","google","trees"],"slug":"how-to-build-a-confluence-like-sidebar-with-tree-structure-or-atlassian-frontend-interview-question-or-react-js---qid---3r7988VsESMQBt9vP1Zi","title":"How to build a Confluence-like Sidebar with Tree Structure? | Atlassian Frontend Interview Question | React.js","questionId":"3r7988VsESMQBt9vP1Zi"}],"resources":[{"_id":"655600ac3e4c0459a44b430d","content":{"difficulty":4,"domain":2,"type":1,"isInternal":false,"languages":["javascript"]},"tags":["frontend","coding","ui","ux","razorpay","interview experience","tooling","devtools tech","hasnode","blog","tutorial"],"slug":"razorpay-frontend-engineer-interview-experience---rid---1JDZUAHqg0r2uYXxVPZW","title":"Razorpay Frontend Engineer interview experience","resourceId":"1JDZUAHqg0r2uYXxVPZW"},{"_id":"61f505741238c849f9e159e5","content":{"difficulty":4,"domain":2,"type":1,"isInternal":true},"tags":["javascript","pagination","remix run","frontend","tutorial","query params","navigation","js framework"],"slug":"add-pagination-to-remix-run---rid---A9jJkhqXgojvhovKZACe","title":"Add Pagination to Remix Run","resourceId":"A9jJkhqXgojvhovKZACe"},{"_id":"69a52acc92f33c7d8a9f6107","content":{"difficulty":4,"domain":1,"type":2,"isInternal":false,"languages":[]},"tags":["javascript","ui","ux","devtools tech","tutorial","rendering","coding"],"slug":"how-react-ssr-actually-works-without-frameworks---rid---8decG2azJUycVwuG2WQE","title":"How React SSR Actually Works (Without Frameworks)","resourceId":"8decG2azJUycVwuG2WQE"},{"_id":"6731bf5cd34d7f4b8cccbdec","content":{"difficulty":4,"domain":1,"type":1,"isInternal":true,"languages":[]},"tags":["javascript","frontend","coding","ui","ux","developer tools","youtube videos"],"slug":"how-to-become-a-better-software-engineer---rid---4lmB97aZrn9z5q00FKZz","title":"How to become a better Software Engineer?","resourceId":"4lmB97aZrn9z5q00FKZz"},{"_id":"652d6380d5ab2876a4ca20df","content":{"difficulty":4,"domain":2,"type":1,"isInternal":false,"languages":["undefined"]},"tags":["javascript","frontend","ui","ux","factset","interview experience","devtools tech","blog","medium"],"slug":"factset-software-engineer-ii-interview-experience---rid---ShYACNVRYsAX43wOki4A","title":"FactSet Software Engineer-II Interview Experience","resourceId":"ShYACNVRYsAX43wOki4A"}]}}