Let's face it - there are some problems with React & Webpack.
When I create a Webpack bundle - All the files (js and css) are merged. (remember files Name Must Start with Capital letter- js , css,..)
It means that if I have some styles with the
same name, the style will be applied on all the elements.
Ex:
In A component - there is an element like this:
<Button className="mybutton" label="close" />
with style like this:
.mybutton {color:red}
In B component - there is element with the same class name
<Button
className="mybutton" label="open" />
So because I used the same style css class name
- the Webpack bundle merged the css files of all the components, its means that
we got red color to all components that use the same name. In the example
component B got red color for the button.
I call it a bug (not a feature 😀)
In my project I created an app.js. In this file I import all the components. There, I
noticed that as I mentioned earlier, one component get styled by another
component.
As I remember in Angular, it gives all class names a new name with GUID. It
means that in angular one component style does not affect another component.
Before:
we write this code in app.js to import our components
import
MyComponent from './MyComponent';
The time and memory:
After:
Now my suggested solution:
const
MyComponent = React.lazy(() => import('./MyComponent'));
It's means that ContactUs component now no
longer has a style from ModSlider component, because we used React.Lazy.
To complete the job you need to wrap your code
with Suspense
Now you need create your own fallback code
(loading / spinner)
The time and memory:
On this example we saved almost
6 MB and 1 sec.... amusing 😃
This will automatically load the bundle
containing the MyComponent when this component is first rendered.
React.lazy takes a function that must call a dynamic import(). This must return
a Promise which resolves to a module with a default export containing a React
component.
The lazy component should then be rendered inside a Suspense component, which
allows us to show some fallback content (such as a loading indicator) while
we’re waiting for the lazy component to load.
**import React, { Suspense } from 'react';
const MyComponent = React.lazy(() =>
import('./MyComponent'));
function MyComponent() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<OtherComponent />
</Suspense>
</div>
);
}
The fallback prop accepts any
React elements that you want to render while waiting for the component to load.
You can place the Suspense component anywhere above the lazy component. You can
even wrap multiple lazy components with a single Suspense
component.
import React, { Suspense } from 'react';
const OtherComponent = React.lazy(() => import('./OtherComponent'));
const AnotherComponent = React.lazy(() =>
import('./AnotherComponent'));
function MyComponent() {
return (
<div>
<Suspense
fallback={<div>Loading...</div>}>
<section>
<OtherComponent />
<AnotherComponent />
</section>
</Suspense>
</div>
);
}
To support Webpack Chunk Name
const News = React.lazy(() =>
import(/*webpackChunkName:"News"
*/"../components/News/News"));
to webpack.config.js:
output: {
path:
path.resolve(__dirname,
'D:/Code/React/'),
filename: 'Roi_bundle.js',
chunkFilename:'[name].[chunkhash].js'
},