国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

淺談Vue 初始化性能優化

2019-11-19 15:35:43
字體:
來源:轉載
供稿:網友

前言

一般來說,你不需要太關心vue的運行時性能,它在運行時非常快,但付出的代價是初始化時相對較慢。在最近開發的一個Hybrid APP里,Android Webview初始化一個較重的vue頁面竟然用了1200ms ~ 1400ms,這讓我開始重視vue的初始化性能,并最終優化到200 ~ 300ms,這篇文章分享我的優化思路。

性能瓶頸在哪里?

先看一下常見的vue寫法:在html里放一個app組件,app組件里又引用了其他的子組件,形成一棵以app為根節點的組件樹。

<body>  <app></app> </body>

而正是這種做法引發了性能問題,要初始化一個父組件,必然需要先初始化它的子組件,而子組件又有它自己的子組件。那么要初始化根標簽<app>,就需要從底層開始冒泡,將頁面所有組件都初始化完。所以我們的頁面會在所有組件都初始化完才開始顯示。

這個結果顯然不是我們要的,更好的結果是頁面可以從上到下按順序流式渲染,這樣可能總體時間增長了,但首屏時間縮減,在用戶看來,頁面打開速度就更快了。

要實現這種渲染模式,我總結了下有3種方式實現。第3種方式是我認為最合適的,也是我在項目中實際使用的優化方法。

第一種:不使用根組件

這種方式非常簡單,例如:

<body>  <A></A>  <B></B>  <C></C></body>

拋棄了根組件<app>,從而使A、B、C每一個組件初始化完都立刻展示。但根組件在SPA里是非常必要的,所以這種方式只適用小型頁面。

第二種:異步組件

異步組件在官方文檔已有說明,使用非常簡單:

<app>  <A></A>  <B></B></app>
new Vue({  components: {    A: { /*component-config*/ },    B (resolve) {      setTimeout(() => {        resolve({ /*component-config*/ })      }, 0);    }  }})

這里<B>組件是一個異步組件,會等到手動調用resolve函數時才開始初始化,而父組件<app>也不必等待<B>先初始化完。

我們利用setTimeout(fn, 0)將<B>的初始化放在隊列最后,結果就是頁面會在<A>初始化完后立刻顯示,然后再顯示<B>。如果你的頁面有幾十個組件,那么把非首屏的組件全設成異步組件,頁面顯示速度會有明顯的提升。

你可以封裝一個簡單的函數來簡化這個過程:

function deferLoad (component, time = 0) {  return (resolve) => {    window.setTimeout(() => resolve(component), time)  };}new Vue({  components: {    B: deferLoad( /*component-config*/ ),    // 100ms后渲染    C: deferLoad( /*component-config*/, 100 )  }})

看起來很美好,但這種方式也有問題,考慮下這樣的結構:

<app>  <title></title>  <A></A>  <title></title>  <B></B>  <title></title>  <C></C></app>

還是按照上面的異步組件做法,這時候就需要考慮把哪些組件設成異步的了。如果把A、B、C都設成異步的,那結果就是3個<title>會首先渲染出來,頁面渲染的過程在用戶看來非常奇怪,并不是預期中的從上到下順序渲染。

第三種:v-if 和 terminal指令

這是我推薦的一種做法,簡單有效。還是那個結構,我們給要延遲渲染的組件加上v-if:

<app>  <A></A>  <B v-if="showB"></B>  <C v-if="showC"></C></app>
new Vue({  data: {    showB: false,    showC: false  },  created () {    // 顯示B    setTimeout(() => {      this.showB = true;    }, 0);    // 顯示C    setTimeout(() => {      this.showC = true;    }, 0);  }});

這個示例寫起來略顯

主站蜘蛛池模板: 泰来县| 巴林右旗| 贺州市| 南宫市| 台南县| 阿拉善左旗| 合作市| 江陵县| 林芝县| 峨边| 明光市| 乐至县| 东海县| 林口县| 商洛市| 沿河| 贡觉县| 达日县| 六枝特区| 荣成市| 虞城县| 兴宁市| 广水市| 蒙阴县| 和田市| 林口县| 镇康县| 瑞金市| 肃宁县| 黎川县| 吴忠市| 平乡县| 建湖县| 舒城县| 海盐县| 远安县| 永昌县| 泊头市| 唐河县| 巴林右旗| 土默特右旗|