譯者註解: 這裡指的 LINE MUSIC 在日本上線的產品 。
大家好,我是柴阪浩行 (Shibasaka Hiroyuki),在LINE的京都開發工程團隊負責前端的開發。
大家在工作的時候用電腦聽音樂嗎?
LINE MUSIC 不僅有手機版本 App,還有 Web 版網站應用。
我們開發的 Web 版網站應用使用 Vue.js 作爲 JS 框架。
到目前爲止,這個Web版本的網站應用使用的是Vue2,
2022 年 6 月,我們發佈了升級到 Vue 3 的版本。
我們的團隊在開發Web版網站應用的功能的同時,也致力於提高性能。性能方面也有很多方面,其中 package 檔案的肥大化是最大的課題。構成應用程序的js和css的 package 大小爲6MB,使用名爲Sentry的監控工具測量對Web版網站應用的訪問量時,顯示時間超過2秒的訪問量約佔一半。
我們進行了重構、整理依存套件等,致力於縮小檔案。其中,我們研究了我們網站用最多的 Vue.js,發現升級到 Vue3 可以減少整體的檔案大小。 遷移到 Vue3 本身已計劃就緒,以便將來部署 TypeScript,因此我們決定優先執行此計劃。
這篇報道將一邊回顧如何進行移植作業,以及他們在什麼地方下了功夫,一邊寫下去。此外,我們還將結合性能方面的結果進行介紹,這些性能方面的實際改進非常顯著。
使用「遷移構建」進行升級
升級到 Vue 3 需要進行許多更改,很難一步到位。
值得慶幸的是,在 Vue3 中,名爲 @vue/compat 的套件提供了兼容模式,稱爲"遷移構建" ("the migration build")。通過在升級 Vue.js 的同時安裝遷移版本,您可以在最低限度的調整下運行 Vue3。此外,文檔 (en) 中還列出了所需的更改,以便可以順利地開始遷移工作。
包含遷移版本時,需要修改的部分將顯示爲錯誤或警告。通過解決這些問題,可以毫無猶豫地進行遷移作業。
在升級到 Vue 3 時,您還需要升級許多相依的套件。這次多虧了遷移構建,我們才能逐一進行升級,一邊確認運行情況一邊進行工作。
Step 1 首先升級到 Vue 3 相關流程
- 升級 vue-cli、Vue.js
- @vue/compat 安裝和啓用兼容模式
- 支持webpack-dev-server設定的版本變更
- 修復編譯錯誤
由於 @vue/cli-service 升級會將 webpack-dev-server 版本從 v3 更改爲 v4,因此可能需要更改相關設定。
此外,由於相依的套件中有些套件已停止維護,因此我們還進行了升級。由於主要版本號碼的更改,需要進行較大的設置更改,因此花費了很長時間。到處都需要這樣的應對。
至此 , 暫時可通過 Dev Server 來做相關的升級測試 。
Step 2 對應主要規格變更
在此,移植文檔要求以下2處對應。
<transition>
相關類別名稱變更的修改- 支持新的全局安裝 API
<transition>
的類別名稱在文檔中也有記載,但不會作爲錯誤出現,因此要提前進行更改,以免忘記。
另一個新的全局掛載 API 要求對每個 API 進行大量更改,因爲有些方法已更改或已刪除。
此外,由於 Vue I18n 在此時間不再維護了,因此進行了升級。Vue I18n 的移植也提供官方文檔,供您參考。
順便說一下,在設置 props 的預設值時,Vue3 無法使用 this 作爲 Vue 實例,因此,如果使用以下方法調用 Vue I18n 文本,則需要進行更改:
props: {
title: {
type: String,
default() {
return this.$t('title'); // It will not work
},
},
}
Step 3 升級關鍵套件
然後升級 Vuex 和 Vue-router。
剛開始印象最深的是這裏,但只要不做特別的事情,就很容易升級。除了文檔中的說明之外,不需要進行任何更改。
Step 4 修復錯誤並升級相依套件
然後 , 從此逐個消除剩餘的錯誤和警告 。
您可能會覺得您已經完成了大部分工作,因爲您已經完成了重大更改,而且每次升級依賴性套件時,您可能會覺得您已經完成了大部分工作。但是實際上,從這裏開始的工作需要花費很長的時間,因爲有些東西必須找出原因。到目前爲止,只有大約一天的工作時間,而錯誤和測試修復的總時間大約爲 6 天。順便說一下,因爲實際上也在推進其他的項目,所以作爲時間整體花費了1個月的時間。
在找到需要升級的相關軟件包或在瀏覽器中運行之前,有些軟件包不會出現錯誤。在此移植中,"從出現錯誤的套件開始依次升級"的方針完全沒有問題。這樣想的話,不就可以輕鬆地開始工作了嗎?
首先消除 terminator上顯示的警告(錯誤到此爲止已消除),然後消除瀏覽器控制檯的警告和錯誤。瀏覽器錯誤當然會因頁面和組件而異,並且會按每個 js 顯示使用位置,以查看其行爲並找出問題所在。
執行時發生的錯誤中 , 某些變更後會發生錯誤 , 因此仔細的提交非常重要 。因爲那樣的話容易判斷原因,所以我覺得能夠回到任何階段是非常好的。
Step 5 修改測試
最後修復了測試程式碼。
我在這個項目中使用 Vue Testing Library 我還需要升級 Vue3,但沒有關於遷移的文章。截至 2022 年 4 月,當我在開發它時,Vue3 的版本在下一個分支中,我通過閱讀其中的原始碼和範例程式碼來收集信息。
一個特別大的變化是對 Vuex 和 Vue-router 的處理。
到目前為止,每個實例都是在 render 函數中創建的,您可以在 render 函數的第三個參數中將其與 vue 實例一起處理。
https://github.com/testing-library/vue-testing-library/blob/96c0c2d/src/render.js#L30-L43
此版本已棄用此功能,因此您需要創建自己的 Vuex 和 Vue-router 實例。
https://github.com/testing-library/vue-testing-library/blob/03c53e1/src/render.js#L22-L26
我們為渲染創建了一個包裝函數並為它編寫了一個單元測試,但讓我們看看我們如何改變它。
修改前
export const initAndRender = (TestComponent, options, configure) => {
return render(TestComponent, options, (vue, store, router) => {
/* common settings */
const addtionalResponse = configure ? configure(vue, store, router) : {};
return { ...(addtionalResponse ? addtionalResponse : {}) };
});
};
修改後
export const initAndRender = (TestComponent, options) => {
const global = options?.global || {};
const plugins = global?.plugins || [];
/* common settings */
// vuex
if ('store' in options) {
const storeInstance = createStore(options.store);
plugins.push(storeInstance);
delete options.store;
}
// vue-router
const router = createRouter({
history: createWebHistory(),
routes: [...(options.routes || [])],
});
plugins.push(router);
delete options.routes;
// merge options
global.plugins = plugins;
global.mocks = mocks;
options.global = global;
return { ...render(TestComponent, options), router };
};
這是程式碼修改的摘錄,但主要區別在於缺少 render 函數的第三個參數以及增加了對 Vuex 和 vue-router 的描述。為了減少測試程式碼端的更改次數,我們讓小幅改動後可以繼續使用 store 和 routes 選項,並在包裝函數端創建了 Vuex 和 Vue-router 實例。
另外,有一部分我使用了在 render 中生成的 Vue-router 實例,所以我將 router 連同 render 的內容一起返回,以便我可以繼續在測試中使用 router。
很高興我們最初為 render 準備了一個包裝函數,因此我們能夠吸收其中的重大變化。
除此之外,還有很多地方需要修改測試程式碼,所以我們通過反複試驗修改測試程式碼,直到所有測試通過。
第 6 步完成
最後,刪除您一直在使用的遷移構建。
如果您沒有收到任何錯誤,那麼它就是在 Vue 3 上運行的正式 Web 應用程序!
開發完成後,我們要求 QA 團隊進行回歸測試以檢查整體行為。進行這些測試很重要,因為仍然存在一些錯誤。發現的所有錯誤均已修復,現已正式發布。
改進結果 1 捆綁包大小
好吧,這裡是 Omachikane 的性能改進。
我們記錄了在引入 Vue3 和過渡構建之前和之後包大小如何變化,以及何時移除過渡構建。
首先,我比較了在開發模式下構建時的包大小。
圖表從左到右是
- 遷移工作前
- [Step1] 引入Vue3和遷移構建後立即
- [Step6] 遷移工作後的比較(刪除遷移構建)。
Central 剛剛升級到 Vue3,他們的大小減半,當我向團隊報告這個結果時,他們大吃一驚。完成遷移工作後,移除遷移構建並成為純 Vue 3 應用程序進一步減小了包大小。
接下來是生產模式下的構建結果。
開發模式下,js中的css是外化的,所以文件配置略有不同。
無論它在引入遷移構建期間的行為是否像 Vue 2 一樣,都與遷移工作之前幾乎相同。另一方面,刪除遷移構建並成為純 Vue 3 應用程序將包大小減少了一半。
改進結果 2 頁面顯示速度及其得分
除了 Vue3,我們還推進了 Vite 的引入。Vite 是 webpack 的前端替代品,擁有快速的開發服務器。編譯器也很強大,可以輸出為每個組件分段的文件。由於只加載訪問頁面所需的文件,因此可以進一步提高頁面加載速度。
當我們發布一個包含 Vue 3 和 Vite 引入的版本時,我們決定將其與 Google Lighthouse 上的先前版本進行比較。結果,性能得分從 44 顯著提高到 65。
不是Vue2和Vue3的純粹對比,但效果似乎很棒。
此外,以下爲顯示通過Sentry測量的首頁所需的時間。圖表清楚地顯示,從 Release 之後,頁面顯示時間實際減少了一半。現在,75%的用戶可以在兩秒鐘內查看。
最後
我們部署了Vue3以提高性能,但我們計劃部署Composition API和TypeScript,並希望進一步利用Vue3。今後將繼續致力於重構和改善 , 推進LINE MUSIC的Web版應用程序的開發 。
LINE京都開發室正在招募一起工作的前端工程師。
如果您想在京都工作,並且對團隊中的前端開發和產品改進感興趣,
有沒有興趣加入我們和我們一起開發?
https://linecorp.com/ja/career/position/1659
譯者註解:
如果對於台灣的 UIT (Front-end) 開發有興趣的朋友,也可以參考以下職缺: