在寫該項目以前, 參考了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