在写该项目以前, 参考了ssh大佬的音乐项目(掘金地址), 由于了解到ssh效力于国内著名大厂,因此本着学习的态度在动手以前将其音乐项目的基础架构及代码风格研究了一遍(确实收获了不少)javascript
感谢大佬提供的apicss
cnpm i
npm run start 本地预览
npm run build 打包
npm run analyz 打包文件分析
npm run release 部署到服务器
复制代码
这个项目写到目前为止, 我花费精力最可能是webpack相关以及打包优化相关的内容(这里的精力 = 花费时间 / 代码量). 脚手架 很方便, 可是我仍是想体验下从0搭建一个小项目的webpack配置前端
mode: production
), 有了这句话, webpack会自动帮你压缩代码, 且效果很是显著gzip
, 这一步须要在webpack使用
compression-webpack-plugin
插件
plugins: [
...
new CompressionWebpackPlugin({
algorithm: 'gzip',
test: /\.js(\?.*)?$/i,
threshold: 10240,
minRatio: 0.8
}),
复制代码
以及nginx配置文件中配置vue
http{
....
gzip on;
gzip_comp_level 6;
gzip_types text/xml text/plain text/css application/javascript application/x-javascript application/rss+xml;
gzip_disable "MSIE[1-6]\.";
复制代码
使用过程当中我发现webpack不配置gzip压缩仅配置nginx, 在最终访问项目时, 拿到的文件也是gzip格式的. 查阅后,才知道 gzip 服务端也能进行压缩, 可是若是客户端直接把压缩好的gzip文件传到服务端 能够节省服务端在收到请求后对文件进行的压缩的性能损耗java
ParallelUglifyPlugin
, 开启多个子进程并行压缩 节省压缩时间, 而且去除调试日志plugins:[
...
new ParallelUglifyPlugin({
cacheDir: '.cache/',
uglifyJS:{
output: {
comments: false
},
warnings: false,
compress: {
drop_debugger: true, // 去除生产环境的 debugger 和 console.log
drop_console: true
}
}
}),
复制代码
// webpack.prod.conf.js
externals:{
vue: 'Vue',
'vue-router': 'VueRouter',
vuex: 'Vuex',
axios: 'axios',
},
// index.html
<head>
//使用dns预解析(将域名解析成ip是很耗时的)
<link rel="dns-prefetch" href="//cdn.bootcss.com">
<link rel="dns-prefetch" href="//cdnjs.cloudflare.com">
</head>
...
<body>
//这串奇怪的代码html-webpack-plugin插件会解析的
<% if ( process.env.NODE_ENV === 'production' ) { %>
<script src="https://cdn.bootcss.com/vue/2.6.10/vue.runtime.min.js"></script>
<script src="https://cdn.bootcss.com/vue-router/3.1.3/vue-router.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.0/axios.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/3.1.2/vuex.min.js"></script>
<%} %>
复制代码
splitChunks
, 这个插件不须要install, 直接使用便可, 它的做用是将公共依赖单独提取出来,避免被重复打包, 具体细节能够看这splitChunks: {
chunks: 'all',
cacheGroups: {
xgplayer: {
test: /xgplayer/,
priority: 0,
name: 'xgplayer'
},
vendor: {
test: /[\\/]node_modules[\\/]/,
priority: -10,
name: 'vendors',
minChunks: 10
}
}
}
复制代码
注意下
'xgplayer'
, 这是个视频播放器库, 我这里单独配置也是为了优化打包, 第7点会说node
webpack-bundle-analyzer
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
plugins: [
// 打包分析
new BundleAnalyzerPlugin(
{
analyzerMode: 'server',
analyzerHost: '127.0.0.1',
analyzerPort: 8888,
reportFilename: 'report.html',
defaultSizes: 'parsed',
openAnalyzer: true,
generateStatsFile: false,
statsFilename: 'stats.json',
statsOptions: null,
logLevel: 'info'
}
),
],
复制代码
moment
这个库中有不少的语言包, 能够用webpack自带的ContextReplacementPlugin
插件进行过滤//过滤moment其余语言包 打包体积缩小200kb
new webpack.ContextReplacementPlugin(
/moment[/\\]locale$/,
/zh-cn/,
),
复制代码
xgplayer
也占用了很大的体积, 那如何优化呢? 这里引入一个'prefetching'
概念, 其思想就是将一些文件在浏览器资源空闲时去分配资源下载, 从业务逻辑考虑, 在用户初次访问项目时, 是不须要用到视频库的资源的, 因此能够把浏览器资源分配给首屏须要的文件. 在业务逻辑中这样配置watch: {
url: {
handler(newV, oldV) {
if (newV && newV !== oldV) {
if (!this.player) {
import(/* webpackPrefetch:true */'xgplayer').then((module) => {
xyPlayer = module.default;
this.initVideo()
//这里这样写的目的是,若是有用户经过url直接打开视频页, 那我也能够同步加载完视频库文件后, 再初始化视频组件
})
} else {
this.player.src = newV
this.player.reload()
}
}
},
immediate: !0
}
}
复制代码
coverage
, 这个工具能够帮你分析出文件利用率(即加载的文件中, 真正用到的代码有哪些), 附上一张我优化好的截图component: () => import('xxxx')
路由懒加载, 将须要用户交互才会用到的逻辑代码单独封装,按需加载,例如
//click.js
function click() {
....
}
export default click
//main.js
document.addEventListener('click', () => {
import('./click').then(({ default: click }) => {
click()
})
})
复制代码
固然这样作会很繁琐, 不过对于追求极致体验的应用来讲, 也是个路子...webpack
附上两张优化完状态, 固然 这不是还不是最佳的状态... ios
不用脚手架从0搭webpack及优化打包能让本身接触到不少业务代码之外的东西, 这些东西也是前端职责中很重要的但也经常被忽视的模块, 过程很艰难但也充满意义.nginx