Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incremental build performance issues #20

Closed
IronSean opened this issue Dec 11, 2019 · 11 comments · Fixed by #22
Closed

Incremental build performance issues #20

IronSean opened this issue Dec 11, 2019 · 11 comments · Fixed by #22

Comments

@IronSean
Copy link

I'm experiencing some incremental build performance issues. These are taken by sampling the Time output from webpack incremental builds.

RRWP+babel+ts-loader+ForkTsCheckerWebpackPlugins: 11-17 s
RRWP+babel+ts: 9-16 s
babel+ts-loader+ForkTsCheckerWebpackPlugin: 1.8-2.0s
babel+ts-loader: 1.5s-1.7s
babel: 1.4-2.1 s
ts-loader+ForkTsCheckerWebpackPlugin: 1.1-1.9 s

It looks like RRWP is adding 8-15 seconds build time to my typescript react project.

The config is as follows:
webpack.common.js

const path = require('path');
const webpack = require('webpack');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');

module.exports = {
  target: 'web',

  entry: {
    core: [
      path.resolve(__dirname, 'ts/core/polyfill.ts'),
      path.resolve(__dirname, 'ts/core/core.ts'),
    ],
    reports: [
      path.resolve(__dirname, 'ts/core/polyfill.ts'),
      path.resolve(__dirname, 'ts/core/reports.ts'),
    ],
    app: [path.resolve(__dirname, 'ts/apps/index.tsx')],
  },

  resolve: {
    extensions: ['.ts', '.tsx', '.js', '.json', '.html'],
    alias: {
      Shared: path.resolve(__dirname, 'ts/shared'),
      appA: path.resolve(__dirname, 'ts/apps/appA'),
      appB: path.resolve(__dirname, 'ts/apps/appB'),
    },
  },

  module: {
    rules: [
      // All image files will be handled here
      {
        test: /\.(png|svg|jpg|gif)$/,
        loader: 'file-loader',
      },

      // All font files will be handled here
      {
        test: /\.(woff|woff2|eot|ttf|otf)$/,
        loader: 'file-loader',
      },

      // All files with ".html" will be handled
      { test: /\.html$/, loader: 'html-loader' },

      // All output ".js" files will have any sourcemaps re-processed by "source-map-loader".
      { enforce: 'pre', test: /\.js$/, exclude: [/node_modules/], loader: 'source-map-loader' },
    ],
  },

  plugins: [
    // Clean dist folder.
    new CleanWebpackPlugin({ verbose: true }),

    // Split out library into seperate bundle and remove from app bundle.
    new webpack.HashedModuleIdsPlugin(),

    // avoid publishing when compilation failed.
    new webpack.NoEmitOnErrorsPlugin(),

    new HtmlWebpackPlugin({
      inject: false,
      title: null,
      chunks: ['common', 'app', 'core'],
      heads: ['common', 'core'],
      bodys: ['app'],
      filename: '../Views/Shared/_Layout.cshtml',
      template: './Views/Shared/_Layout_Template.cshtml',
      appMountId: 'react-app',
    }),
    new HtmlWebpackPlugin({
      inject: false,
      title: null,
      chunks: ['common', 'core'],
      heads: ['common', 'core'],
      bodys: [],
      filename: '../Views/Shared/_ExternalLayout.cshtml',
      template: './Views/Shared/_ExternalLayout_Template.cshtml',
    }),
    new HtmlWebpackPlugin({
      inject: false,
      title: null,
      chunks: ['common', 'reports'],
      heads: ['common', 'reports'],
      bodys: [],
      filename: '../Views/Shared/_ReportLayout.cshtml',
      template: './Views/Shared/_reportLayout_Template.cshtml',
    }),

    new CopyWebpackPlugin([
      'ts/core/dependencies/telerik-report-viewer/telerikReportViewerTemplate-sass.html',
    ]),

    // Moment.js is an extremely popular library that bundles large locale files
    // by default due to how Webpack interprets its code. This is a practical
    // solution that requires the user to opt into importing specific locales.
    // https://github.com/jmblog/how-to-optimize-momentjs-with-webpack
    // You can remove this if you don't use Moment.js:
    new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
    new ForkTsCheckerWebpackPlugin(),
  ],

  // Some libraries import Node modules but don't use them in the browser.
  // Tell Webpack to provide empty mocks for them so importing them works.
  node: {
    dgram: 'empty',
    fs: 'empty',
    net: 'empty',
    tls: 'empty',
    child_process: 'empty',
  },
  // Turn off performance hints during development because we don't do any
  // splitting or minification in interest of speed. These warnings become
  // cumbersome.
  performance: {
    hints: false,
  },

  // pretty terminal output
  stats: { colors: true },

  // Set up chunks
  optimization: {
    splitChunks: {
      chunks: 'all',
      cacheGroups: {
        default: false,
        vendors: false,
        commons: {
          name: 'common',
          chunks: 'initial',
          minChunks: 2,
        },
      },
    },
  },
};

