1.異步路由加載
import Vue from 'vue'
import Router from 'vue-router'
// 之前的方案
// import Index from '@/pages/index/'
// import ChooseUser from '@/pages/detail/chooseUser'
// 異步加載方案
const Index = r =>
require.ensure([], () => r(require('@/pages/index')), 'Index')
const ChooseUser = r =>
require.ensure([], () => r(require('@/pages/detail/chooseUser')),'ChooseUser')
Vue.use(Router)
export default new Router({
// mode:'history',// 開發(fā)階段開啟
routes: [
{
path: '/board/index/:id?',
name: 'Index',
component: Index
},
{
path: '/board/chooseUser',
name: 'ChooseUser',
component: ChooseUser
}
]
})
2.不打包庫文件
spa首屏加載慢蓝翰,主要是打包后的js文件過大,阻塞加載所致贯钩。那么如何減小js的體積呢募狂?
那就是把庫文件單獨(dú)拿出來加載,不要參與打包角雷。
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,minimum-scale=1,maximum-scale=1,initial-scale=1,user-scalable=no" />
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache">
<meta http-equiv="Expires" content="0">
<title>test</title>
<link rel="icon" type="image/x-icon" href="/static/favicon.ico" />
<link rel="stylesheet" href="/static/common/css/base.css">
</head>
<body style="margin:0;background:#f2f2f2;">
<script src="/static/common/js/polyfill.min.js"></script>
<!--vue-->
<script src="/static/common/js/vue.min.js"></script>
<!--vue-router-->
<script src="/static/common/js/vue-router.min.js"></script>
<!--axios-->
<script src="/static/common/js/axios.min.js"></script>
<!--element-ui-->
<link href="/static/common/js/element-ui/lib/theme-chalk/index.css" rel="stylesheet">
<script src="/static/common/js/element-ui/lib/index.js"></script>
<!--echarts-->
<script src="/static/common/js/echarts.min.js"></script>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
webpack.base.conf.js
externals: {
'element-ui': 'ELEMENT',
'vue': 'Vue',
'axios': 'axios',
'echarts': 'echarts',
'vue-router': 'VueRouter'
},
這個(gè)鍵值對(duì)大家需要重點(diǎn)關(guān)注一下熬尺,配置錯(cuò)了這些大文件仍舊參與打包,導(dǎo)致優(yōu)化失敗谓罗。
鍵(key)粱哼,就是你用npm install命令裝的插件名稱,不確定的話檩咱,找一下package.json文件對(duì)一下揭措。
值(value),就是對(duì)外提供的那個(gè)對(duì)象刻蚯,這個(gè)你得打開庫文件看看咯绊含。
比如element UI:
element-ui是通過exports模塊導(dǎo)出ELEMENT這個(gè)變量,所有的功能也應(yīng)該追加到這個(gè)變量下面炊汹。
再比如vue-router:
看一下未壓縮過的代碼躬充,發(fā)現(xiàn)作者是在VueRouter.prototype下面追加了不少方法,因此基本可以確定對(duì)外導(dǎo)出的對(duì)象應(yīng)該是VueRouter了。
這個(gè)辦法可以極大的壓縮js代碼的體積充甚,應(yīng)重點(diǎn)掌握以政。
但有同學(xué)還會(huì)有這樣的疑問:
既然在外部引入了庫文件,那在main.js里面伴找,是不是就不能這樣引用庫了:
main.js
import Vue from 'vue'
import App from './App'
import router from './router' // 路由
import ElementUI from 'element-ui'// UI插件
import echarts from 'echarts'// 引入圖表插件
Vue.prototype.$echarts = echarts // 追到全局
Vue.use(ElementUI)
Vue.config.productionTip = false
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
是嗎盈蛮?
當(dāng)然不是了!你該怎么import還是一樣技矮,否則怎么追加到Vue這個(gè)對(duì)象下面呢抖誉?
3.關(guān)閉sourcemap
sourcemap是為了方便線上調(diào)試用的,因?yàn)榫€上代碼都是壓縮過的衰倦,導(dǎo)致調(diào)試極為不便袒炉,而有了sourcemap,就等于加了個(gè)索引字典樊零,出了問題可以定位到源代碼的位置我磁。
但是,這個(gè)玩意是每個(gè)js都帶一個(gè)sourcemap淹接,有時(shí)sourcemap會(huì)很大十性,拖累了整個(gè)項(xiàng)目加載速度,為了節(jié)省加載時(shí)間塑悼,我們將其關(guān)閉掉劲适。
config/index.js
/**
* Source Maps
*/
productionSourceMap: false,
就這一句話就可以關(guān)閉sourcemap了,很簡單厢蒜。
4.開啟gzip壓縮
這個(gè)優(yōu)化是兩方面的霞势,前端將文件打包成.gz文件,然后通過nginx的配置斑鸦,讓瀏覽器直接解析.gz文件愕贡。
webpack的配置
config/index.js
// 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'],
build/webpack.prod.conf.js
if (config.build.productionGzip) {
const CompressionWebpackPlugin = require('compression-webpack-plugin')
webpackConfig.plugins.push(
new CompressionWebpackPlugin({
asset: '[path].gz[query]',
algorithm: 'gzip',
test: new RegExp(
'\\.(' +
config.build.productionGzipExtensions.join('|') +
')$'
),
threshold: 10240,
minRatio: 0.8
})
)
}
好了,做完這兩步巷屿,打包后的代碼就是醬紫的了:
nginx的配置
修改服務(wù)器的nginx 配置固以,找到conf目錄下的nginx.conf ,開啟gzip,并設(shè)置gzip的類型,如下:
gzip on;
gzip_types text/plain application/x-javascript application/javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
重啟nginx:
nginx -s reload
最后驗(yàn)證一下:
小結(jié)
以上幾種優(yōu)化方案較常用嘱巾,效果也立竿見影憨琳,這是我們的一個(gè)項(xiàng)目優(yōu)化過的代碼:
除了echart文件較大之外,其他的小文件基本不會(huì)造成太大影響旬昭,而如果讓這些庫文件參與打包篙螟,那至少得有個(gè)幾m。
首屏較慢的處理辦法
首屏加載過慢的問題如何解決呢问拘?
如果做完以上的優(yōu)化方案遍略,仍嫌過慢的話惧所,可以這樣做:
1.loading效果
首頁加個(gè)好看的loading阻塞一下,讓用戶別等的那么心焦绪杏。
2.首頁單獨(dú)做服務(wù)端渲染
如果首頁真的有瓶頸下愈,兼考慮seo問題,那還是用node的mvc框架(比如express)做首頁渲染寞忿,而下面的子頁面仍用spa單頁(將vue打包的dist目錄放在public目錄下驰唬,當(dāng)靜態(tài)資源來訪問)顶岸。
這里不推薦直接用nuxt.js服務(wù)端渲染方案腔彰。
因?yàn)橐皇窃黾恿藢W(xué)習(xí)成本,二是本來渲染就是瀏覽器該做的事情啊辖佣,憑什么讓服務(wù)端來摻和霹抛?
服務(wù)端組裝頁面需耗費(fèi)巨大的內(nèi)存資源,很容易把服務(wù)器搞死卷谈,而且這種方案對(duì)代碼質(zhì)量要求非常高杯拐,如果你不注意資源的回收而造成內(nèi)存泄露,瀏覽器重新刷一下就可以了世蔗,而服務(wù)端呢端逼?你重啟一下?一次宕機(jī)事故是要記入績效考核的污淋,宕機(jī)幾次你一個(gè)月工資就沒了顶滩!