无法改善网站首次加载效果

时间:2018-01-15 15:28:28

标签: javascript performance webpack bundling-and-minification lighthouse

我正在使用HTML5,JavaScript和React创建网站。 我正在使用Google Chrome Lighthouse来检查首次加载网站的效果。

这是Lighthouse Runtime环境:

  • 用户代理:Mozilla / 5.0(Windows NT 10.0; Win64; x64)AppleWebKit / 537.36(KHTML,与Gecko一样)Chrome / 63.0.3239.132 Safari / 537.36
  • 设备仿真Nexus 5X:已启用
  • 网络限制562.5ms RTT,1.4Mbps下行,0.7Mbps上行:启用
  • CPU限制4倍减速:已启用

经过多次迭代和修复,这些是我到目前为止在灯塔上的分数:

  • 表演57
  • Progressive Web App 100
  • 辅助功能100
  • 最佳实践88
  • SEO 100

最佳实践不是100,因为:

  • 我所拥有的主机没有提供HTTP / 2(如果这确实是个问题,我可能会改变)
  • 我的Google广告脚本包含document.write()(无法更改任何内容)

我的主要问题是性能指标。 我有一个超过3.3秒的白色空白屏幕,并在8.3秒后完全显示! 第一个有意义的油漆是5,750毫秒,第一个互动是6,720毫米(相同的一致性互动) 感知速度指数是4,228(得分64) 估计输入延迟为16毫秒(得分100)

这是关键链请求: Critical Chain Request

这是网络概述: Network overview

这是我到目前为止所做的/尝试过:

  • 使用react-code-splitting将启动页面中的所有组件移至异步加载
  • 优化图像以使用新的J2P,JXR和WEBP格式,并使它们的大小正确,因此浏览器无需调整大小。
  • 将App.js的内容移动到index.js中(在加载之前将并行获取index.js和vendor.js,然后是一个包含所有css文件和app.js的js文件,之后它会并行加载app.js
  • 中使用的组件
  • 将一些css导入移动到与其关联的组件。
  • 使用webpack-bundle-analyzer尝试查找公共库及其拆分方式。正如您在下面的屏幕截图中看到的那样,我的捆绑包中有很多重复的模块,我找不到如何提取效率。 (lodash,反应覆盖,......)

Bundles

这是我的webpack.config.js

const webpack = require('webpack');
const path = require('path');

const HtmlWebpackPlugin = require('html-webpack-plugin');
const ChunkManifestPlugin = require('chunk-manifest-webpack-plugin');
const WebpackChunkHash = require('webpack-chunk-hash');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
//var SWPrecacheWebpackPlugin = require('sw-precache-webpack-plugin');
const OfflinePlugin = require('offline-plugin');

// To handle the regeneratorRuntime exception
require('babel-polyfill');

require('file-loader');
require('css-loader');
require('style-loader');
require('html-webpack-template');

/* Shared Dev & Production */

const config = {
  context: path.resolve(__dirname, 'src'),

  entry: {
    index: [
        // To handle the regeneratorRuntime exception
        'babel-polyfill',
        './index.js'
    ],
    vendor: ['offline-plugin/runtime', 'react', 'react-dom', 'react-router', 'react-redux', 'history', 'react-router-dom', 'redux', 'react-router-redux', 'redux-form', 'lodash'],
  },

  module: {
    rules: [
      {
        test: /\.js$/,
        use: 'babel-loader',
        exclude: /node_modules/,
      },
      {
        test: /\.(ico|jpg|png|gif|eot|otf|jp2|jxr|webp|svg|ttf|woff|woff2)(\?.*)?$/,
        exclude: /\/favicon.ico$/,
        use: [
          {
            loader: 'file-loader',
            query: {
              name: '[path][name][hash].[ext]',
              publicPath: '/'
            }
          }
        ]
      },
      {
        test: /\.css$/,
        include: path.join(__dirname, 'src/style'),
        use: [
          'style-loader',
          {
            loader: 'css-loader',
            options: {
              minimize: true
            }
          }
        ]
      },
      {
        test: /\.(ico)(\?.*)?$/,
        exclude: /node_modules/,
        use: {
          loader: 'file-loader',
          options: { name: '[name].[ext]' },
        },
      },
      {
        test: /\.xml/,
        use: {
          loader: 'file-loader',
          options: { name: '[name].[ext]' },
        },
      },
    ],
  },

  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].bundle.js',
    publicPath: '/',
  },

  resolve: {
    extensions: ['.js'],
    modules: [path.resolve(__dirname, 'src'), 'node_modules'],
  },

  plugins: [
    // New moment.js optimization
    new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /en/),

    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      minChunks: 2
    }),

    new webpack.optimize.ModuleConcatenationPlugin(),

    new HtmlWebpackPlugin({
      appMountId: 'app-root',
      inlineManifestWebpackName: 'webpackManifest',
      template: 'templateIndex.html',
      title: 'Our Site',
    }),

    new OfflinePlugin({
      AppCache: false,
      ServiceWorker: { events: true },
    }),

    new BundleAnalyzerPlugin({analyzerMode: 'static'}),
  ],

  devServer: {
    historyApiFallback: true,
  },
};

