有沒(méi)有好的做海報(bào)的網(wǎng)站seo sem是指什么意思
在Vue項(xiàng)目中,引入到工程中的所有js、css文件,編譯時(shí)都會(huì)被打包進(jìn)vendor.js,瀏覽器在加載該文件之后才能開(kāi)始顯示首屏。若是引入的庫(kù)眾多,那么vendor.js文件體積將會(huì)相當(dāng)?shù)拇?#xff0c;影響首屏的體驗(yàn)??梢钥磦€(gè)例子:
這是優(yōu)化前的頁(yè)面加載狀態(tài):執(zhí)行?npm run build?
打包項(xiàng)目,出來(lái)的vendeor.js文件,基本都是1M以上的的巨大文件,沒(méi)有用戶能忍受5s以上的loading而不關(guān)閉頁(yè)面的,如圖所示:
?
當(dāng)項(xiàng)目在掛載到服務(wù)器上,平均都是10S+以上加載出來(lái),好家伙這加載時(shí)間,仿佛過(guò)了半個(gè)世紀(jì),很煩人,心態(tài)boom, 開(kāi)發(fā)者甚至都有種想砸電腦的沖動(dòng)?
一、分析下前端加載速度慢原因?
第一步:首先安裝webpack的可視化資源分析工具,命令行執(zhí)行:
?npm i webpack-bundle-analyzer -D
第二步:然后在webpack的dev開(kāi)發(fā)模式配置中,引入插件,代碼如下:
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer')plugins: [new BundleAnalyzerPlugin()
]
第三步:最后命令行執(zhí)行?npm run build --report?
?, 瀏覽器會(huì)自動(dòng)打開(kāi)分析結(jié)果,如下所示:
?
?可以看到vue全家桶相關(guān)依賴占用了很大的空間,對(duì)webpack的構(gòu)建速度和網(wǎng)站加載速度都會(huì)有比較大的影響。單頁(yè)應(yīng)用會(huì)隨著項(xiàng)目越大,導(dǎo)致首屏加載速度很慢,針對(duì)目前所暴露出來(lái)的問(wèn)題,有以下幾種優(yōu)化方案可以參考:?
二、優(yōu)化方案
0.初步優(yōu)化
初步優(yōu)化,減少全局組件引入(是否放在main.js),按需引入需要的模塊(echarts按需引入等),使用輕量級(jí)數(shù)據(jù)庫(kù)(moment.js 切換 data-fns等)?
1.采用懶加載的方式
路由懶加載和組件懶加載:
訪問(wèn)到當(dāng)前頁(yè)面才會(huì)加載相關(guān)的資源,異步方式分模塊加載文件,默認(rèn)的文件名是隨機(jī)的id。如果在output中配置了chunkFilename,可以在component中添加WebpackChunkName,是為了方便調(diào)試,在頁(yè)面加載時(shí)候,會(huì)顯示加載的對(duì)應(yīng)文件名+hash值,如下圖:
{path: '/Login',name: 'Login',component: () = >import( /* webpackChunkName: "Login" */ '@/view/Login')
}
圖片懶加載:使用vue-lazyload插件
//引入vue懶加載
import VueLazyload from 'vue-lazyload'//方法一: 沒(méi)有頁(yè)面加載中的圖片和頁(yè)面圖片加載錯(cuò)誤的圖片顯示
// Vue.use(VueLazyload)//方法二: 顯示頁(yè)面圖片加載中的圖片和頁(yè)面圖片加載錯(cuò)誤的圖片
//引入圖片
import loading from '@/assets/images/load.jpg'
//注冊(cè)圖片懶加載
Vue.use(VueLazyload, {// preLoad: 1.3,error: '@/assets/images/error.jpg',//圖片錯(cuò)誤的替換圖片路徑(可以使用變量存儲(chǔ))loading: loading,//正在加載的圖片路徑(可以使用變量存儲(chǔ))// attempt: 1
})
2.webpack開(kāi)啟gzip壓縮文件傳輸模式
gizp壓縮是一種http請(qǐng)求優(yōu)化方式,通過(guò)減少文件體積來(lái)提高加載速度。html、js、css文件甚至json數(shù)據(jù)都可以用它壓縮,可以減小60%以上的體積。
前端配置gzip壓縮,并且服務(wù)端使用nginx開(kāi)啟gzip,用來(lái)減小網(wǎng)絡(luò)傳輸?shù)牧髁看笮 ?/strong>
?webpack打包時(shí)借助 compression webpack plugin實(shí)現(xiàn)gzip壓縮,安裝插件如下:
npm i -D compression-webpack-plugin
在vue-cli 3.0 中,vue.config.js配置如下:
const CompressionPlugin = require('compression-webpack-plugin');//引入gzip壓縮插件
module.exports = {plugins:[new CompressionPlugin({//gzip壓縮配置test:/\.js$|\.html$|\.css/,//匹配文件名threshold:10240,//對(duì)超過(guò)10kb的數(shù)據(jù)進(jìn)行壓縮deleteOriginalAssets:false,//是否刪除原文件})]
}
啟用gzip壓縮打包之后,會(huì)變成下面這樣,自動(dòng)生成gz包。目前大部分主流瀏覽器客戶端都是支持gzip的,就算小部分非主流瀏覽器不支持也不用擔(dān)心,不支持gzip格式文件的會(huì)默認(rèn)訪問(wèn)源文件的,所以不要配置清除源文件。
在nginx中開(kāi)啟gzip:
server {gzip on;gzip_buffers 32 4K;gzip_comp_level 6;gzip_min_length 100;gzip_types application/javascript text/css text/xml application/json;gzip_vary on;listen 80;listen [::]:80 ;。。。。。。。。
配置好之后,打開(kāi)瀏覽器訪問(wèn)線上,F12查看控制臺(tái),如果該文件資源的響應(yīng)頭里顯示有Content-Encoding: gzip,表示瀏覽器支持并且啟用了Gzip壓縮的資源
3.依賴模塊采用第三方cdn資源(對(duì)于第三方j(luò)s庫(kù)的優(yōu)化,分離打包)?
生產(chǎn)環(huán)境是內(nèi)網(wǎng)的話,就把資源放內(nèi)網(wǎng),通過(guò)靜態(tài)文件引入,會(huì)比node_modules和外網(wǎng)CDN的打包加載快很多。如果有外網(wǎng)的話,可以通過(guò)CDN方式引入,因?yàn)椴挥谜加迷L問(wèn)外網(wǎng)的帶寬,不僅可以為您節(jié)省流量,還能通過(guò)CDN加速,獲得更快的訪問(wèn)速度。但是要注意下,如果你引用的CDN 資源存在于第三方服務(wù)器,在安全性上并不完全可控。國(guó)內(nèi)的CDN服務(wù)推薦使用?BootCDN
目前采用引入依賴包生產(chǎn)環(huán)境的js文件方式加載,直接通過(guò)window可以訪問(wèn)暴露出的全局變量,不必通過(guò)import引入,Vue.use去注冊(cè)
在webpack的dev開(kāi)發(fā)配置文件中, 加入如下參數(shù),可以分離打包第三方資源包,key為依賴包名稱,value是源碼拋出來(lái)的全局變量。對(duì)于一些其他的工具庫(kù),盡量采用按需引入的方式。
使用 CDN 的好處有以下幾個(gè)方面
(1)加快打包速度。分離公共庫(kù)以后,每次重新打包就不會(huì)再把這些打包進(jìn) vendors 文件中。
(2)CDN減輕自己服務(wù)器的訪問(wèn)壓力,并且能實(shí)現(xiàn)資源的并行下載。瀏覽器對(duì) src 資源的加載是并行的(執(zhí)行是按照順序的)。
第一步:修改vue.config.js
module.exports = {...externals: {'vue': 'Vue','vuex': 'Vuex','vue-router': 'VueRouter','axios': 'axios','element-ui': 'ELEMENT','underscore' : {commonjs: 'underscore',amd: 'underscore',root: '_'},'jquery': {commonjs: 'jQuery',amd: 'jQuery',root: '$'}} ...
}
如果想引用一個(gè)庫(kù),但是又不想讓webpack打包,且又不影響我們?cè)诔绦蛑幸訡MD、AMD或者window/global全局等方式進(jìn)行使用,那就可以通過(guò)配置externals
第二步:在index.html中添加cdn
<link href="https://cdn.bootcss.com/element-ui/2.7.2/theme-chalk/index.css" rel="stylesheet"></head><body><div id="app"></div><script src="https://cdn.bootcss.com/vue/2.6.10/vue.min.js"></script><script src="https://cdn.bootcss.com/vuex/3.1.0/vuex.min.js"></script><script src="https://cdn.bootcss.com/vue-router/3.0.4/vue-router.min.js"></script><script src="https://cdn.bootcss.com/axios/0.18.0/axios.min.js"></script><script src="https://cdn.bootcss.com/element-ui/2.7.2/index.js"></script><script src="https://cdn.bootcss.com/jquery/3.4.0/jquery.min.js"></script><script src="https://cdn.bootcss.com/underscore.js/1.9.1/underscore-min.js"></script></body>
第三步:去除vue.use相關(guān)代碼
通過(guò) CDN 引入,在使用 VueRouter Vuex ElementUI 的時(shí)候要改下寫(xiě)法。CDN會(huì)把它們掛載到window上,可以不再使用Vue.use(xxx)
main.js中 注釋掉
// import Vue from 'vue';
// import iView from 'iview';
// import '../theme/index.less';
4.禁止生成map文件
在vue.config.js配置:
module.exports = {productionSourceMap: false, // 生產(chǎn)環(huán)境是否生成 sourceMap 文件,一般情況不建議打開(kāi)
}
在設(shè)置了productionSourceMap: false之后,就不會(huì)生成map文件,map文件的作用在于:項(xiàng)目打包后,代碼都是經(jīng)過(guò)壓縮加密的,如果運(yùn)行時(shí)報(bào)錯(cuò),輸出的錯(cuò)誤信息無(wú)法準(zhǔn)確得知是哪里的代碼報(bào)錯(cuò)。也就是說(shuō)map文件相當(dāng)于是查看源碼的一個(gè)東西。如果不需要定位問(wèn)題,并且不想被看到源碼,就把productionSourceMap 置為false,既可以減少包大小,也可以加密源碼。
5.去掉代碼中的console和debugger
打包之后控制臺(tái)很干凈,部署正式環(huán)境之前最好這樣做。vue-cli3.0
configureWebpack: config => {if (process.env.NODE_ENV === 'production') {config.optimization.minimizer[0].options.terserOptions.compress.warnings = falseconfig.optimization.minimizer[0].options.terserOptions.compress.drop_console = trueconfig.optimization.minimizer[0].options.terserOptions.compress.drop_debugger = trueconfig.optimization.minimizer[0].options.terserOptions.compress.pure_funcs = ['console.log']}},
uglifyOptions去除console來(lái)減少文件大小
// 安裝uglifyjs-webpack-plugin
cnpm install uglifyjs-webpack-plugin --save-dev// 修改vue.config.jsconfigureWebpack: config => {if (isProduction) {.....config.plugins.push(new UglifyJsPlugin({uglifyOptions: {compress: {warnings: false,drop_debugger: true,drop_console: true,},},sourceMap: false,parallel: true,}) )}}
6.?預(yù)渲染配置
使用插件:prerender-spa-plugin?
vue.config.js中配置如下:
const PrerenderSpaPlugin = require('prerender-spa-plugin');
const Render = PrerenderSpaPlugin.PuppeteerRenderer;
const path = require('path');configureWebpack: () => {if (process.env.NODE_ENV !== 'production') return;return {plugins: [new PrerenderSPAPlugin({// 生成文件的路徑,也可以與webpakc打包的一致。// 下面這句話非常重要!!!// 這個(gè)目錄只能有一級(jí),如果目錄層次大于一級(jí),在生成的時(shí)候不會(huì)有任何錯(cuò)誤提示,在預(yù)渲染的時(shí)候只會(huì)卡著不動(dòng)。staticDir: path.join(__dirname, 'dist'),// 對(duì)應(yīng)自己的路由文件,比如a有參數(shù),就需要寫(xiě)成 /a/param1。routes: ['/', '/Login', '/Home'],// 這個(gè)很重要,如果沒(méi)有配置這段,也不會(huì)進(jìn)行預(yù)編譯renderer: new Renderer({inject: {foo: 'bar'},headless: false,// 在 main.js 中 document.dispatchEvent(new Event('render-event')),兩者的事件名稱要對(duì)應(yīng)上。renderAfterDocumentEvent: 'render-event'})})]};
}
7.圖片資源的壓縮、icon資源使用雪碧、代碼壓縮
嚴(yán)格說(shuō)來(lái)這一步不算在編碼技術(shù)范圍內(nèi),但是卻對(duì)頁(yè)面的加載速度影響很大。對(duì)于所有的圖片文件,都可以在一個(gè)叫tinypng的網(wǎng)站上去壓縮一下。網(wǎng)址:tinypng.com/,對(duì)頁(yè)面上使用到的icon,可以使用在線字體圖標(biāo),或者雪碧圖,將眾多小圖標(biāo)合并到同一張圖上,用以減輕http請(qǐng)求壓力。然后通過(guò)操作CSS的background屬性,控制背景的位置以及大小,來(lái)展示需要的部分。
// 圖片壓縮設(shè)置chainWebpack: config => {// 圖片打包壓縮,使用了 --- image-webpack-loader --- 插件對(duì)圖片進(jìn)行壓縮config.module.rule('images').use('image-webpack-loader').loader('image-webpack-loader').options({ bypassOnDebug: true }).end()},
js代碼壓縮- - - -(webpack 自UglifyJsPlugin插件壓縮js文件)
css 代碼壓縮- - - - (采用optimize-css-assets-webpack-plugin插件來(lái)壓縮css代碼)
8. 前端頁(yè)面代碼層面的優(yōu)化
-
合理使用v-if和v-show
-
合理使用watch和computed
-
使用v-for必須添加key, 最好為唯一id, 避免使用index, 且在同一個(gè)標(biāo)簽上,v-for不要和v-if同時(shí)使用
-
定時(shí)器的銷(xiāo)毀。可以在beforeDestroy()生命周期內(nèi)執(zhí)行銷(xiāo)毀事件;也可以使用$once這個(gè)事件偵聽(tīng)器,在定義定時(shí)器事件的位置來(lái)清除定時(shí)器。詳細(xì)見(jiàn)vue官網(wǎng)
-
長(zhǎng)列表性能優(yōu)化
- 圖片資源懶加載
9.解決白屏,體驗(yàn)優(yōu)化
?上邊已經(jīng)講述了優(yōu)化問(wèn)題,把 所 有 的 優(yōu) 化 都 做 完 之 后 , 加 載 速 度 有 了 顯 著 提 升,把所有的優(yōu)化都做完之后,加載速度有了顯著提升}把所有的優(yōu)化都做完之后,加載速度有了顯著提升把所有的優(yōu)化都做完之后,加載速度有了顯著提升,但是再網(wǎng)慢的時(shí)候還是會(huì)有白屏,所以再白屏期間加骨架屏和loading就顯得格外重要了。
<body>//這里親測(cè)有效,放心使用<div id="app">// 我們只需要再這里添加loading圖或者骨架屏,有人會(huì)說(shuō)怎么控制它的顯示隱藏啊,//不用擔(dān)心,再項(xiàng)目初始化完成后會(huì)自動(dòng)替換為你的頁(yè)面。<div class="self-loading">頁(yè)面正快馬加鞭趕來(lái),請(qǐng)耐心等待</div></div>
</body>