Parcel: webpack is faster than parcel when I built the same project

Created on 29 Apr 2019  ยท  9Comments  ยท  Source: parcel-bundler/parcel

๐Ÿ› bug report

I did a simple build speed test between parcel and webpack on a same simple vue project. However, webpack did better than parcel.

๐ŸŽ› Configuration (.babelrc, package.json, cli command)

.babelrc

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "modules": false
      }
    ]
  ],
  "plugins": [
    "@babel/plugin-transform-runtime",
    [
      "component",
      {
        "libraryName": "element-ui",
        "styleLibraryName": "theme-chalk"
      }
    ],
  ]
}

package.json

{
  "name": "parcel-demo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "rm -rf dist && parcel -p 8081 index.html",
    "build": "rm -rf build && parcel build index.html -d build --no-source-maps --experimental-scope-hoisting --detailed-report"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@babel/preset-env": "^7.4.3",
    "babel-eslint": "^10.0.1",
    "babel-plugin-component": "^1.1.1",
    "element-ui": "^2.8.2",
    "eslint": "^5.16.0",
    "eslint-plugin-html": "^5.0.3",
    "jquery": "^3.4.0",
    "lodash": "^4.17.11",
    "parcel-bundler": "^1.12.3",
    "rimraf": "^2.6.3",
    "vue": "^2.6.10",
    "vue-hot-reload-api": "^2.3.3",
    "vue-router": "^3.0.6"
  },
  "devDependencies": {
    "@babel/core": "^7.4.3",
    "@babel/plugin-transform-runtime": "^7.4.3",
    "@vue/component-compiler-utils": "^3.0.0",
    "less": "^3.9.0",
    "sass": "^1.19.0",
    "vue-template-compiler": "^2.6.10"
  }
}

build command in parcel
"build": "rm -rf build && parcel build index.html -d build --no-source-maps --experimental-scope-hoisting --detailed-report"
webpack.prod.config.js

/*eslint-disable*/
const path = require('path')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const CleanWebpackPlugin = require('clean-webpack-plugin')
const UglifyjsPlugin = require('uglifyjs-webpack-plugin')
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
  entry: {
    app: ['./src/index.js'],
  },
  mode: 'production',
  //devtool: 'source-map',
  plugins: [
    new CleanWebpackPlugin(['dist'], {
      verbose: true
    }),
    new MiniCssExtractPlugin({
      filename: './css/style.css'
    }),
    new HtmlWebpackPlugin({
      template: './index.html'
    }),
    new VueLoaderPlugin(),
    new BundleAnalyzerPlugin()
  ],
  optimization: {
    splitChunks: {
      chunks: 'all',
      name: 'vendor'
    },
    runtimeChunk: {
      name: 'runtime'
    },
    minimizer: [
      new UglifyjsPlugin(),
      new OptimizeCSSAssetsPlugin()
    ]
  },
  output: {
    filename: 'bundle-[hash].js',
    path: path.resolve(__dirname, './dist'),
    //libraryTarget: 'umd',
    //umdNamedDefine: true
  },
  module: {
    rules: [
      {
        test: /\.vue$/,
        use: ['vue-loader']
      },
      {
        test: /\.js$/,
        exclude: /(node_modules|bower_components)/,
        use: ['babel-loader']
      },
      {
        test: /\.css$/,
        use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader']
      },
      {
        test: /\.scss$/,
        use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', 'sass-loader']
      },
      {
        test: /\.(png|svg|jpg|jpeg|gif)$/,
        use: [
          'file-loader'
        ]
      },
      {
        test: /\.(woff|woff2|eot|ttf|otf)$/,
        use: [
          'file-loader'
        ]
      }
    ]
  }
}

๐Ÿค” Expected Behavior

parcel will be faster than webpack as it should be

๐Ÿ˜ฏ Current Behavior

webpack build info

Hash: d1103cf2d6ef5e73d46c
Version: webpack 4.30.0
Time: 4761ms
Built at: 2019-04-29 16:10:29
                                Asset       Size  Chunks             Chunk Names
                    ./css/2.style.css    187 KiB       2  [emitted]  vendor
     0.bundle-d1103cf2d6ef5e73d46c.js   1.75 KiB       0  [emitted]  app
     2.bundle-d1103cf2d6ef5e73d46c.js    194 KiB       2  [emitted]  vendor