//if (process.env.NODE_ENV === 'production') {
config.output.filename = '[name].[chunkhash].js';
config.plugins = [
  ...config.plugins,
  new webpack.HashedModuleIdsPlugin(),
  new WebpackChunkHash(),
  /*new ChunkManifestPlugin({
    filename: 'chunk-manifest.json',
    manifestVariable: 'webpackManifest',
    inlineManifest: true,
  }),*/
];
//}

module.exports = config;

我的.babelrc

{
  "presets": [
    [
      "env",
      { "modules": false }
    ],
    "react",
    "stage-0",
    "stage-2"
  ],
  "plugins": [ "syntax-dynamic-import", "transform-react-jsx", "transform-decorators-legacy" ]
}

我的index.js

import React from 'react';
import { render } from 'react-dom';
import { BrowserRouter } from "react-router-dom";
import {Redirect, Route, Switch, withRouter} from 'react-router';
import { Provider } from 'react-redux';
import Async from 'react-code-splitting';

const TopBar = () => (<Async load={import('./containers/TopBar/TopBarAsync')} />);
const NavBar = () => (<Async load={import('./containers/NavBar/NavBarAsync')} />);
const BottomBar = () => (<Async load={import('./containers/BottomBar/BottomBarAsync')} />);
const UserHelpers = (props) => <Async load={import('./containers/UserHelpers')} componentProps={props} />
const Main = () => (<Async load={import('./containers/Main')} />);
const Blog = () => (<Async load={import('./containers/Blog')} />);
const PublicPage = () => (<Async load={import('./containers/PublicPage')} />);

import configureStore from './store/store';
const store = configureStore();

import './styles/font-awesome.min.css';

import './styles/app.css';
import './styles/TeamBrowser.css';

let googleTracking = null;
if(process.env.NODE_ENV==='production') {
  // https://web-design-weekly.com/2016/07/08/adding-google-analytics-react-application/
  ReactGA.initialize([my key here]);
  googleTracking = function fireTracking() {
    let page=window.location.pathname+window.location.search;
    ReactGA.set({ page: page });
    ReactGA.pageview(page);
  }

  const runtime=require('offline-plugin/runtime');
  runtime.install({
    onUpdateReady() {
      runtime.applyUpdate();
    },
    onUpdated() {
      window.location.reload();
    },
  });
}

render((
  <Provider
    store={store}>
    <BrowserRouter
      onUpdate={googleTracking}>
      <div className="body">
        <header>
          <TopBar/>
          <NavBar />
        </header>
        <main>
          <Switch>
            <Route path="/" exact component={Main} />
            <Route path="/main" component={Main} />
            <Route path="/Feed" component={Blog} />
            <Route path="/Blog" component={Blog} />
            <Route path="/:id" component={PublicPage} />
           <Redirect to="/" />
          </Switch>
        </main>
        <footer
          className="footer">
          <BottomBar />
        </footer>
        <UserHelpers />
      </div>
    </BrowserRouter>
  </Provider>),
  document.getElementById('app'));

目前我对如何提高加载速度以获得更好的灯塔得分没有想法。 任何人都可以发现任何我不知道的事情吗?

对我来说,看起来chunk-manifest-webpack-plugin没有正常工作,因为它没有提取所有常用模块。 第二,索引。[hash] .js bundle包含它不应该的文件(例如:utils.js,'actions'文件夹下的文件,......这些是我自己的文件,但我的索引中没有引用它们.js为什么要把它们放在那里?

0 个答案:

没有答案