首页 > 解决方案 > Lighthouse 审计中的不良反应性能?

问题描述

我正在努力通过反应提高我在灯塔中的绩效审计分数,但我似乎无法弄清楚为什么。令我好奇的是,我在开发(29)和生产(32)中的分数非常相似(我认为 webpack 在生产中应该更多地压缩文件)。我似乎无法弄清楚如何解决这个问题......

代码拆分:我的包大小约为 1.1MB,其中包含一组非常基本的库(我使用 webpack-bundle-analyser 进行了检查)。我尝试了动态代码拆分,将包大小(作为测试)减少了大约 20%,但它并没有真正反映在性能审计中……这让我相信这可能不是问题?

应用程序性能:我尝试将一个空视图渲染为索引,但性能得分仍然很差 - 但是......我的整个应用程序可能没有针对性能进行非常优化。我最近才学会了如何包含 PureComponent。我的任何容器视图模式可能还不是最佳的......但话又说回来,这些组件都没有在空视图中呈现?

会不会是 webpack 没有正确压缩文件?我使用了 create-react-app 并没有真正改变任何配置。

对于你们(和女孩)可以提供的任何帮助,我感到非常高兴。

在此处输入图像描述

标签: reactjscreate-react-applighthouse

解决方案


  1. 在 React 中使用 Lazy / Suspense 实现代码拆分。

应用程序.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);
  1. 在 webpack 中实现 Gzip;
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()
    ]
};
  1. 使用优质的无服务器托管平台,我使用 AWS Amplify,因为它很容易启动,而且价格也不贵。(他们只对底层基础设施收费,而不是很棒的工具)

https://docs.amplify.aws/start/q/integration/react


推荐阅读