and webpack.dev.js

const webpack = require('webpack');
const Merge = require('webpack-merge');
const CommonConfig = require('./webpack.common.js');
const postcssConfig = require('./postcss-config');
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');

const babelLoader = {
  loader: 'babel-loader?cacheDirectory', //require.resolve('babel-loader'),
  options: {
    presets: ['@babel/react', '@babel/typescript', ['@babel/env', { modules: false }]],
    plugins: [
      '@babel/plugin-proposal-class-properties',
      '@babel/plugin-proposal-optional-chaining',
      '@babel/plugin-proposal-nullish-coalescing-operator',
      'react-refresh/babel',
    ],
  },
};

module.exports = Merge(CommonConfig, {
  mode: 'development',
  devtool: 'cheap-module-eval-source-map',
  devServer: {
    headers: {
      'Access-Control-Allow-Origin': 'http://localhost:2354',
      'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
      'Access-Control-Allow-Headers': 'X-Requested-With, content-type, Authorization',
    },
    writeToDisk: true,
    hot: true,
  },
  output: {
    filename: '[name].js',
    path: __dirname + '/dist',
    publicPath: 'http://localhost:8080/dist/',
    pathinfo: false,
  },
  module: {
    rules: [
      {
        test: /\.(ts|tsx)$/,
        exclude: /node_modules/,
        use: [
          babelLoader,
          {
            loader: 'ts-loader',
            options: {
              transpileOnly: true,
              experimentalWatchApi: true,
            },
          },
        ],
      },

      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: [babelLoader],
      },
      {
        // All css files will be handled here
        oneOf: [
          {
            test: /^((?!\.module).)*scss$/,
            use: [
              'style-loader',
              {
                loader: 'css-loader',
                options: {
                  importLoaders: 2,
                  sourceMap: true,
                },
              },
              postcssConfig,
              {
                loader: 'sass-loader',
                options: {
                  implementation: require('node-sass'),
                  sourceMap: true,
                },
              },
            ],
          },
          {
            test: /\.module.scss$/,
            use: [
              'style-loader',
              {
                loader: 'typings-for-css-modules-loader',
                options: {
                  namedExport: true,
                  camelCase: true,
                  importLoaders: 2,
                  localIdentName: '[path][name]__[local]--[hash:base64:5]',
                  modules: true,
                  sourceMap: true,
                },
              },
              postcssConfig,
              {
                loader: 'sass-loader',
                options: {
                  implementation: require('node-sass'),
                  sourceMap: true,
                },
              },
            ],
          },

          // All files with ".less" will be handled and transpiled to css
          {
            test: /^((?!\.module).)*less$/,
            use: [
              'style-loader',
              {
                loader: 'css-loader',
                options: {
                  importLoaders: 2,
                  sourceMap: true,
                },
              },
              postcssConfig,
              {
                loader: 'less-loader',
                options: {
                  sourceMap: true,
                },
              },
            ],
          },
          {
            test: /\.module.less$/,
            use: [
              'style-loader',
              {
                loader: 'typings-for-css-modules-loader',
                options: {
                  namedExport: true,
                  camelCase: true,
                  importLoaders: 2,
                  localIdentName: '[path][name]__[local]--[hash:base64:5]',
                  modules: true,
                  sourceMap: true,
                },
              },
              postcssConfig,
              {
                loader: 'less-loader',
                options: {
                  sourceMap: true,
                },
              },
            ],
          },
          {
            test: /^((?!\.module).)*css$/,
            use: [
              'style-loader',
              {
                loader: 'css-loader',
                options: {
                  importLoaders: 1,
                  sourceMap: true,
                },
              },
              postcssConfig,
            ],
          },
          {
            test: /module.css$/,
            use: [
              'style-loader',
              {
                loader: 'typings-for-css-modules-loader',
                options: {
                  namedExport: true,
                  camelCase: true,
                  importLoaders: 2,
                  localIdentName: '[path][name]__[local]--[hash:base64:5]',
                  modules: true,
                  sourceMap: true,
                },
              },
              postcssConfig,
            ],
          },
        ],
      },
    ],
  },
  plugins: [
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: JSON.stringify('development'),
      },
      PRODUCTION: false,
    }),
    new ReactRefreshWebpackPlugin({ disableRefreshCheck: true }),
  ],
});
@gaearon
Copy link

