前端性能優化-Vue代碼層面


 

1、v-if 和 v-show 區分使用場景
  v-if 是 真正 的條件渲染,因為它會確保在切換過程中條件塊內的事件監聽器和子組件適當地被銷毀和重建;也是惰性的:如果在初始渲染時條件為假,則什么也不做——直到條件第一次變為真時,才會開始渲染條件塊。
  v-show 就簡單得多, 不管初始條件是什么,元素總是會被渲染,並且只是簡單地基於 CSS 的 display 屬性進行切換。
  所以,v-if 適用於在運行時很少改變條件,不需要頻繁切換條件的場景;v-show 則適用於需要非常頻繁切換條件的場景。
2、computed 和 watch 區分使用場景
  computed:**是計算屬性,依賴其它屬性值,並且 computed 的值有緩存,只有它依賴的屬性值發生改變,下一次獲取 computed 的值時才會重新計算 computed 的值;
  watch:**更多的是「觀察」的作用,類似於某些數據的監聽回調 ,每當監聽的數據變化時都會執行回調進行后續操作;
  運用場景:
  當我們需要進行數值計算,並且依賴於其它數據時,應該使用 computed,因為可以利用 computed 的緩存特性,避免每次獲取值時,都要重新計算;當我們需要在數據變化時執行異步或開銷較大的操作時,應該使用 watch,使用 watch 選項允許我們執行異步操作 ( 訪問一個 API ),限制我們執行該操作的頻率,並在我們得到最終結果前,設置中間狀態。這些都是計算屬性無法做到的。

3、v-for 遍歷必須為 item 添加 key,且避免同時使用 v-if
(1)v-for 遍歷必須為 item 添加 key
  在列表數據進行遍歷渲染時,需要為每一項 item 設置唯一 key 值,方便 Vue.js 內部機制精准找到該條列表數據。當 state 更新時,新的狀態值和舊的狀態值對比,較快地定位到 diff 。
(2)v-for 遍歷避免同時使用 v-if
  v-for 比 v-if 優先級高,如果每一次都需要遍歷整個數組,將會影響速度,尤其是當之需要渲染很小一部分的時候,必要情況下應該替換成 computed 屬性。

//推薦:
<ul>
  <li
    v-for="user in activeUsers"
    :key="user.id">
    {{ user.name }}
  </li>
</ul>
computed: {
  activeUsers: function () {
    return this.users.filter(function (user) {
     return user.isActive
    })
  }
}
//不推薦:
<ul>
  <li
    v-for="user in users"
    v-if="user.isActive"
    :key="user.id">
    {{ user.name }}
  </li>
</ul>

4、利用凍結數據
  Vue 會通過 Object.defineProperty 對數據進行劫持,來實現視圖響應數據的變化,然而有些時候我們的組件就是純粹的數據展示,不會有任何改變,我們就不需要 Vue 來劫持我們的數據,在大量數據展示的情況下,這能夠很明顯的減少組件初始化的時間,那如何禁止 Vue 劫持我們的數據呢?可以通過 Object.freeze 方法來凍結一個對象,一旦被凍結的對象就再也不能被修改了。

export default {
  data: () => ({
    users: {}
  }),
  async created() {
    const users = await axios.get("/api/users");
    this.users = Object.freeze(users);
  }
};

5、事件的銷毀
  Vue 組件銷毀時,會自動清理它與其它實例的連接,解綁它的全部指令及事件監聽器,但是僅限於組件本身的事件。 如果在 js 內使用 addEventListene 等方式是不會自動銷毀的,我們需要在組件銷毀時手動移除這些事件的監聽,以免造成內存泄露,如:

created() {
  addEventListener('click', this.click, false)
},
beforeDestroy() {
  removeEventListener('click', this.click, false)
}

6、圖片資源懶加載
  對於圖片過多的頁面,為了加速頁面加載速度,所以很多時候我們需要將頁面內未出現在可視區域內的圖片先不做加載, 等到滾動到可視區域后再去加載。這樣對於頁面加載性能上會有很大的提升,也提高了用戶體驗。我們在項目中使用 Vue 的 vue-lazyload 插件:

7、路由懶加載
  Vue 是單頁面應用,可能會有很多的路由引入 ,這樣使用 webpcak 打包后的文件很大,當進入首頁時,加載的資源過多,頁面會出現白屏的情況,不利於用戶體驗。如果我們能把不同路由對應的組件分割成不同的代碼塊,然后當路由被訪問的時候才加載對應的組件,這樣就更加高效了。這樣會大大提高首屏顯示的速度,但是可能其他的頁面的速度就會降下來。
路由懶加載:

const Foo = () => import('./Foo.vue')
const router = new VueRouter({
  routes: [
    { path: '/foo', component: Foo }
  ]
})

8、第三方插件的按需引入
  我們在項目中經常會需要引入第三方插件,如果我們直接引入整個插件,會導致項目的體積太大,我們可以借助 babel-plugin-component ,然后可以只引入需要的組件,以達到減小項目體積的目的。以下為項目中引入 element-ui 組件庫為例:

(1)首先,安裝 babel-plugin-component :

npm install babel-plugin-component -D

(2)然后,將 .babelrc 修改為:

{
  "presets": [["es2015", { "modules": false }]],
  "plugins": [
    [
      "component",
      {
        "libraryName": "element-ui",
        "styleLibraryName": "theme-chalk"
      }
    ]
  ]
}

(3)在 main.js 中引入部分組件:

import Vue from 'vue';
import { Button, Select } from 'element-ui';

Vue.use(Button)
Vue.use(Select)

9、優化無限列表性能
  如果你的應用存在非常長或者無限滾動的列表,那么需要采用 窗口化 的技術來優化性能,只需要渲染少部分區域的內容,減少重新渲染組件和創建 dom 節點的時間。 你可以參考以下開源項目 vue-virtual-scroll-list 和 vue-virtual-scroller 來優化這種無限列表的場景的。

10、服務端渲染 SSR or 預渲染
  服務端渲染是指 Vue 在客戶端將標簽渲染成的整個 html 片段的工作在服務端完成,服務端形成的 html 片段直接返回給客戶端這個過程就叫做服務端渲染。
(1)服務端渲染的優點:
  更好的 SEO: 因為 SPA 頁面的內容是通過 Ajax 獲取,而搜索引擎爬取工具並不會等待 Ajax 異步完成后再抓取頁面內容,所以在 SPA 中是抓取不到頁面通過 Ajax 獲取到的內容;而 SSR 是直接由服務端返回已經渲染好的頁面(數據已經包含在頁面中),所以搜索引擎爬取工具可以抓取渲染好的頁面;

  更快的內容到達時間(首屏加載更快): SPA 會等待所有 Vue 編譯后的 js 文件都下載完成后,才開始進行頁面的渲染,文件下載等需要一定的時間等,所以首屏渲染需要一定的時間;SSR 直接由服務端渲染好頁面直接返回顯示,無需等待下載 js 文件及再去渲染等,所以 SSR 有更快的內容到達時間;

(2)服務端渲染的缺點:
  更多的開發條件限制: 例如服務端渲染只支持 beforCreate 和 created 兩個鈎子函數,這會導致一些外部擴展庫需要特殊處理,才能在服務端渲染應用程序中運行;並且與可以部署在任何靜態文件服務器上的完全靜態單頁面應用程序 SPA 不同,服務端渲染應用程序,需要處於 Node.js server 運行環境;

更多的服務器負載:在 Node.js 中渲染完整的應用程序,顯然會比僅僅提供靜態文件的 server 更加大量占用CPU 資源,因此如果你預料在高流量環境下使用,請准備相應的服務器負載,並明智地采用緩存策略。


 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM