专栏首页全栈开发webpack构建优化:bundle体积从3M到400k之路
原创

webpack构建优化:bundle体积从3M到400k之路

在CQM平台开发时,把demo网站给同事体验,都纷纷反馈第一次打开页面的时候需要等待很久,页面一直在转菊花。作为一个为韩国头部厂商提供优质服务的网站,接到这种反馈,这不是啪啪打脸吗。

代码是在以前的老框架上写的(必须坚定把锅甩出去,手动捂脸)。喝杯咖啡镇定下,找找什么问题。赶紧打开chrome (disable cache):

哇,吓了一跳,这打包出来的JS辣么大:lib.js 2.3M(花了14s 才加载完)、app.js 1.2M(花了9s多加载完),难怪反馈页面响应慢。

  • 1、祭出神器把Bundle分析利器拿出来:

  webpack-bundle-analyzer是一个基于webpack的插件,能够用zoomable treemap可视化webpack输出文件的大小(Visualize size of webpack output files with an interactive zoomable treemap)

不慌,喝口白开水,装上webpack-bundle-analyzer看看里面分别是啥。

npm install webpack-bundle-analyzer

     在webpack.app.config.js引入webpack-bundle-analyzer

constBundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
   output: {
       //省略
   },
   entry: { 
      //省略
   },
   plugins: [
      new BundleAnalyzerPlugin(),
   ],
};

很简单吧,这样我们就配好了webpack-bundle-analyzer

  • 2、优化app.js文件

项目的package.json文件如下:

{
  "private": true,
  "scripts": {
    "dev": "npm run development",
    "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
    //开发环境生成 app.js及页面js
    "watch": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=webpack.app.config.js",
    "watch-poll": "npm run watch -- --watch-poll",
    "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
    "prod": "npm run production",
    //生成环境打包 app.js及页面js
    "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --config=webpack.app.config.js",
    //单独打包 lib.js
    "build-lib": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --config=webpack.lib.config.js",
    "build-online": "gulp pack --env production"
  },
  "devDependencies": {
   	//省略
  },
  "dependencies": {
   //
  }
}

运行下npm run watch,Webpack会自动打开浏览器,在127.0.0.1:8888上显示如下:

ps: npm run watch 对应的配置文件webpack.app.config.js,打包的app.js及页面js的各组成的大小(面积越大,表示比重越大)。可以看到,app.js里面大头分别是vue、vue-router、vue-i18n组件(好家伙,这些组件都是在app.js里面import进来的)。我们将他们踢出去:

a、在webpack.app.config.js里面添加externals参数,这样即使我们没将这几个组件打包到app.js中,我们依然能将其import进来并use:

module.exports = {
    externals : {
       'vue':'Vue',
       'vue-router':'VueRouter',
       'vue-i18n': 'VueI18n',
}};

b、接着在index.html中:

<scriptsrc="//cdn.bootcss.com/vue/2.3.3/vue.min.js"></script>
<script src="//cdn.bootcss.com/vue-router/3.0.1/vue-router.min.js"></script>
<scriptsrc="https://unpkg.com/vue-i18n@7.3.2/dist/vue-i18n.js"></script>

为什么要这么做呢?因为vue和vue-router在cdn上都提供了min版的js,已经是压缩精简版的,而vue-i18n.js的官方网站也建议使用cdn方式引入,没必要将都打包到app.js中。

对比优化前的app.js大小1.2M,以及下图单独引入vue.min.js、vue-i18n.js、vue-router.min.js的大小,分别为78K、38K、24K。效果十分明显

c、除了拆分依赖包,另一个重要的优化就是压缩代码,这里使用的是uglifyjs-webpack-plugin,同样在webpack.app.config.js的plugin里面添加

constUglifyJsPlugin= require('uglifyjs-webpack-plugin');
module.exports = {
     plugins:[
         new UglifyJsPlugin({
             uglifyOptions: {
                 output: {
                    beautify: false,
                    comments: false, 
                 },
                compress: {
                   warnings: false,
                   drop_debugger: true,
                   drop_console: true,
                   pure_funcs: ['console.log', '(e = console).log' ]
               },
               sourceMap: false
          }
    })
]};

这样之后效果如下,app.js从1.2M缩减到200kb,达到了可观的效果

  • 3、优化lib.js文件

       导致我们页面响应慢另一个大文件是 lib.js这里介绍下,在我们工程里,对常用的第三方UI组件、绘图组件、编辑组件,项目里将其统一打包到lib.js里面,不用每次构建都重新打包lib.js,这样可以加快构建速度),对应配置文件webp.lib.config.js。同样用webpack-bundle-analyzer,如图所示:里面体积最大的分别是element-ui、vue2-editor、highchart、jquery

以前的webpack.lib.config.js文件如下:

module.exports = {
    output: {
        path: path.join(__dirname, './public/js'),
        filename: '[name].js',
        library: '[name]',
    },
    entry: {
        "lib": ['vue','jquery', 'element-ui', 'vue-highcharts', 'vue2-editor', 'lodash'],
    },
};

       对比上面的webpack.app.config.js,vue已经引进了,所以不必重复打包。jquery、element-ui可以通过引入cdn文件解决,vue2-editor目前项目中暂时没用到,所以去掉呗。再添加上代码压缩插件,修改后的webpack.lib.config.js文件如下:

module.exports = {
    output: {
       path: path.join(__dirname, './public/js'),
       filename: '[name].js',
       library: '[name]',
    },
    entry: {
        "lib": ['vue-highcharts', 'lodash'],
    },
    newwebpack.optimize.UglifyJsPlugin({
       minimize: true
    }),
};

但是在app.js中还使用element-ui,所以在webpack.app.config.js中需要在external添加该项element-uijquery

module.exports = {
    externals : {
       'vue':'Vue',
       'vue-router':'VueRouter',
       'vue-i18n': 'VueI18n',
       'element-ui':'ElementUI',
       'jquery': 'jQuery.noConflict()'
}};

在index.html中添加jquery.all.js和element-ui,引入的js如下:

<script src="//cdn.bootcss.com/vue/2.3.3/vue.min.js"></script>
<script src="//cdn.bootcss.com/vue-router/3.0.1/vue-router.min.js"></script>
<script src="//unpkg.com/element-ui@1.3.6"></script>
<script src="//unpkg.com/element-ui@1.3.6/lib/umd/locale/en.js"></script>
<script>
    ELEMENT.locale(ELEMENT.lang.en)
</script>
<script src="https://unpkg.com/vue-i18n@7.3.2/dist/vue-i18n.js"></script>
<script src="/js/lib.js?12124142"></script>
<script src="http://iwaibao.qq.com/js/jquery.all.js?v=" language="javascript" type="text/javascript"></script>
<script src="{{ mix('js/app.js') }}"></script>

这里element-ui通过设置external然后引入cdn的js的时候有个坑,打包后老报错:

索性通过npm uninstall element-ui,将这个组件删除掉,直接通过cdn引入。执行npm run build-lib 生成,lib.js从2.3M减小到274kB

最终页面的js文件如下:

     对比优化前,网站访问流畅了不少(总共花了3s多加载完成)。虽然还不能做到如丝般柔滑,但罗马不是一天建成的(毕竟不能一次优化的太完美,不然后面怎么提升呢),比如打包速度提升(多线程打包)、页面代码分割与混淆等,后面咱们再慢慢优化

  • 最后

webpack基本已经成为前端项目的标配构建工具了,个人感觉大而全,里面有很多插件。比较赞同知乎网友对其的评价:

webpack充斥着大量名字类似 what-the-fuck-is-this-plugin 的插件,以及这个插件附带的一千种配置和一万种副作用,以至于每次出现打包的问题都会产生哲学三问:

    这个插件干了什么?

    我的配置有错误吗?

    这个插件真的没有bug吗?

比如UglifyJsPlugin删除生产环境里console.log的选项drop_console死活不生效,最后只能通过vue-loader中的preLoader预加载选项,利用strip-loader将vue文件中的console去掉

let rules = [
 {
    test: /\.vue$/,
    loader: 'vue-loader',
    options: {
       preLoaders: Mix.inProduction ? {js: 'strip-loader?strip[]=console.log,strip[]=console.warn'}:{},
       loaders:  //省略
    }
]

最后的最后再加一条:这个插件版本对吗?(手动哭脸)

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 浏览器架构学习

    在从事前端开发过程中,浏览器作为最重要的开发环境,浏览器基础是是前端开发人员必须掌握的基础知识点,它贯穿着前端的整个网络体系。对浏览器原理的了解,决定着编写前端...

    RubyLiao廖彩明
  • 一步一步创建vue2.0项目(一)

    新建一个文件夹 vue2.0-learn 。_前提是默认已经安装了nodejs和npm_

    frontoldman
  • webpack 4 :从0配置到项目搭建

    webpack4发布以来,我写项目都是用脚手架,即使再简单的项目,真的是really shame。。虽然道听途说了很多 webpack4 的特性,却没有尝试过,...

    前端博客 : alili.tech
  • 三分钟使用webpack-dev-sever搭建一个服务器

    webpack-dev-server是一个小型的Node.js Express服务器,我们可以通过它搭建一个本地服务器,并且实现文件热更新; 1.切换到你的目录...

    李文杨
  • React多页面应用3(webpack性能提升,包括打包性能、提取公共包等)

    本教程总共7篇,每日更新一篇,请关注我们!你可以进入历史消息查看以往文章,也敬请期待我们的新文章! 1.React多页面应用1(webpack开发环境搭建,包...

    前端人人
  • 利用webpack和vue实现组件化

    原文链接:http://mrzhang123.github.io/2016/06/02/webpack-vue-3/

    前端博客 : alili.tech
  • webpack2.x+vue2.x+node7.x+superagent 多入口多页面(MPA)开发环境搭建

    很早以前就想写这篇文章了,一直在犹豫,因为现在网上已经有很多大牛写了关于webpack+react、webpack+vue等入门的文章。我今天主要和大家分享的是...

    前端博客 : alili.tech
  • webpack入门指南

    1. 导语 github仓库 https://github.com/Rynxiao/webpack-test 1.1 什么叫做webpack webpack ...

    糊糊糊糊糊了
  • WebPack2配置我的Vue开发环境

    webpack-dev-server: webpack-dev-server是一款小型的Node.js Express服务器,我们使用它主要是为了实现代码的热重...

    前端博客 : alili.tech
  • 前后端分离之vue2.0+webpack2 实战项目 -- webpack介绍

    webpack的一点介绍 Webpack 把任何一个文件都看成一个模块,模块间可以互相依赖(require or import),webpack 的功能是把相互...

    smy

扫码关注云+社区

领取腾讯云代金券