2fad952a20fbbcfd1bf2ebb210dccf7a.woff   6.02 KiB          [emitted]
     3.bundle-d1103cf2d6ef5e73d46c.js  353 bytes       3  [emitted]
     4.bundle-d1103cf2d6ef5e73d46c.js  356 bytes       4  [emitted]
 6f0a76321d30f3c8120915e57f7bd77e.ttf   10.8 KiB          [emitted]
       bundle-d1103cf2d6ef5e73d46c.js   2.14 KiB       1  [emitted]  runtime
                           index.html  577 bytes          [emitted]

parcel buld info

โœจ  Built in 12.89s.

build/src.e6310d07.js                                                   372.2 KB    12.48s
โ”œโ”€โ”€ node_modules/vue/dist/vue.runtime.esm.js                            92.72 KB     3.61s
โ”œโ”€โ”€ node_modules/jquery/dist/jquery.js                                  85.97 KB     5.00s
โ”œโ”€โ”€ node_modules/lodash/lodash.js                                       68.62 KB     6.95s
โ”œโ”€โ”€ node_modules/vue-router/dist/vue-router.esm.js                      31.52 KB     3.34s
โ”œโ”€โ”€ node_modules/element-ui/lib/select.js                               26.36 KB     1.36s
โ”œโ”€โ”€ node_modules/buffer/index.js                                        25.01 KB     457ms
โ”œโ”€โ”€ node_modules/element-ui/lib/utils/popper.js                         12.54 KB     1.65s
โ”œโ”€โ”€ node_modules/element-ui/lib/input.js                                11.14 KB     905ms
โ”œโ”€โ”€ node_modules/resize-observer-polyfill/dist/ResizeObserver.es.js      9.15 KB     719ms
โ”œโ”€โ”€ node_modules/element-ui/lib/loading.js                               7.47 KB     766ms
โ””โ”€โ”€ + 38 more assets

build/src.7c78d54f.css                                                 260.94 KB     9.77s
โ”œโ”€โ”€ node_modules/element-ui/lib/theme-chalk/index.css                  211.08 KB     9.45s
โ”œโ”€โ”€ node_modules/element-ui/lib/theme-chalk/base.css                    15.88 KB     9.38s
โ”œโ”€โ”€ node_modules/element-ui/lib/theme-chalk/select.css                  15.44 KB     9.38s
โ”œโ”€โ”€ node_modules/element-ui/lib/theme-chalk/button.css                  10.34 KB     9.38s
โ”œโ”€โ”€ node_modules/element-ui/lib/theme-chalk/input.css                    6.55 KB     9.38s
โ””โ”€โ”€ node_modules/element-ui/lib/theme-chalk/loading.css                  1.63 KB     9.38s

build/element-icons.f5240f4e.ttf                                        54.64 KB      78ms
build/element-icons.67bee1e1.woff                                       27.54 KB      77ms
build/login.daa6053a.js                                                     1 KB     8.29s
build/home.3d8983da.js                                                      1 KB     8.30s
build/index.html                                                           359 B     429ms
build/home.3d8983da.css                                                     32 B     8.30s

๐Ÿ”ฆ Context

Webpack built it much faster than parcel . Otherwise, I got much bigger size from parcel than wepack.
eg:
in parcel

build/src.e6310d07.js                                                   372.2 KB    10.61s
โ”œโ”€โ”€ node_modules/vue/dist/vue.runtime.esm.js                            92.72 KB     3.58s
โ”œโ”€โ”€ node_modules/jquery/dist/jquery.js                                  85.97 KB     5.74s
โ”œโ”€โ”€ node_modules/lodash/lodash.js                                       68.62 KB     5.80s
โ”œโ”€โ”€ node_modules/vue-router/dist/vue-router.esm.js                      31.52 KB     2.21s
โ”œโ”€โ”€ node_modules/element-ui/lib/select.js                               26.36 KB     1.37s
โ”œโ”€โ”€ node_modules/buffer/index.js                                        25.01 KB     440ms
โ”œโ”€โ”€ node_modules/element-ui/lib/utils/popper.js                         12.54 KB     820ms
โ”œโ”€โ”€ node_modules/element-ui/lib/input.js                                11.14 KB     842ms
โ”œโ”€โ”€ node_modules/resize-observer-polyfill/dist/ResizeObserver.es.js      9.15 KB     861ms
โ”œโ”€โ”€ node_modules/element-ui/lib/loading.js                               7.47 KB     726ms

only 63 kb in webpack

๐Ÿ’ป Code Sample

๐ŸŒ Your Environment