gaearon commented Dec 12, 2019

Could adding

this.cacheable();

to the loader help? https://webpack.js.org/api/loaders/#thiscacheable

I don't understand for sure from the docs if it's the default or if calling it without argument is the default. @IronSean mind checking if putting this line here helps:

@IronSean
Copy link
Author

Incremental builds adding and removing a character from a component took 14, 13, 11.5, and 11 seconds with this.cacheable() added. Also, this is with the latest master and not 0.1.0.

@IronSean
Copy link
Author

IronSean commented Dec 12, 2019

Here is the output from the incremental build using

With RRWP

「wdm」: Compiling...
<w> [webpack.Progress] 14616ms building
<i> [webpack.Progress] 11ms finish module graph
<i> [webpack.Progress] 54ms chunk graph
<i> [webpack.Progress] 31ms advanced chunk optimization
<i> [webpack.Progress] 50ms before module ids
<i> [webpack.Progress] 13ms module id optimization
<i> [webpack.Progress] 67ms hashing
<i> [webpack.Progress] 209ms chunk assets processing
<i> [webpack.Progress] 30ms additional chunk assets processing
<i> [webpack.Progress] 633ms emitting
98% after emitting SizeLimitsPluginclean-webpack-plugin: removed dist\telerikReportViewerTemplate-sass.html
No type errors found
Version: typescript 3.7.3
Time: 1402ms
<i> [webpack.Progress] 181ms after emitting
i 「wdm」: Hash: 0b7daa8befa4f9b4d09d
Version: webpack 4.41.2
Time: 15842ms
Built at: 12/12/2019 11:48:59 AM
                                 Asset        Size   Chunks                                      Chunk Names
../Views/Shared/_ExternalLayout.cshtml    4.36 KiB           [emitted]
        ../Views/Shared/_Layout.cshtml    5.48 KiB           [emitted]
  ../Views/Shared/_ReportLayout.cshtml   695 bytes           [emitted]
  041f1357f2492b05851876a11fc8a3a0.png    3.63 KiB
  2e8648b3a07565dbffc7f0ce9d317b5a.png  1010 bytes
  2e971aaba434e77407062be68abcb816.png    3.62 KiB
  2f33973cbe60f770a187e86895cb6e88.png    4.15 KiB
  3444d9d5d1039b8b619d05efd687a6a9.png   132 bytes
  4215acb9b1d5d9de2bc0.hot-update.json    45 bytes           [emitted] [immutable] [hmr]
  4405429be6a2a9858b9d6c0440bca385.png    1.16 KiB
448c34a56d699c29117adc64c43affeb.woff2    17.6 KiB
  4889784689c1b8109f97a0eecf9265f4.gif   723 bytes
  674f50d287a8c48dc19ba404d20fe713.eot     162 KiB
  76d94c53ff582a64732e992bf3205e60.png   117 bytes
  7a4b4c6ebdb549fcbe47408f9457493e.gif   329 bytes
  7b9776076d5fceef4993b55c9383dedd.gif    1.81 KiB
  89889688147bd7575d6327160d64e760.svg     106 KiB
  89e54b5ecbc18456c945a814484ded7e.png   807 bytes
  912ec66d7572ff821749319396470bde.svg     434 KiB                                        [big]
  9cd6e041544b63fb70f4b3e898a9878d.eot    12.9 KiB
  9d4c1f083c33e23adc577b1589dfe851.png    1.09 KiB
  9f5ff9b0d8b042651089bccbbcfe56fb.jpg    4.93 MiB                                        [big]
  a57ccfcfbc09eacaa8c7d490af8faed1.png   107 bytes
  a7c2174f5c11fe4d4fe622f53adcf471.png    3.62 KiB
  aa6c079759e4cdbb3b14cd960047cc93.png   116 bytes
  ae06b0018e895cfdfec66183874d0282.gif    8.04 KiB
