Reputation: 9722
I am struggeling to increase my performance audit score in lighthouse with react and I can't seem to figure out why. What is curious to me is that my scores in development (29) and production (32) are very similar (I think webpack should compress the files a lot more in production). I can't really seem to figure out how to tackle this problem ...
Code Splitting: My bundle size is around 1.1MB containing a very basic set of libraries (I checked with webpack-bundle-analyser). I tried dynamic code splitting fore reducing the bundle size (as a test) by around 20% but it did not really reflect in the performance audit ... which leads me to believe that this may not be the problem?
App Performance: I tried rendering a an empty view as index and the performance score was still bad - however ... my entire app may not be very optimised for performance. I just recently learned how to include PureComponent. Any my container-view patterns may not be optimal yet ... but then again, none of these components are rendered within an empty view?
Could it be that webpack may not be compressing the files correctly? I used create-react-app and haven't really changed any configuration.
I am super glad for any help you guys (and girls) can give.
Upvotes: 4
Views: 4946
Reputation: 185
App.js
// packages
import React, { Component, Suspense, lazy } from 'react';
import { Route, Switch, BrowserRouter, Redirect } from 'react-router-dom';
import { connect } from 'react-redux';
// material UI components
import { MuiThemeProvider, createMuiTheme } from '@material-ui/core/styles';
// actions
import { updateUser } from './actions/sessionController';
// pages
const Sales = lazy(() => import('./pages/Sales.js'));
const Privacy = lazy(() => import('./pages/Privacy.js'));
const Terms = lazy(() => import('./pages/Terms.js'));
const Home = lazy(() => import('./pages/Home.js'));
const Login = lazy(() => import('./pages/Login.js'));
const Checkin = lazy(() => import('./pages/Checkin.js'));
const NoMatch = lazy(() => import('./pages/404.js'));
// misc
const themeData = lazy(() => import('./assets/Theme.js'));
class App extends Component {
constructor (props) {
super(props);
this.state = {
lastPath: '/',
redirect: false
}
}
componentDidMount () {
// load the know path from local storage
var lastPath = localStorage.getItem('lastPath');
// if lastPath exists navigate to last know path
if (lastPath && lastPath !== '/') {
this.setState({
lastPath: lastPath,
redirect: true
})
setTimeout(() => {
this.setState({
redirect: false
})
}, 0);
}
}
render () {
const loading = (
<div>Loading ...</div>
);
return (
<div className='App'>
<BrowserRouter>
<Suspense fallback={loading}>
<MuiThemeProvider theme={theme}>
{
this.state.redirect
?
<Redirect to={this.state.lastPath} />
:
null
}
<Switch>
<Route exact path='/' component={Sales}/>
<Route exact path='/privacy' component={Privacy}/>
<Route exact path='/terms' component={Terms}/>
<Route exact path='/home' component={Home}/>
<Route exact path='/login' component={Login}/>
<Route exact path='/checkin' component={Checkin}/>
<Route component={NoMatch}/>
</Switch>
</MuiThemeProvider>
</Suspense>
</BrowserRouter>
</div>
);
}
}
const theme = createMuiTheme(themeData);
function mapStateToProps(state) {
return {
// for when redux is added
};
}
function mapDispatchToProps(dispatch) {
return {
updateUser: user => dispatch(updateUser(user))
}
}
export default connect(mapStateToProps, mapDispatchToProps)(App);
const path = require( 'path' );
const CompressionPlugin = require('compression-webpack-plugin');
const BrotliPlugin = require('brotli-webpack-plugin');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
context: __dirname,
entry: './src/index.js',
output: {
path: path.resolve( __dirname, 'dist' ),
filename: 'main.js',
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: 'babel-loader',
},
{
test: /\.(png|jp(e*)g|svg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
name: 'images/[hash]-[name].[ext]',
}
}
]
}
]
},
plugins: [
new CompressionPlugin({
filename: '[path].gz[query]',
algorithm: 'gzip',
test: /\.(js|css|html|svg)$/,
threshold: 8192,
minRatio: 0.8
}),
new BrotliPlugin({ //brotli plugin
asset: '[path].br[query]',
test: /\.(js|css|html|svg)$/,
threshold: 10240,
minRatio: 0.8
}),
new BundleAnalyzerPlugin()
]
};
https://docs.amplify.aws/start/q/integration/react
Upvotes: 3