| Software | Version(s) |
| ---------------- | ---------- |
| Parcel | 1.12.3
| Node | 10.15.1
| npm/Yarn | 1.13.0
| Operating System | macOs Mojave 10.14

Feature โœจ Parcel 2

Most helpful comment

The sizes parcel reports when using scope hoisting are incorrect.

The file sizes of the bundles should be correct. The detailed breakdown of the assets in the bundle are not, however.

If I'm not mistaken Parcel still transforms unused requires but treeshakes them out at the end we do remove some obvious obsolete requires but not all of them, which webpack does better.

Also: webpack likely runs terser after the treeshaking (on the whole bundle).

a library is written poorly.

In this case, element-ui doesn't provide an ES modules build (https://unpkg.com/[email protected]/package.json). Treeshaking a minified CommonJS build with Parcel isn't nearly as effective.

All 9 comments

The sizes parcel reports when using scope hoisting are incorrect. You should check the actual filesize for the real size. Parcel is mainly faster on large projects and when using cache. Not sure why it is slower without being able to debug this...

Sent with GitHawk

The sizes parcel reports when using scope hoisting are incorrect. You should check the actual filesize for the real size. Parcel is mainly faster on large projects and when using cache. Not sure why it is slower without being able to debug this...

Sent with GitHawk

I had closed tree shaking but got the same result.,smaller and bigger.

Howerver, if element-ui was removed, parcel performed faster than webpack.

I think one of the factors of parcel bad performance was some third libraries such as element-ui, when it was build ,element-ui/lib/index.js and element-ui/lib/theme-chalk/index.css take a lot of time.
Did babel transform these files which were exclude in webpack because the size were over than limited size ?

@yanxiaosong0902 Webpack does treeshaking differently.
If I'm not mistaken Parcel still transforms unused requires but treeshakes them out at the end we do remove some obvious obsolete requires but not all of them, which webpack does better.

However this only happens for libraries that are designed poorly.
For example one giant index file that exports 1000 files is a terrible idea.
Making it slower if a library is written poorly.

Also as the flag states Parcel's treeshaking is experimental and I strongly hope things like this will be optimised once Parcel 2 is released and we can focus on bugs & improvements again.

I had closed tree shaking but got the same result.,smaller and bigger.

Not sure what you mean by this. I meant open your file explorer and look at the actual file sizes the reported sizes by the cli aren't 100% accurate especially when using treeshaking

EDIT: Just had a look at element-ui and it is doing exactly what I described earlier as poor library design.

The sizes parcel reports when using scope hoisting are incorrect.

The file sizes of the bundles should be correct. The detailed breakdown of the assets in the bundle are not, however.

If I'm not mistaken Parcel still transforms unused requires but treeshakes them out at the end we do remove some obvious obsolete requires but not all of them, which webpack does better.

Also: webpack likely runs terser after the treeshaking (on the whole bundle).

a library is written poorly.

In this case, element-ui doesn't provide an ES modules build (https://unpkg.com/[email protected]/package.json). Treeshaking a minified CommonJS build with Parcel isn't nearly as effective.

Just adding according to the work in progress PR for v2 treeshaking this should get fixed in v2. As unused imports will no longer get processed

Sent with GitHawk

I think one of the factors of parcel bad performance was some third libraries such as element-ui, when it was build , element-ui/lib/index.js and element-ui/lib/theme-chalk/index.css take a lot of time.

Maybe the issue lies in the fact, that parcel compiles all node_modules, while your webpack config ignores them?
I'm not sure what the default behaviour of parcel is, but I couldn't find anything related to the node modules.

@yanxiaosong0902 could you retry the test with babel's exclude option in your .babelrc?

I'm not sure what the default behaviour of parcel is, but I couldn't find anything related to the node modules.

Parcel doesn't process node_modules with Babel, unless that package has a browserslist config that declares "newer" target browsers than the one you provided.

@mischnic Can you go explain a bit more. So If I've browserlist in babel what would be the outcome and what If I don't?

If the browserslist of the dependency means that it uses features that aren't available in your local browserslist config, then that dependency should be transpiled.

myapp/package.json: {ย "browserslist": "Chrome 10"}
myapp/node_modules/somelibrary/package.json: {ย "browserslist": "Chrome 70"}

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mnn picture mnn  ยท  3Comments

will-stone picture will-stone  ยท  3Comments

dotdash picture dotdash  ยท  3Comments

Niggler picture Niggler  ยท  3Comments

humphd picture humphd  ยท  3Comments