1. 代码包优化
-
屏蔽 sourceMap
- 待下项目开发完成。进行打包源码上线环节,需要对项目开发环节的开发提示信息以及错误信息进行屏蔽,一方面可以减少上线代码包的大小;另一方面提高系统的安全性。在 vuejs 项目的 config 目录下有三个文件 dev.env.js(开发环境配置文件)、prod.env.js(上线配置文件)、index.js(通用配置文件)。vue-cli 脚手架在上线配置文件会自动设置允许 sourceMap 打包,所以在上线前可以屏蔽 sourceMap。如下所示,index.js 的配置如下, 通用配置文件分别对开发环境和上线环境做了打包配置分类,在 build 对象中的配置信息中,productionSourceMap 修改成 false:
'use strict'
// Template version: 1.3.1
// see http://vuejs-templates.github.io/webpack for documentation.
const path = require('path')
module.exports = {
dev: {
// Paths
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {},
// Various Dev Server settings
host: 'localhost', // can be overwritten by process.env.HOST
port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
autoOpenBrowser: false,
errorOverlay: true,
notifyOnErrors: true,
poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-
/**
* Source Maps
*/
// https://webpack.js.org/configuration/devtool/#development
devtool: 'cheap-module-eval-source-map',
// If you have problems debugging vue-files in devtools,
// set this to false - it *may* help
// https://vue-loader.vuejs.org/en/options.html#cachebusting
cacheBusting: true,
cssSourceMap: true
},
build: {
// Template for index.html
index: path.resolve(__dirname, '../dist/ndindex.html'),
// Paths
assetsRoot: path.resolve(__dirname, '../dist'),
assetsSubDirectory: 'static',
assetsPublicPath: './',
/**
* Source Maps
*/
productionSourceMap: false,
// https://webpack.js.org/configuration/devtool/#production
devtool: '#source-map',
// Gzip off by default as many popular static hosts such as
// Surge or Netlify already gzip all static assets for you.
// Before setting to `true`, make sure to:
// npm install --save-dev compression-webpack-plugin
productionGzip: true,
productionGzipExtensions: ['js', 'css','svg'],
// Run the build command with an extra argument to
// View the bundle analyzer report after build finishes:
// `npm run build --report`
// Set to `true` or `false` to always turn it on or off
bundleAnalyzerReport: process.env.npm_config_report
}
}
-
对项目代码中的 JS/CSS/SVG(*.ico) 文件进行 gzip 压缩
- 在 vue-cli 脚手架的配置信息中,有对代码进行压缩的配置项,例如 index.js 的通用配置,productionGzip 设置为 true,但是首先需要对 compress-webpack-plugin 支持,所以需要通过 npm install –save-dev compression-webpack-plugin(如果 npm install 出错了,就使用 cnpm install 安装。可能网络比较差 npm install 会出现频率比较大),gzip 会对 js、css 文件进行压缩处理;对于图片进行压缩问题,对于 png,jpg,jpeg 没有压缩效果,对于 svg,ico 文件以及 bmp 文件压缩效果达到 50%,在 productionGzipExtensions: [‘js’, ‘css’,’svg’] 设置需要进行压缩的什么格式的文件。对项目文件进行压缩之后,需要浏览器客户端支持 gzip 以及后端支持 gzip。下面可以查看成功支持 gzip 状态:
'use strict'
// Template version: 1.3.1
// see http://vuejs-templates.github.io/webpack for documentation.
const path = require('path')
module.exports = {
build: {
// Template for index.html
index: path.resolve(__dirname, '../dist/ndindex.html'),
// Paths
assetsRoot: path.resolve(__dirname, '../dist'),
assetsSubDirectory: 'static',
assetsPublicPath: './',
/**
* Source Maps
*/
productionSourceMap: false,
// https://webpack.js.org/configuration/devtool/#production
devtool: '#source-map',
// Gzip off by default as many popular static hosts such as
// Surge or Netlify already gzip all static assets for you.
// Before setting to `true`, make sure to:
// npm install --save-dev compression-webpack-plugin
productionGzip: true,
productionGzipExtensions: ['js', 'css','svg'],
// Run the build command with an extra argument to
// View the bundle analyzer report after build finishes:
// `npm run build --report`
// Set to `true` or `false` to always turn it on or off
bundleAnalyzerReport: process.env.npm_config_report
}
}
-
ResponseHeader- content-encoding:”gzip”
-
对路由组件进行懒加载
- 在路由配置文件里,这里是 router.js 里面引用组件。如果使用同步的方式加载组件,在首屏加载时会对网络资源加载加载比较多,资源比较大,加载速度比较慢。所以设置路由懒加载,按需加载会加速首屏渲染。在没有对路由进行懒加载时,在 Chrome 里 devtool 查阅可以看到首屏网络资源加载情况(6requests 3.8MB transfferred Finish:4.67s DOMContentLoaded 2.61s Load 2.70s)。在对路由进行懒加载之后(7requests 800kb transffered Finish2.67s DOMContentLoaded 1.72s Load 800ms), 可以看见加载速度明显加快。但是进行懒加载之后,实现按需加载,那么项目打包不会把所有 js 打包进 app.[hash].js 里面,优点是可以减少 app.[hash].js 体积,缺点就是会把其它 js 分开打包,造成多个 js 文件,会有多次 https 请求。如果项目比较大,需要注意懒加载的效果。
// 实现懒加载方式 import Vue from "vue"; import Router from "vue-router"; Vue.use(Router); export default new Router({ mode: "history", base: "/facex/district/", routes: [{ path: "/", redirect: "index"}, { path: "/", name: "home", component: resolve=>require(["@/views/home"],resolve), children: [ { // 员工查询 path: "/employees", component: resolve=>require(["@/components/employees"],resolve) }, { // 首页 path: "/index", component: resolve=>require(["@/views/index"],resolve) }, { // 访客查询 path: "/visitorlist", component: resolve=>require(["@/components/visitorlist"],resolve) }, { path: "/department", component: resolve=>require(["@/views/department"],resolve) }, // 识别查询 { path: "/discriminate", component: resolve=>require(["@/components/discriminate"],resolve) }, { path: "/addDevice", component: resolve=>require(["@/views/addDevice"],resolve) }, { path: "/districtNotice", component: resolve=>require(["@/components/districtNotice"],resolve) } ] }, { path: "/noticeList", name: "noticeList", component: resolve=>require(["@/views/noticeList"],resolve) }, { path: "/login", name: "login", component: resolve=>require(["@/views/login"],resolve) }, { path: "/register", name: "register", component: resolve=>require(["@/views/register"],resolve) }, { path: "/setaccount", name: "setaccount", component:resolve=>require(["@/views/setaccount"],resolve) }, { path: "/addGroup", name: "addGroup", component:resolve=>require(["@/views/addGroup"],resolve) }, { path: "/guide", name: "guide", component:resolve=>require(["@/components/guide"],resolve) }, { path: "/addNotice", name: "addNotice", component: resolve=>require(["@/views/addNotice"],resolve) } ] });i
2. 源码优化
-
v-if 和 v-show 选择调用
- v-show 和 v -if 的区别是:v-if 是懒加载,当状态为 true 时才会加载,并且为 false 时不会占用布局空间;v-show 是无论状态是 true 或者是 false,都会进行渲染,并对布局占据空间对于在项目中,需要频繁调用,不需要权限的显示隐藏,可以选择使用 v -show,可以减少系统的切换开销。
-
为 item 设置唯一 key 值,
- 在列表数据进行遍历渲染时,需要为每一项 item 设置唯一 key 值,方便 vuejs 内部机制精准找到该条列表数据。当 state 更新时,新的状态值和旧的状态值对比,较快地定位到 diff。
-
细分 vuejs 组件
- 在项目开发过程之中,第一版本把所有的组件的布局写在一个组件中,当数据变更时,由于组件代码比较庞大,vuejs 的数据驱动视图更新比较慢,造成渲染比较慢。造成比较差的体验效果。所以把组件细分,比如一个组件,可以把整个组件细分成轮播组件、列表组件、分页组件等。
-
减少 watch 的数据
- 当组件某个数据变更后需要对应的 state 进行变更,就需要对另外的组件进行 state 进行变更。可以使用 watch 监听相应的数据变更并绑定事件。当 watch 的数据比较小,性能消耗不明显。当数据变大,系统会出现卡顿,所以减少 watch 的数据。其它不同的组件的 state 双向绑定,可以采用事件中央总线或者 vuex 进行数据的变更操作。
-
内容类系统的图片资源按需加载
- 对于内容类系统的图片按需加载,如果出现图片加载比较多,可以先使用 v -lazy 之类的懒加载库或者绑定鼠标的 scroll 事件,滚动到可视区域先再对数据进行加载显示,减少系统加载的数据。
-
SSR(服务端渲染)
- 如果项目比较大,首屏无论怎么做优化,都出现闪屏或者一阵黑屏的情况。可以考虑使用 SSR(服务端渲染),vuejs 官方文档提供 next.js 很好的服务端解决方案,但是局限性就是目前仅支持 Koa、express 等 Nodejs 的后台框架,需要 webpack 支持。目前自己了解的就是后端支持方面,vuejs 的后端渲染支持 php,其它的不太清楚。
3. 用户体验优化
-
better-click 防止 iphone 点击延迟
- 在开发移动端 vuejs 项目时,手指触摸时会出现 300ms 的延迟效果,可以采用 better-click 对 ipone 系列的兼容体验优化。
-
菊花 loading
- 菊花 loading,在加载资源过程之中,可以提供 loading。此菊花 loading 不是那菊花。所以可以自由选择自己喜欢的菊花。
-
骨架屏加载
- 在首屏加载资源较多,可能会出现白屏和闪屏的情况。体验不好。使用骨架屏进行首屏在资源数据还没有加载完成时显示,给很好的体验效果。