摘要:如果我們能把不同路由對應的組件分割成不同的代碼塊,然后當路由被訪問的時候才加載對應組件,這樣就更加高效了。
前言
之前用vuecli做了個博客,是一個單頁面項目,大概有十個路由
直接npm run build打包出來,有一個1M的巨大js文件
先掛載到服務器上試試
好家伙 這加載時間 仿佛過了半個世紀
首屏頁面整整加載了9s 光加載那個大文件就花了8s
這必須得做個優化了,沒有用戶能忍受9s的白屏而不關閉頁面的
過程中,我還順便把項目從vuecli 2.x遷移到了vuecli 3,所以接下來還會介紹一些它們在優化上的異同
分析vuecli 2.x自帶了分析工具
只要運行npm run build --report
如果是vuecli 3的話,先安裝插件
cnpm intall webpack-bundle-analyzer –save-dev
然后在vue.config.js中對webpack進行配置
chainWebpack: (config) => { /* 添加分析工具*/ if (process.env.NODE_ENV === "production") { if (process.env.npm_config_report) { config .plugin("webpack-bundle-analyzer") .use(require("webpack-bundle-analyzer").BundleAnalyzerPlugin) .end(); config.plugins.delete("prefetch") } } }
再運行npm run build --report
會在瀏覽器打開一個項目打包的情況圖,便于直觀地比較各個bundle文件的大小
可以看到 項目中所有的依賴,所有的路由,都被打包進了同一個文件中
另外,在瀏覽器中,也可以通過converge來查看代碼的使用狀況
紅色的是下載了但未使用的部分
當打包構建應用時,JavaScript包會變得非常大,影響頁面加載。
如果我們能把不同路由對應的組件分割成不同的代碼塊,然后當路由被訪問的時候才加載對應組件,這樣就更加高效了。
在一開始就下載完所有路由對應的組件文件,這明顯是不合適的,這就像下載一個app了,所以我們就需要使用路由懶加載
在router.js文件中,原來的靜態引用方式
import ShowBlogs from "@/components/ShowBlogs" routes:[ path: "Blogs", name: "ShowBlogs", component: ShowBlogs ]
改為
routes:[ path: "Blogs",name: "ShowBlogs",component: () => import("./components/ShowBlogs.vue")
以函數的形式動態引入,這樣就可以把各自的路由文件分別打包,只有在解析給定的路由時,才會下載路由組件
首屏需要加載的文件變成了橙色的部分,被小弟們分流出去了300k
如果是在vuecli 3中,我們還需要多做一步工作
因為vuecli 3默認開啟prefetch(預先加載模塊),提前獲取用戶未來可能會訪問的內容
在首屏會把這十幾個路由文件,都一口氣下載了
所以我們要關閉這個功能,在vue.config.js中設置
參考官網的做法:
設置完畢后,首屏就只會加載當前頁面路由的組件了
element-ui按需加載首屏需要加載的依賴包,其中element-ui整整占了568k
原本的引進方式引進了整個包:
import ElementUI from "element-ui" Vue.use(ElementUI)
但實際上我用到的組件只有按鈕,分頁,表格,輸入與警告
所以我們要按需引用:
import { Button, Input, Pagination, Table, TableColumn, MessageBox } from "element-ui"; Vue.use(Button) Vue.use(Input) Vue.use(Pagination) Vue.prototype.$alert = MessageBox.alert
注意MessageBox注冊方法的區別,并且我們雖然用到了alert,但并不需要引入Alert組件
在.babelrc文件中添加(vue-cli 3要先安裝babel-plugin-component):
plugins: [ [ "component", { "libraryName": "element-ui", "styleLibraryName": "theme-chalk" } ] ]
element-ui小了很多,不過看到那個顯眼的table.js后想到,table組件只有后臺管理頁面用到了,不需要全局注冊,所以我們刪除main.js中Table和TablColumn的引用,并在后臺組件中局部注冊
import { Table, TableColumn } from "element-ui"; components: { "el-table": Table, "el-table-column": TableColumn },
table就被拆分到了路由文件中
可以看到上圖,有兩個路由文件都引用了codemirror.js造成重復下載
我們可以在webpack的config文件中,修改CommonsChunkPlugin的配置
minChunks: 3
把3改為2,就會把使用2次及以上的包抽離出來,放進公共依賴文件,不過由于首頁也有復用的組件,所以首頁也會下載這個公共依賴文件
首頁下載了黃色和灰色部分
拆了半天,又回到原點
當然,我們可以繼續折騰CommonsChunkPlugin的配置來解決這個問題
但在新版webpack中,CommonsChunkPlugin被自由度更高,更高級的SplitChunksPlugin代替
這也是為什么我要把項目遷移到vuecli 3(使用webpack4)
默認就做了優化,首頁只會下載灰色的部分(235K)
拆完包之后,我們再用gzip做一下壓縮
安裝compression-webpack-plugin
cnmp i compression-webpack-plugin -D
在vue.congig.js中引入并修改webpack配置
const CompressionPlugin = require("compression-webpack-plugin") configureWebpack: (config) => { if (process.env.NODE_ENV === "production") { // 為生產環境修改配置... config.mode = "production" return { plugins: [new CompressionPlugin({ test: /.js$|.html$|.css/, //匹配文件名 threshold: 10240, //對超過10k的數據進行壓縮 deleteOriginalAssets: false //是否刪除原文件 })] } }
可以看到200k以上的文件被壓縮到了100k以內
在服務器我們也要做相應的配置
如果發送請求的瀏覽器支持gzip,就發送給它gzip格式的文件
我的服務器是用express框架搭建的
只要安裝一下compression就能使用
const compression = require("compression") app.use(compression())
注意,后面這一句,要放在所有其他中間件注冊之前
最終效果
首屏加載資源198k,加載時間1s,相比原來速度提升了90%
vuecli 3和vuecli2.x還有一個區別是
vuecli 3會默認開啟一個css分離插件 ExtractTextPlugin
每一個模塊的css文件都會分離出來,整整13個css文件,而我們的首頁就請求了4個,花費了不少的資源請求時間
我們可以在vue.config.js中關閉它
css: { // 是否使用css分離插件 ExtractTextPlugin extract: false, // 開啟 CSS source maps? sourceMap: false, // css預設器配置項 loaderOptions: {}, // 啟用 CSS modules for all css / pre-processor files. modules: false },
打包出來的文件中,直接就沒有了css文件夾
取而代之的是整合起來的一個js文件,負責在一開始就注入所有的樣式
首屏加載文件數減少,但體積變大,最終測下來速度沒有太大差異
所以,是否要css拆分就見仁見智,具體項目具體分析吧
性能優化是一個非常令人愉悅的過程,同時也是個深坑,有著太多東西,本篇文章開了個頭,希望能對大家有所幫助
參考文章Vue打包優化之code spliting
https://juejin.im/post/5ac815...
Vue 性能優化:如何實現延遲加載和代碼拆分?
https://www.infoq.cn/article/...*zN
Webpack 打包優化之體積篇
https://www.jeffjade.com/2017...
記一次vue+element+echarts項目的優化
https://juejin.im/post/5b0033...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/104757.html
摘要:性能統計有助于幫我們檢測網站的用戶體驗。這樣,我們就輕輕松松的統計到了首屏時間。下一章,我們將繼續聊聊百度移動版首頁那些事。 歡迎大家收看聊一聊系列,這一套系列文章,可以幫助前端工程師們了解前端的方方面面(不僅僅是代碼): https://segmentfault.com/blog/frontenddriver 上一篇文章我們討論了,如何進行前端日志打點統計: https://segm...
摘要:性能統計有助于幫我們檢測網站的用戶體驗。這樣,我們就輕輕松松的統計到了首屏時間。下一章,我們將繼續聊聊百度移動版首頁那些事。 歡迎大家收看聊一聊系列,這一套系列文章,可以幫助前端工程師們了解前端的方方面面(不僅僅是代碼): https://segmentfault.com/blog/frontenddriver 上一篇文章我們討論了,如何進行前端日志打點統計: https://segm...
摘要:目標是探索是否能夠加快頁面首屏速度。實驗組瀏覽器支持,本次時,進行初始化。從上面的直觀對比可以看出,個指標,組的分位值都略微大于組的分位值,差距在幾十毫秒左右。最終,我也沒有采用來優化首屏速度。 寫在前面 本文首發于公眾號:符合預期的CoyPan 不久之前,我簡單探索了service worker在一個活動運營頁面中的應用,可以參考我之前的這篇文章: service worker輕度探...
摘要:而渲染帶來的性能問題主要是由于數據接口請求返回以及前端資源獲取所帶來的網絡問題。本地化實現由于我們的這面是純渲染的,所以我們一個最終的詳情頁主要是由新聞數據和靜態頁面兩者構成的。 showImg(https://segmentfault.com/img/remote/1460000019904452?w=900&h=383); 開篇之前先介紹一下場景。信息流是一個基于用戶興趣使用算法將...
閱讀 3412·2023-04-25 20:37
閱讀 3153·2021-09-07 09:59
閱讀 1676·2019-08-29 12:43
閱讀 1195·2019-08-28 18:27
閱讀 489·2019-08-26 13:50
閱讀 2045·2019-08-26 10:33
閱讀 3602·2019-08-23 18:39
閱讀 2414·2019-08-23 18:09