LINE Corporation 於2023年10月1日成爲 LY Corporation。LY Corporation 的新部落格在這裏。LY Corporation Tech Blog

Blog


具有改進的 LINE MUSIC 性能的 Vue3 升級

譯者註解: 這裡指的 LINE MUSIC 在日本上線的產品 。

大家好,我是柴阪浩行 (Shibasaka Hiroyuki),在LINE的京都開發工程團隊負責前端的開發。

大家在工作的時候用電腦聽音樂嗎?

LINE MUSIC 不僅有手機版本 App,還有 Web 版網站應用。
我們開發的 Web 版網站應用使用 Vue.js 作爲 JS 框架。

https://music.line.me/webapp/

到目前爲止,這個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 相關流程

  1. 升級 vue-cli、Vue.js
  2. @vue/compat 安裝和啓用兼容模式
  3. 支持webpack-dev-server設定的版本變更
  4. 修復編譯錯誤

由於 @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) 開發有興趣的朋友,也可以參考以下職缺: