灯塔审核的反应性能不好?

时间:2019-11-28 12:10:53

标签: reactjs create-react-app lighthouse

我正在努力提高自己在灯塔上的绩效审核分数,并且做出了反应,但我似乎不知道为什么。 让我感到好奇的是,我在开发阶段(29)和生产阶段(32)的得分非常相似(我认为webpack应该在生产阶段进一步压缩文件)。弄清楚如何解决这个问题...

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

应用程序性能:我尝试呈现一个空白视图作为索引,并且性能得分仍然很差-但是...我的整个应用程序可能未针对性能进行非常优化。我刚刚学习了如何包含PureComponent。我的容器视图模式可能还不是最优的……但是,再一次,这些组件都没有呈现在空视图中吗?

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

我很高兴你们(和女孩)能提供任何帮助。

enter image description here

2 个答案:

答案 0 :(得分:0)

您的大输入延迟是由Javascript引起的。由于阻止了CSS或JS(框架),您的第一个内容丰富的绘画。您应该异步加载JS和CSS。但是,如果在React应用程序中无法做到这一点(我不知道),我想您会被这个分数困扰。

PS。我写了一篇有关how to get a 100% Google Lighthouse score的文章。请注意,这与React应用无关,而与常规网站有关。

答案 1 :(得分:0)

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

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);
  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