af7ae505a9eed503f8b8e6982036873e.woff2    75.4 KiB
app.4215acb9b1d5d9de2bc0.hot-update.js    25.9 KiB      app  [emitted] [immutable] [hmr]         app
                                app.js    15.9 MiB      app  [emitted]                    [big]  app
  b06871f281fee6b241d60582ae9369b9.ttf     162 KiB
  b958053351f480436d7550170526256f.png    3.62 KiB
  bce450800e44a407218277f2d518a635.png    2.77 KiB
  c4f238d22393a5e916764759aaaf9e0f.gif    3.61 KiB
  c4fc0214ddf2b82117aefeea28f39bab.png   117 bytes
  c575d67d0bb94b23dc90eff65993e4c3.png    1.95 KiB
  cb057877085d8ef838b8a8247477bccc.png    23.3 KiB
                             common.js    34.9 MiB   common                               [big]  common
                               core.js     7.9 MiB     core  [emitted]                    [big]  core
  d8aaa942c8c026410cd3032167facd15.png       1 KiB
 df36508b58279b852bce0bc1a503eb8d.woff    8.14 KiB
  e18bbf611f2a2e43afc071aa2f4e1512.ttf    44.3 KiB
  ee79d26d853d4de007a1abada84d6f12.png   962 bytes
  f266141392a706176dc9cf22b4740040.png    3.83 KiB
  f470863024f982806a178d720710f024.png   509 bytes
  f4769f9bdb7466be65088239c12046d1.eot    19.7 KiB
 fa2772327f55d8198301fdb8bcfc8158.woff    22.9 KiB
  fa9d99f038715abf8ace2816decde252.png   494 bytes
  fab39f2771ab597b747dd401a85acad4.png   118 bytes
  fce9a0f2784bc80eeb2f2f25f670f3da.ttf    12.7 KiB
 fee66e712a8a08eef5805a46892932ad.woff    95.7 KiB
                            reports.js    33.3 KiB  reports  [emitted]                           reports
Entrypoint core [big] = common.js core.js
Entrypoint reports [big] = common.js reports.js
Entrypoint app [big] = common.js app.js app.4215acb9b1d5d9de2bc0.hot-update.js
[3] multi (webpack)-dev-server/client?http://localhost:8080 (webpack)/hot/dev-server.js ./node_modules/@pmmmwh/react-refresh-webpack-plugin/src/runtime/ReactRefreshEntry.js ./node_modules/@pmmmwh/react-refresh-webpack-plugin/src/runtime/ErrorOverlayEntry.js ./node_modules/@pmmmwh/react-refresh-webpack-plugin/src/runtime/BabelDetectComponent.js ./ts/core/polyfill.ts ./ts/core/core.ts 100 bytes {core}
    factory:0ms dependencies:1ms = 1ms
[5] multi (webpack)-dev-server/client?http://localhost:8080 (webpack)/hot/dev-server.js ./node_modules/@pmmmwh/react-refresh-webpack-plugin/src/runtime/ReactRefreshEntry.js ./node_modules/@pmmmwh/react-refresh-webpack-plugin/src/runtime/ErrorOverlayEntry.js ./node_modules/@pmmmwh/react-refresh-webpack-plugin/src/runtime/BabelDetectComponent.js ./ts/core/polyfill.ts ./ts/core/reports.ts 100 bytes {reports}
    factory:0ms dependencies:0ms = 0ms
[6] multi (webpack)-dev-server/client?http://localhost:8080 (webpack)/hot/dev-server.js ./node_modules/@pmmmwh/react-refresh-webpack-plugin/src/runtime/ReactRefreshEntry.js ./node_modules/@pmmmwh/react-refresh-webpack-plugin/src/runtime/ErrorOverlayEntry.js ./node_modules/@pmmmwh/react-refresh-webpack-plugin/src/runtime/BabelDetectComponent.js ./ts/apps/index.tsx 88 bytes {app}
    factory:0ms dependencies:0ms = 0ms
[+HD3] ./ts/apps/index.tsx 2.12 KiB {app} [built]
    [0] 0ms -> factory:0ms building:441ms dependencies:10ms = 451ms
[+gfj] (webpack)-dev-server/client/overlay.js 3.51 KiB {common}
    [3] 0ms -> [GBRk] 1ms -> factory:3ms dependencies:0ms = 4ms
[/ig4] ./ts/core/assets/styles/win-custom-styles.less 1.35 KiB {core}
    [1] 0ms -> [7nBf] 290ms -> factory:12ms dependencies:9ms building:339ms = 650ms
[04Yr] ./ts/shared/contexts/ModalContext.tsx 2.54 KiB {app} [built]
    [0] 0ms -> [+HD3] 441ms -> factory:10ms dependencies:11ms building:1205ms = 1667ms
[56O9] (webpack)/hot/dev-server.js 1.59 KiB {common}
    [3] 0ms -> factory:1ms = 1ms
[7nBf] ./ts/core/core.ts 395 bytes {core} [built]
    [1] 0ms -> factory:8ms building:282ms = 290ms
[GBRk] (webpack)-dev-server/client?http://localhost:8080 4.29 KiB {common}
    [3] 0ms -> factory:1ms = 1ms
[GNp0] ./ts/core/polyfill.ts 133 bytes {common} [built]
    [1] 0ms -> factory:8ms building:282ms = 290ms
[HRtE] ./node_modules/@pmmmwh/react-refresh-webpack-plugin/src/runtime/ErrorOverlayEntry.js 2.22 KiB {common}
    [1] 0ms -> factory:8ms building:282ms = 290ms
[YQPH] ./node_modules/@pmmmwh/react-refresh-webpack-plugin/src/runtime/ReactRefreshEntry.js 1.47 KiB {common}
    [1] 0ms -> factory:8ms building:282ms = 290ms
[h2+b] ./node_modules/@pmmmwh/react-refresh-webpack-plugin/src/runtime/BabelDetectComponent.js 269 bytes {common}
    [1] 0ms -> factory:8ms building:282ms = 290ms
[ys7K] ./ts/core/reports.ts 431 bytes {reports} [built]
    [2] 0ms -> factory:0ms building:471ms dependencies:1ms = 472ms
    + 2563 hidden modules
Child html-webpack-plugin for "..\Views\Shared\_ExternalLayout.cshtml":
                                     Asset      Size  Chunks  Chunk Names
    ../Views/Shared/_ExternalLayout.cshtml  1.38 MiB       1
    Entrypoint undefined = ../Views/Shared/_ExternalLayout.cshtml
    [LvDl] ./node_modules/lodash/lodash.js 528 KiB {1}
        [dySk] 30ms -> factory:0ms = 30ms
    [YuTi] (webpack)/buildin/module.js 497 bytes {1}
        [dySk] 30ms -> [LvDl] 0ms -> factory:0ms = 30ms
    [dySk] ./node_modules/html-webpack-plugin/lib/loader.js!./Views/Shared/_ExternalLayout_Template.cshtml 8.99 KiB {1}
        factory:30ms = 30ms
    [yLpj] (webpack)/buildin/global.js 472 bytes {1}
        [dySk] 30ms -> [LvDl] 0ms -> factory:0ms = 30ms
Child html-webpack-plugin for "..\Views\Shared\_Layout.cshtml":
                             Asset      Size  Chunks  Chunk Names
    ../Views/Shared/_Layout.cshtml  1.38 MiB       1
    Entrypoint undefined = ../Views/Shared/_Layout.cshtml
    [0mc8] ./node_modules/html-webpack-plugin/lib/loader.js!./Views/Shared/_Layout_Template.cshtml 9.96 KiB {1}
        factory:36ms = 36ms
    [LvDl] ./node_modules/lodash/lodash.js 528 KiB {1}
        [0mc8] 36ms -> factory:0ms = 36ms
    [YuTi] (webpack)/buildin/module.js 497 bytes {1}
        [0mc8] 36ms -> [LvDl] 0ms -> factory:0ms = 36ms
    [yLpj] (webpack)/buildin/global.js 472 bytes {1}
        [0mc8] 36ms -> [LvDl] 0ms -> factory:0ms = 36ms
Child html-webpack-plugin for "..\Views\Shared\_ReportLayout.cshtml":
                                   Asset      Size  Chunks  Chunk Names
    ../Views/Shared/_ReportLayout.cshtml  1.36 MiB       1
    Entrypoint undefined = ../Views/Shared/_ReportLayout.cshtml
    [LvDl] ./node_modules/lodash/lodash.js 528 KiB {1}
        [jqcT] 28ms -> factory:0ms = 28ms
    [YuTi] (webpack)/buildin/module.js 497 bytes {1}
        [jqcT] 28ms -> [LvDl] 0ms -> factory:0ms = 28ms
    [jqcT] ./node_modules/html-webpack-plugin/lib/loader.js!./Views/Shared/_reportLayout_Template.cshtml 1.88 KiB {1}
        factory:28ms = 28ms
    [yLpj] (webpack)/buildin/global.js 472 bytes {1}
        [jqcT] 28ms -> [LvDl] 0ms -> factory:0ms = 28ms
i 「wdm」: Compiled successfully.

Without WWRP

