前言
Vue 框架通過數據雙向綁定和虛擬 DOM 技術,幫我們處理了前端開發中最臟最累的 DOM 操作部分, 我們不再需要去考慮如何操作 DOM 以及如何最高效地操作 DOM;但 Vue 項目中仍然存在項目首屏優化、Webpack 編譯配置優化等問題,所以我們仍然需要去關注 Vue 項目性能方面的優化,使項目具有更高效的性能、更好的用戶體驗。接下來我們提供一些 vue 性能優化的方法。
1、路由懶加載
Vue 是單頁面應用,可能會有很多的路由引入 ,這樣使用 webpcak 打包后的文件很大,當進入首頁時,加載的資源過多,頁面會出現白屏的情況,不利於用戶體驗。
如果我們能把不同路由對應的組件分割成不同的代碼塊,然后當路由被訪問的時候才加載對應組件,這樣就要更加高效了。
這是什么意思呢?
- 首先,我們知道路由中通常會定義很多不同的頁面
- 這個頁面最后被打包在哪里呢?一般情況下,是放在一個 js 文件中
- 但是,頁面這么多放在一個 js 文件中,必然會造成這個頁面非常大
- 如果我們一次性從服務器請求下來這個頁面,可能需要花費一定的時間,甚至用戶的電腦上還出現了短暫空白的情況
- 那么如何避免這種情況呢?使用路由懶加載就可以了
那么,路由懶加載做了什么?
- 路由懶加載的主要作用就是將路由對應的組件打包成一個個的 js 代碼塊
- 只有在這個路由被訪問到的時候,才加載對應的組件
在 ES6 中,懶加載的方式:
2、圖片懶加載
對於圖片過多的頁面,為了加速頁面加載速度,所以很多時候我們需要將頁面內未出現在可視區域內的圖片先不做加載, 等到滾動到可視區域后再去加載。這樣對於頁面加載性能上會有很大的提升,也提高了用戶體驗。我們在項目中使用 Vue 的 vue-lazyload 插件。
對其包裹的組件進行狀態的緩存,使其不被銷毀,避免重新渲染。
4、區分使用 v-if 和 v-show
v-if 是真正的條件渲染,因為它會確保在切換過程中條件塊內的事件監聽器和子組件適當地被銷毀和重建;也是惰性的:如果在初始渲染時條件為假,則什么也不做——直到條件第一次變為真時,才會開始渲染條件塊。
v-show 就簡單得多, 不管初始條件是什么,元素總是會被渲染,並且只是簡單地基於 CSS 的 display 屬性進行切換。
所以,v-if 適用於在運行時很少改變條件,不需要頻繁切換條件的場景;v-show 則適用於需要非常頻繁切換條件的場景。
5、區分 computed 和 watch
computed: 是計算屬性,依賴其它屬性值,並且 computed 的值有緩存,只有它依賴的屬性值發生改變,下一次獲取 computed 的值時才會重新計算 computed 的值;另外,computed 必須要有返回值。
watch: 更多的是「觀察」的作用,類似於某些數據的監聽回調 ,每當監聽的數據變化時都會執行回調進行后續操作;
應用場景:
- 當我們需要進行數值計算,並且依賴於其它數據時,應該使用 computed,因為可以利用 computed 的緩存特性,避免每次獲取值時,都要重新計算;
- 當我們需要在數據變化時執行異步或開銷較大的操作時,應該使用 watch,使用 watch 選項允許我們執行異步操作 ( 訪問一個 API ),限制我們執行該操作的頻率,並在我們得到最終結果前,設置中間狀態。這些都是計算屬性無法做到的。
6、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 屬性。
7、事件的銷毀
Vue 組件銷毀時,會自動清理它與其它實例的連接,解綁它的全部指令及事件監聽器,但是僅限於組件本身的事件。 如果在 js 內使用 addEventListener 等方式是不會自動銷毀的,我們需要在組件銷毀時手動移除這些事件的監聽,以免造成內存泄露。
8、第三方組件的按需引入
我們在項目中經常會需要引入第三方插件,如element-ui這樣的第三方組件庫,如果我們直接引入整個插件,會導致項目的體積太大,我們可以借助 babel-plugin-component ,然后可以只引入需要的組件,以達到減小項目體積的目的。
9、長列表性能優化
Vue 會通過 Object.defineProperty 對數據進行劫持,來實現視圖響應數據的變化,然而有些時候我們的組件就是純粹的數據展示,不會有任何改變,我們就不需要 Vue 來劫持我們的數據,在大量數據展示的情況下,這能夠很明顯的減少組件初始化的時間,那如何禁止 Vue 劫持我們的數據呢?使用 object.freeze(data) 方法來凍結一個對象,一旦被凍結的對象就再也不能被修改了。
如果是大數據長列表,可采用虛擬滾動,只渲染少部分區域的內容,參考vue-virtual-scroller、vue-virtual-scroll-list
10、子組件分割
子組件耗時任務,切割為獨立子樹,獨立為自己的渲染,切割為子樹 有動態內容,自己管自己的渲染不用管其它地方,多一個watcher自己管自己。
參考資料:https://blog.csdn.net/weixin_43392489/article/details/114178963