黑马程序员技术交流社区

标题: vue打包优化大小,vue服务端渲染,非cli环境实现spa单页面项目 [打印本页]

作者: 绮罗    时间: 2020-4-29 17:54
标题: vue打包优化大小,vue服务端渲染,非cli环境实现spa单页面项目
引言:写这篇文章的目的主要在于刚才看了一位掘友的文章,但是我看了他的代码有点粗糙,甚至是我觉得无法作为一篇好的给予新手的引导文章。
这里我先抱歉一声,因为我这样做有损你的声誉。
先放上该掘友的文章,还是很不错的,只是希望多点注解会更好:
https://juejin.im/post/5d9ff02df265da5baf4104d9#comment
一、知识点和目的1、打包优化的目的优化项目启动速度,和性能
2、必要的清理数据
第一点是核心,第二点呢其实主要是清理console
3、性能优化的主要方向1、cdn加载
2、压缩js
3、减少项目在首次加载的时长(首屏加载优化)
4、目前的解决方向cdn加载不比多说,就是改为引入外部js路径
首屏加载优化方面主要其实就两点
第一:
尽可能的减少首次加载的文件体积,和进行分布加载,这是我们今天主要讲的
第二:
首屏加载最好的解决方案就是ssr(服务端渲染),还利于seo
但是一般情况下没太多人选择ssr,因为只要不需要seo,ssr更多的是增加了项目开销和技术难度的。很多公司是不会这样选择的
二、服务端渲染解决方案提供这块我先讲,因为篇幅较小,主要也是各大公司已经总结的
1、nuxt.js,地址:https://zh.nuxtjs.org
2、egg.js解决方案:地址:https://www.yuque.com/easy-team
我个人喜欢阿里团队的方式,毕竟性能更好,但是呢技术要求也更高。
注意语雀的连接进去,react和vue都有。所以很全面的。
三、打包优化1、我们首先是压缩js,并且开启gzip这个我用的是vueCLi3.X所以压缩js不必说,自带的。
说明:开启gzip代表你项目实际环境就可以使用gzip。
还有打包的时候不是你打出来的整体包越小越好,虽然从基本面上看确实如此。但是会有几个情况影响你打包的文件大小。
比如map.js文件还有gzip文件。
特别是gzip文件你是不可以删除原文件的。如果删除了原文件那么不支持的浏览器就炸了。所以,最好的方式是用浏览器的f12来观测是最好的
原因:
第一:浏览器需要支持
第二:需要后端配置,这里提供nginx方式:



http:{       gzip on; #开启或关闭gzip on off      gzip_disable "msie6"; #不使用gzip IE6      gzip_min_length 100k; #gzip压缩最小文件大小,超出进行压缩(自行调节)      gzip_buffers 4 16k; #buffer 不用修改      gzip_comp_level 8; #压缩级别:1-10,数字越大压缩的越好,时间也越长      gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png; #  压缩文件类型 }复制代码
gizp部分:
npm install compression-webpack-plugin
下面是我的vue.config.js
const CompressionWebpackPlugin = require("compression-webpack-plugin");const productionGzipExtensions = [  "js",  "css",  "svg",  "woff",  "ttf",  "json",  "html"];module.exports = {  publicPath: process.env.NODE_ENV === "production" ? "/" : "/", //部署应用包时的基本 URL  outputDir: "dist", //打包目录  indexPath: "index.html",  configureWebpack: {    plugins: [      //开启gzip压缩      new CompressionWebpackPlugin({        filename: "[path].gz[query]",        test: new RegExp("\\.(" + productionGzipExtensions.join("|") + ")$"),        threshold: 10240,        minRatio: 0.8, //压缩率大于0.8的才压缩        deleteOriginalAssets: false //是否删除原文件      })    ]  },  productionSourceMap: false, //不输出map文件  devServer: {}};复制代码2、去除不必要的提示和拆分与抽离公共js这里performance就是关闭每次打包之后的文件过大警告
optimization这个比较复杂,主要是拆分js和抽离公共js的。

提供一篇csdn的文章:https://blog.csdn.net/weixin_43678786/article/details/85788759
webpack官方文档:https://webpack.docschina.org/configuration/optimization/
configureWebpack: {  //关闭文件过大提示,利于打包加快速度  performance: {    hints: "warning",    //入口起点的最大体积    maxEntrypointSize: 50000000,    //生成文件的最大体积    maxAssetSize: 30000000,    //只给出 js 文件的性能提示    assetFilter: function(assetFilename) {      return assetFilename.endsWith(".js");    }  },  //公共代码抽离和代码分割,避免单个js文件过大  optimization: {    splitChunks: {      cacheGroups: {        vendor: {          chunks: "all",          test: /node_modules/,          name: "vendor",          minChunks: 1,          maxInitialRequests: 5,          minSize: 30000,          priority: 100        },        common: {          chunks: "all",          test: /[\\/]src[\\/]js[\\/]/,          name: "common",          minChunks: 3,          maxInitialRequests: 5,          minSize: 30000,          priority: 60        },        styles: {          name: "styles",          test: /\.(sa|sc|c)ss$/,          chunks: "all",          enforce: true        },        runtimeChunk: {          name: "manifest"        }      }    }  }},复制代码3、项目去除console.log这个项目上线那是基本上必须的,所以也提供下。
有两种方式
第一种:babel方式
npm install babel-plugin-transform-remove-console --save-dev

babel.config.js文件改为

let plugins = [];if (process.env.NODE_ENV === "production") {  plugins.push("transform-remove-console");}module.exports = {  plugins: plugins,  presets: ["@vue/app"]};复制代码
第二种:webpack方式
npm install uglifyjs-webpack-plugin
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");module.exports = {  publicPath: process.env.NODE_ENV === "production" ? "/" : "/", //部署应用包时的基本 URL  outputDir: "miniprogram", //打包目录  indexPath: "index.html",  configureWebpack: {    optimization: {      minimizer: [        new UglifyJsPlugin({          uglifyOptions: {            compress: {              drop_console: true, //console              drop_debugger: true,              pure_funcs: ["console.log"] //移除console            }          }        })      ]    }  }};复制代码
关闭eslint关于console的提示。很烦的。
.eslintrc.js文件

rules: {  "no-console": "off",  "no-debugger": "off"},复制代码4、项目中能用cdn加载的都用cdn加载这里我是基础的项目模版,所以没有加入axios,但是原理一致。
总体来说能用cdn加载的js都可以这样干。但是我必须做出说明该方式的有点和缺点。
缺点:
a、项目依赖会比较难以处理,毕竟全部放index.html下面真的很丑
b、对于大厂来说或者说带宽够高的情况下,对于首屏渲染的差别较小。
原因在于,改用cdn加载主要是降低服务器流量,但是js加载只是放在了别服务器,难道也不需要加载了?所以有用,但是呢一定规模后会有弊端出现。
下面是我把vue的基本三要素都改为cdn加载了
包含,vuerouter,vue,vuex
main.js文件
//import Vue from "vue";import App from "./App.vue";import router from "./router";import store from "./store";Vue.config.productionTip = false;new Vue({  router,  store,  render: h => h(App)}).$mount("#app");复制代码
router.js
这个路由懒加载必须的,这个也很影响首屏加载。(必须)
//import Vue from "vue";//import Router from "vue-router";Vue.use(VueRouter);export default new VueRouter({  mode: "history",  base: process.env.BASE_URL,  routes: [    {      path: "/",      name: "home",      component: () => import("./views/Home.vue")    },    {      path: "/about",      name: "about",      component: () => import("./views/About.vue")    }  ]});复制代码
store.js
//import Vue from "vue";//import Vuex from "vuex";Vue.use(Vuex);export default new Vuex.Store({  state: {    ceshi: "dht"  },  mutations: {},  actions: {}});复制代码
最后是打包出来的结果:
很小吧,而且我初步试验过,对于scss的处理和scpoe(css样式不冲突)没有影响,vuex也是正常运行。


然后这是我仅仅是把vue加载注释去掉
就加了60kb



5、cdn加载,但是不去除import引入方式这是掘友提供的,文章第三次修改。
这个方式的优点是不需要删除上述三个文件的代码,直接就可以拿来用。
扩展一下,该方法也可以作为不打包指定的js的方式。
官方文档的解释:如果我们想引用一个库,但是又不想让webpack打包

修改vue.config.js
configureWebpack:{    externals: {       'vue': 'Vue',       "vue-router": "VueRouter",       'vuex': 'Vuex'    }  },复制代码把上一步当中关于vue,vuex,等注释放开
router.js文件
修改为:
import Vue from "vue";import VueRouter from "vue-router";Vue.use(VueRouter);export default new VueRouter({  mode: "history",  base: process.env.BASE_URL,  routes: [    {      path: "/",      name: "home",      component: () => import("./views/Home.vue")    },    {      path: "/about",      name: "about",      component: () => import("./views/About.vue")    }  ]});复制代码
这样就可以了。这个是后续掘友提供的方法。更加顺滑的切换,并且更符合模块化开发。
个人已经试验过,并且修正。
不会增加包大小,也不需要注释import。
这是第四次修改文章,代码已经提交到git上。
四、git地址提供和不使用vueCli下怎么去实现vue单页面项目首先是本项目的地址:https://github.com/ht-sauce/performance-optimization
我们现在大部分都用的是vuecli,但是如果一个老项目的话就不能用vuecli了。所以就需要非cli环境下进行开发。下面是我之前找的两个非cli环境下的项目
注意该两个项目最好是放在nginx或者tomcat下运行,如果是webstrom的话直接右键运行index.html。直接双击html文件是无法运行的。
1、sea.js
https://github.com/ht-sauce/seajs-vue-spa

2、require.js
https://github.com/ht-sauce/vue-requirejs-spa





作者: 放荡的人生    时间: 2020-5-7 16:46

作者: xiaowang66    时间: 2020-5-7 17:34

你很棒




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2