「wdm」: Compiling...
<w> [webpack.Progress] 1109ms building
<i> [webpack.Progress] 13ms finish module graph
<i> [webpack.Progress] 11ms sealing
<i> [webpack.Progress] 70ms chunk graph
<i> [webpack.Progress] 41ms advanced chunk optimization
<i> [webpack.Progress] 74ms before module ids
<i> [webpack.Progress] 23ms module id optimization
<i> [webpack.Progress] 17ms after chunk id optimization
<i> [webpack.Progress] 104ms hashing
<i> [webpack.Progress] 27ms chunk assets processing
<i> [webpack.Progress] 21ms additional chunk assets processing
<i> [webpack.Progress] 693ms emitting
98% after emitting SizeLimitsPluginclean-webpack-plugin: removed dist\telerikReportViewerTemplate-sass.html
No type errors found
Version: typescript 3.7.3
Time: 1085ms
<i> [webpack.Progress] 114ms after emitting
i 「wdm」: Hash: 431214b6852b5a806287
Version: webpack 4.41.2
Time: 2324ms
Built at: 12/12/2019 12:16:48 PM
                                 Asset        Size   Chunks                                      Chunk Names
../Views/Shared/_ExternalLayout.cshtml    4.36 KiB           [emitted]
        ../Views/Shared/_Layout.cshtml    5.48 KiB           [emitted]
  ../Views/Shared/_ReportLayout.cshtml   695 bytes           [emitted]
  041f1357f2492b05851876a11fc8a3a0.png    3.63 KiB
  2e8648b3a07565dbffc7f0ce9d317b5a.png  1010 bytes
  2e971aaba434e77407062be68abcb816.png    3.62 KiB
  2f33973cbe60f770a187e86895cb6e88.png    4.15 KiB
  3444d9d5d1039b8b619d05efd687a6a9.png   132 bytes
  4405429be6a2a9858b9d6c0440bca385.png    1.16 KiB
448c34a56d699c29117adc64c43affeb.woff2    17.6 KiB
  4889784689c1b8109f97a0eecf9265f4.gif   723 bytes
  674f50d287a8c48dc19ba404d20fe713.eot     162 KiB
  76d94c53ff582a64732e992bf3205e60.png   117 bytes
  7a4b4c6ebdb549fcbe47408f9457493e.gif   329 bytes
  7b9776076d5fceef4993b55c9383dedd.gif    1.81 KiB
  89889688147bd7575d6327160d64e760.svg     106 KiB
  89e54b5ecbc18456c945a814484ded7e.png   807 bytes
  912ec66d7572ff821749319396470bde.svg     434 KiB                                        [big]
  94d4a6174afd2fd7ecff.hot-update.json    45 bytes           [emitted] [immutable] [hmr]
  9cd6e041544b63fb70f4b3e898a9878d.eot    12.9 KiB
  9d4c1f083c33e23adc577b1589dfe851.png    1.09 KiB
  9f5ff9b0d8b042651089bccbbcfe56fb.jpg    4.93 MiB                                        [big]
  a57ccfcfbc09eacaa8c7d490af8faed1.png   107 bytes
  a7c2174f5c11fe4d4fe622f53adcf471.png    3.62 KiB
  aa6c079759e4cdbb3b14cd960047cc93.png   116 bytes
  ae06b0018e895cfdfec66183874d0282.gif    8.04 KiB
af7ae505a9eed503f8b8e6982036873e.woff2    75.4 KiB
app.94d4a6174afd2fd7ecff.hot-update.js    24.7 KiB      app  [emitted] [immutable] [hmr]         app
                                app.js    15.7 MiB      app  [emitted]                    [big]  app
  b06871f281fee6b241d60582ae9369b9.ttf     162 KiB
  b958053351f480436d7550170526256f.png    3.62 KiB
  bce450800e44a407218277f2d518a635.png    2.77 KiB
  c4f238d22393a5e916764759aaaf9e0f.gif    3.61 KiB
  c4fc0214ddf2b82117aefeea28f39bab.png   117 bytes
  c575d67d0bb94b23dc90eff65993e4c3.png    1.95 KiB
  cb057877085d8ef838b8a8247477bccc.png    23.3 KiB
                             common.js    34.2 MiB   common                               [big]  common
                               core.js     7.9 MiB     core  [emitted]                    [big]  core
  d8aaa942c8c026410cd3032167facd15.png       1 KiB
 df36508b58279b852bce0bc1a503eb8d.woff    8.14 KiB
  e18bbf611f2a2e43afc071aa2f4e1512.ttf    44.3 KiB
  ee79d26d853d4de007a1abada84d6f12.png   962 bytes
  f266141392a706176dc9cf22b4740040.png    3.83 KiB
  f470863024f982806a178d720710f024.png   509 bytes
  f4769f9bdb7466be65088239c12046d1.eot    19.7 KiB
 fa2772327f55d8198301fdb8bcfc8158.woff    22.9 KiB
  fa9d99f038715abf8ace2816decde252.png   494 bytes
  fab39f2771ab597b747dd401a85acad4.png   118 bytes
  fce9a0f2784bc80eeb2f2f25f670f3da.ttf    12.7 KiB
 fee66e712a8a08eef5805a46892932ad.woff    95.7 KiB
                            reports.js      33 KiB  reports  [emitted]                           reports
