I did a simple build speed test between parcel and webpack on a same simple vue project. However, webpack did better than parcel.
.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'
]
}
]
}
}
parcel will be faster than webpack as it should be
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
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
| Software | Version(s) |
| ---------------- | ---------- |
| Parcel | 1.12.3
| Node | 10.15.1
| npm/Yarn | 1.13.0
| Operating System | macOs Mojave 10.14
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"}
Most helpful comment
The file sizes of the bundles should be correct. The detailed breakdown of the assets in the bundle are not, however.
Also: webpack likely runs terser after the treeshaking (on the whole bundle).
In this case,
element-uidoesn'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.