Entrypoint core [big] = common.js core.js
Entrypoint reports [big] = common.js reports.js
Entrypoint app [big] = common.js app.js app.94d4a6174afd2fd7ecff.hot-update.js
[0] multi (webpack)-dev-server/client?http://localhost:8080 (webpack)/hot/dev-server.js ./ts/core/polyfill.ts ./ts/core/core.ts 64 bytes {core}
    factory:0ms dependencies:0ms = 0ms
[5] multi (webpack)-dev-server/client?http://localhost:8080 (webpack)/hot/dev-server.js ./ts/core/polyfill.ts ./ts/core/reports.ts 64 bytes {reports}
    factory:0ms dependencies:0ms = 0ms
[6] multi (webpack)-dev-server/client?http://localhost:8080 (webpack)/hot/dev-server.js ./ts/apps/index.tsx 52 bytes {app}
    factory:0ms dependencies:0ms = 0ms
[+HD3] ./ts/apps/index.tsx 1.52 KiB {app}
    [1] 0ms -> factory:0ms = 0ms
[+gfj] (webpack)-dev-server/client/overlay.js 3.51 KiB {common}
    [0] 0ms -> [GBRk] 0ms -> factory:3ms dependencies:0ms = 3ms
[/ig4] ./ts/core/assets/styles/win-custom-styles.less 1.35 KiB {core}
    [2] 0ms -> [7nBf] 1ms -> factory:0ms dependencies:0ms = 1ms
[04Yr] ./ts/shared/contexts/ModalContext.tsx 1.74 KiB {app}
    [1] 0ms -> [+HD3] 0ms -> factory:0ms dependencies:1ms = 1ms
[201c] ./node_modules/babel-polyfill/lib/index.js 833 bytes {common}
    [2] 0ms -> [GNp0] 1ms -> factory:0ms = 1ms
[55Ip] ./node_modules/react-router-dom/esm/react-router-dom.js 9.76 KiB {app}
    [1] 0ms -> [+HD3] 0ms -> factory:0ms dependencies:1ms = 1ms
[56O9] (webpack)/hot/dev-server.js 1.59 KiB {common}
    [0] 0ms -> factory:0ms = 0ms
[7cWc] ./ts/core/dependencies/telerik-report-viewer/win-telerik-report-viewer.ts 178 bytes {common}
    [2] 0ms -> [7nBf] 1ms -> factory:0ms dependencies:0ms = 1ms
[7nBf] ./ts/core/core.ts 395 bytes {core}
    [2] 0ms -> factory:1ms = 1ms
[GBRk] (webpack)-dev-server/client?http://localhost:8080 4.29 KiB {common}
    [0] 0ms -> factory:0ms = 0ms
[GNp0] ./ts/core/polyfill.ts 133 bytes {common}
    [2] 0ms -> factory:1ms = 1ms
[ys7K] ./ts/core/reports.ts 431 bytes {reports}
    [3] 0ms -> factory:0ms dependencies:0ms = 0ms
    + 2469 hidden modules
Child html-webpack-plugin for "..\Views\Shared\_ExternalLayout.cshtml":
                                     Asset      Size  Chunks  Chunk Names
    ../Views/Shared/_ExternalLayout.cshtml  1.38 MiB       1
    Entrypoint undefined = ../Views/Shared/_ExternalLayout.cshtml
    [LvDl] ./node_modules/lodash/lodash.js 528 KiB {1}
        [dySk] 61ms -> factory:0ms = 61ms
    [YuTi] (webpack)/buildin/module.js 497 bytes {1}
        [dySk] 61ms -> [LvDl] 0ms -> factory:0ms = 61ms
    [dySk] ./node_modules/html-webpack-plugin/lib/loader.js!./Views/Shared/_ExternalLayout_Template.cshtml 8.99 KiB {1}
        factory:61ms = 61ms
    [yLpj] (webpack)/buildin/global.js 472 bytes {1}
        [dySk] 61ms -> [LvDl] 0ms -> factory:0ms = 61ms
Child html-webpack-plugin for "..\Views\Shared\_Layout.cshtml":
                             Asset      Size  Chunks  Chunk Names
    ../Views/Shared/_Layout.cshtml  1.38 MiB       1
    Entrypoint undefined = ../Views/Shared/_Layout.cshtml
    [0mc8] ./node_modules/html-webpack-plugin/lib/loader.js!./Views/Shared/_Layout_Template.cshtml 9.96 KiB {1}
        factory:64ms = 64ms
    [LvDl] ./node_modules/lodash/lodash.js 528 KiB {1}
        [0mc8] 64ms -> factory:0ms = 64ms
    [YuTi] (webpack)/buildin/module.js 497 bytes {1}
        [0mc8] 64ms -> [LvDl] 0ms -> factory:0ms = 64ms
    [yLpj] (webpack)/buildin/global.js 472 bytes {1}
        [0mc8] 64ms -> [LvDl] 0ms -> factory:0ms = 64ms
Child html-webpack-plugin for "..\Views\Shared\_ReportLayout.cshtml":
                                   Asset      Size  Chunks  Chunk Names
    ../Views/Shared/_ReportLayout.cshtml  1.36 MiB       1
    Entrypoint undefined = ../Views/Shared/_ReportLayout.cshtml
    [LvDl] ./node_modules/lodash/lodash.js 528 KiB {1}
        [jqcT] 51ms -> factory:0ms = 51ms
    [YuTi] (webpack)/buildin/module.js 497 bytes {1}
        [jqcT] 51ms -> [LvDl] 0ms -> factory:0ms = 51ms
    [jqcT] ./node_modules/html-webpack-plugin/lib/loader.js!./Views/Shared/_reportLayout_Template.cshtml 1.88 KiB {1}
        factory:51ms = 51ms
    [yLpj] (webpack)/buildin/global.js 472 bytes {1}
        [jqcT] 51ms -> [LvDl] 0ms -> factory:0ms = 51ms
i 「wdm」: Compiled successfully.

A lot of those files are building in 290ms where as without RRWP they're building 0-3ms. Assuming this hold for the +~2500 hidden modules It just appears the build is two orders of magnitude slower for each module.

Is there a way I can get some more fine grained breakdown of these builds? I might see if I can repeat this is a small barebones repo for easier testing.

@mmhand123
Copy link
Contributor

Was running into the same problem with a pretty large webpack project. It looks like for some reason the addDependency line in the loader is somehow causing it to actually not be cached. Removing that line speeds up incremental recompiles back to their original speed in our project. Happy to make a PR if that helps!

@IronSean
Copy link
Author

@gaearon I was wrong, my run command was triggering npm install before the run and wiping out my npm link. Adding this.cacheable(); does in fact fix it, lowering build times to 1.5-2s.

@mmhand123 's solution of removing the line 21 also works:

this.addDependency(path.resolve('./runtime/RefreshModuleRuntime'));

@mmhand123
Copy link
Contributor

Unfortunately in the project I'm working in the this.cacheable() solution doesn't seem to impact incremental build performance.

@mmhand123
Copy link
Contributor

@IronSean what do you think about using the other solution as the proposed fix since it works for both of us?

@IronSean
Copy link
Author

I'd want to know what it's doing and if it would cause causing any other issues by removing it. Ultimately that's probably for @pmmmwh to answer since I don't know myself. It seemed to work fine without it on my env but I didn't test robustly.

That's odd that this.cacheable only affects one of us.

@mmhand123
Copy link
Contributor

Yeah definitely. I actually ended up moving the require outside of the loader along with removing the dependency. I'll make a pr too for @pmmmwh to look at whenever there's free time!

@IronSean
Copy link
Author

Both solutions work for my project to similar results, but your fix does perform significantly better in the small Kitchen Sink demo, If that single import doesn't cause any other issues I'd say that's the better solution.

@pmmmwh
Copy link
Owner

pmmmwh commented Dec 13, 2019

I don't have time to look at this until Sunday night, but from what I read from the Webpack docs, removing addDependency is safe, because the file is static. I am guessing that addDependency broke Webpack's default caching behaviour, so thus why adding cacheable could fix that.

Moving the require outside of the loader should further ensure better caching since Node will cache it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants