uni-app微信小程序性能優(yōu)化技巧 | 13個實用方法

2024-12-18 11:09 更新

大家好,我是威哥,在使用uni-app開發(fā)微信小程序時,性能優(yōu)化是提升用戶體驗的關(guān)鍵。今天的內(nèi)容,整理了以下13個有效的性能優(yōu)化技巧,供你在開發(fā)中參考:

1. 減少頁面層級和組件嵌套:

減少頁面層級和組件嵌套是前端性能優(yōu)化中的常見做法,它有助于減少瀏覽器的渲染負擔(dān),提高頁面的響應(yīng)速度。我們通過以下優(yōu)化前后的示例對比來說明:

優(yōu)化前:

假設(shè)我們有一個電商應(yīng)用的商品詳情頁,頁面結(jié)構(gòu)如下:

<view class="product-detail">
  <view class="product-header">
    <view class="product-title">一條瑜伽褲</view>
    <view class="product-price">¥199</view>
  </view>
  <view class="product-body">
    <view class="product-image">
      <image src="path/to/img-ku"></image>
    </view>
    <view class="product-info">
      <view class="info-item">
        <text>品牌:</text>
        <text>VG牌</text>
      </view>
      <view class="info-item">
        <text>產(chǎn)地:</text>
        <text>東莞</text>
      </view>
      <!-- 更多 info-item -->
    </view>
  </view>
  <view class="product-footer">
    <button class="buy-button">購買</button>
  </view>
</view>

在這個例子中,product-detail 下有三個直接子元素:product-header、product-bodyproduct-footer。product-body 下又嵌套了 product-imageproduct-info,而 product-info 下還有多個 info-item。

優(yōu)化后:

我們可以將一些不需要單獨樣式或行為的子元素合并到父元素中,以減少層級:

<view class="product-detail">
  <view class="product-header">
    <text class="product-title">一條瑜伽褲</text>
    <text class="product-price">¥199</text>
  </view>
  <image class="product-image" src="path/to/image"></image>
  <view class="product-info">
    <view class="info-item">
      <text>品牌:</text>
      <text>VG牌</text>
    </view>
    <view class="info-item">
      <text>產(chǎn)地:</text>
      <text>東莞</text>
    </view>
    <!-- 更多 info-item -->
  </view>
  <button class="product-footer buy-button">購買</button>
</view>

在這個優(yōu)化后的示例中,我們做了以下改動:

  1. product-titleproduct-price 直接作為 product-header 的子元素,而不是嵌套在另一個 <view> 中。
  2. product-image 不再需要嵌套在 product-body 中,可以直接作為 product-detail 的子元素。
  3. buy-button 合并到 product-footer 中,并移除了 product-footer 的嵌套。

優(yōu)化說明:

  • 減少DOM元素數(shù)量:優(yōu)化后的代碼減少了不必要的 <view> 元素,這減少了DOM樹的深度,使得瀏覽器渲染成本降低。
  • 簡化結(jié)構(gòu):簡化的頁面結(jié)構(gòu)使得維護和理解代碼變得更加容易。
  • 提高性能:較少的DOM操作和更少的重排重繪,可以提高頁面的響應(yīng)速度和流暢度。

通過這樣的優(yōu)化,我們能夠提升頁面的性能,使得用戶在使用小程序時能夠獲得更好的體驗。

2. 避免頻繁的數(shù)據(jù)更新:

避免頻繁的數(shù)據(jù)更新是提升性能的一個重要方面,特別是在數(shù)據(jù)綁定頻繁更新時,可能會導(dǎo)致頁面渲染性能問題。以下是優(yōu)化前后的示例對比說明,我們來看一下:

優(yōu)化前:

假設(shè)我們有一個商品列表頁面,每個商品項都有一個“加入購物車”的按鈕,點擊后商品數(shù)量會增加。我們可能會這樣編寫代碼:

<template>
  <view class="product-list">
    <view v-for="(product, index) in products" :key="index" class="product-item">
      <text class="product-name">{{ product.name }}</text>
      <text class="product-quantity">{{ product.quantity }}</text>
      <button @click="addToCart(product)">加入購物車</button>
    </view>
  </view>
</template>


<script>
export default {
  data() {
    return {
      products: [
        { name: '商品1-瑜伽褲', quantity: 0 },
        { name: '商品2-瑜伽衣', quantity: 0 },
        // 更多商品
      ]
    };
  },
  methods: {
    addToCart(product) {
      product.quantity += 1;
    }
  }
};
</script>

在這個例子中,每次點擊“加入購物車”按鈕,都會觸發(fā) addToCart 方法,該方法直接修改了 product.quantity 的值,導(dǎo)致視圖重新渲染。

優(yōu)化后:

我們可以優(yōu)化數(shù)據(jù)更新的方式,減少不必要的數(shù)據(jù)綁定和視圖渲染:

<template>
  <view class="product-list">
    <view v-for="(product, index) in products" :key="index" class="product-item">
      <text class="product-name">{{ product.name }}</text>
      <text class="product-quantity">{{ product.quantity }}</text>
      <button @click="addToCart(index)">加入購物車</button>
    </view>
  </view>
</template>


<script>
export default {
  data() {
    return {
      products: [
        { name: '商品1-瑜伽褲', quantity: 0 },
        { name: '商品2-瑜伽衣', quantity: 0 },
        // 更多商品
      ]
    };
  },
  methods: {
    addToCart(index) {
      this.products[index].quantity += 1;
    },
    updateQuantity(product) {
      this.$set(this.products, product.index, { ...product });
    }
  }
};
</script>

在這個優(yōu)化后的示例中,我們做了以下改動:

  1. addToCart 方法現(xiàn)在接收商品的索引而不是商品對象本身。
  2. 添加了一個新的 updateQuantity 方法,用于更新商品數(shù)量,并觸發(fā)視圖更新。

優(yōu)化說明:

  • 減少數(shù)據(jù)綁定:通過避免直接在事件處理函數(shù)中修改數(shù)據(jù),我們可以減少數(shù)據(jù)綁定的更新次數(shù)。
  • 使用 $set 方法:Vue 提供了 $set 方法來確保對象屬性的添加和刪除能夠觸發(fā)視圖更新。在這個例子中,我們可以使用 $set 來更新商品數(shù)量,而不是直接修改 product.quantity。
  • 避免不必要的渲染:通過減少數(shù)據(jù)更新的次數(shù),我們可以避免不必要的視圖渲染,從而提高性能。

通過這樣的優(yōu)化,我們可以減少數(shù)據(jù)更新對性能的影響,使得頁面響應(yīng)更加迅速,提升用戶體驗。

3. 使用小程序自帶組件:

在微信小程序開發(fā)中,使用小程序自帶組件而不是自定義組件可以顯著提升性能。這是因為自帶組件經(jīng)過了微信團隊的優(yōu)化,能夠更高效地渲染和更新。以下是優(yōu)化前后的代碼示例對比,來看一下:

優(yōu)化前:

假設(shè)我們正在開發(fā)一個商品列表頁,可能會使用自定義的<custom-list-item>組件來展示每個商品項:

<!-- 在頁面 wxml 中使用自定義組件 -->
<view class="product-list">
  <custom-list-item wx:for="{{products}}" wx:key="id" product="{{item}}"></custom-list-item>
</view>

自定義組件<custom-list-item>可能包含復(fù)雜的結(jié)構(gòu)和樣式,增加了渲染的負擔(dān)。

優(yōu)化后:

我們改用微信小程序提供的<view><text>等基礎(chǔ)組件來實現(xiàn)同樣的功能:

<!-- 在頁面 wxml 中使用小程序基礎(chǔ)組件 -->
<view class="product-list">
  <view wx:for="{{products}}" wx:key="id" class="product-item">
    <text class="product-name">{{item.name}}</text>
    <text class="product-price">{{item.price}}</text>
  </view>
</view>

在這個優(yōu)化后的示例中,我們直接使用<view><text>標(biāo)簽來展示商品信息,減少了自定義組件的使用,從而降低了頁面的渲染時間。

優(yōu)化說明:

  • 減少組件嵌套:使用基礎(chǔ)組件代替自定義組件,減少了組件嵌套的層級,簡化了DOM樹。
  • 提高渲染效率:基礎(chǔ)組件由于其簡單性,能夠更快地被渲染,特別是在列表渲染等高頻更新的場景中。
  • 降低內(nèi)存占用:自定義組件可能會包含額外的邏輯和樣式,這會增加內(nèi)存的占用。使用基礎(chǔ)組件可以減少不必要的內(nèi)存使用。

通過這樣的優(yōu)化,是不是提升小程序的渲染性能了呢,使得頁面滑動更加流暢,提升用戶體驗。

4. 優(yōu)化圖片資源:

優(yōu)化圖片資源是提升小程序性能的重要手段,尤其是在移動網(wǎng)絡(luò)環(huán)境下,合理的圖片優(yōu)化可以顯著減少加載時間,提升用戶體驗。以下是優(yōu)化前后的代碼示例對比:

優(yōu)化前:

在小程序中,我們可能會直接使用較大的圖片資源,沒有進行任何優(yōu)化:

<!-- 在 wxml 中直接使用大圖 -->
<image src="path/to/large-image.jpg" class="product-image"></image>

如果這里的large-image.jpg是一個高分辨率的圖片,加載時間較長,就會影響用戶體驗。

優(yōu)化后:

我們可以采取以下措施進行優(yōu)化:

  1. 圖片壓縮:使用工具壓縮圖片,減少文件大小。
  2. 圖片懶加載:僅在圖片即將進入視口時才開始加載。
  3. 使用合適的圖片格式:如WebP格式,它通常比JPEG或PNG格式的文件更小。
  4. 使用CDN托管:將圖片資源托管在內(nèi)容分發(fā)網(wǎng)絡(luò)(CDN)上,加快加載速度。

優(yōu)化后的代碼可能如下:

<!-- 在 wxml 中使用優(yōu)化后的圖片 -->
<image src="https://cdn.example.com/optimized-image.jpg" rel="external nofollow"  class="product-image"></image>

在小程序的app.json或頁面的.json配置文件中,可以配置圖片的懶加載:

{
  "lazyLoad": true
}

優(yōu)化說明:

  • 通過壓縮工具減小圖片文件的大小,而不損失太多視覺質(zhì)量。
  • 通過延遲非視口內(nèi)圖片的加載,減少初次頁面加載的數(shù)據(jù)量,提升首屏加載速度。
  • 利用CDN的分布式服務(wù)器,用戶可以從距離自己最近的服務(wù)器獲取資源,加快加載速度。
  • WebP等現(xiàn)代圖片格式在保持相同質(zhì)量的前提下,文件大小通常更小。

通過這樣的優(yōu)化,可以減少圖片資源對小程序性能的影響,提高頁面的加載速度和用戶體驗。

5. 分頁加載大量數(shù)據(jù):

在微信小程序中,處理大量數(shù)據(jù)時,分頁加載是一種常見的優(yōu)化手段。以下是優(yōu)化前后的代碼示例對比:

優(yōu)化前:

在沒有進行分頁處理的情況下,可能會一次性加載所有數(shù)據(jù),這會導(dǎo)致加載緩慢,用戶體驗差:

// 假設(shè)有一個獲取所有數(shù)據(jù)的方法
getData() {
  wx.request({
    url: 'https://api.vg.com/data',
    success: (res) => {
      this.setData({
        items: res.data
      });
    }
  });
}

這種方法會一次性請求所有數(shù)據(jù),如果數(shù)據(jù)量大,會導(dǎo)致頁面響應(yīng)慢。

優(yōu)化后:

采用分頁加載,每次只加載一部分?jǐn)?shù)據(jù),用戶可以觸發(fā)加載更多或者上拉加載更多:

// 頁面數(shù)據(jù)
data: {
  items: [], // 當(dāng)前頁面的數(shù)據(jù)列表
  currentPage: 1, // 當(dāng)前頁碼
  pageSize: 10, // 每頁顯示的條數(shù)
  hasMore: true // 是否還有更多數(shù)據(jù)
},


// 加載數(shù)據(jù)的方法
loadData() {
  if (!this.data.hasMore) {
    return; // 如果沒有更多數(shù)據(jù),則不執(zhí)行加載
  }
  wx.request({
    url: 'https://api.vg.com/data',
    data: {
      page: this.data.currentPage,
      pageSize: this.data.pageSize
    },
    success: (res) => {
      let newItems = this.data.items.concat(res.data); // 將新數(shù)據(jù)追加到舊數(shù)據(jù)后面
      this.setData({
        items: newItems,
        currentPage: this.data.currentPage + 1
      });
      if (res.data.length < this.data.pageSize) {
        this.setData({
          hasMore: false // 如果返回的數(shù)據(jù)少于pageSize,說明沒有更多數(shù)據(jù)了
        });
      }
    }
  });
},


// 上拉觸底加載更多
onReachBottom() {
  this.loadData();
},


// 頁面加載時觸發(fā)
onLoad() {
  this.loadData();
}

在這個優(yōu)化后的示例中,我們通過currentPagepageSize控制每次請求的數(shù)據(jù)量,并且只有當(dāng)用戶滾動到頁面底部時才會觸發(fā)onReachBottom事件,加載更多數(shù)據(jù)。

優(yōu)化說明:

  • 分頁加載可以減少單次請求的數(shù)據(jù)量,避免一次性加載大量數(shù)據(jù)導(dǎo)致的性能問題。
  • 用戶可以更快地看到首批數(shù)據(jù),提升用戶體驗。
  • 服務(wù)器和客戶端都不需要一次性處理大量數(shù)據(jù),節(jié)省了資源消耗。

通過分頁加載,我們可以有效地提升小程序處理大量數(shù)據(jù)時的性能,使得用戶體驗更加流暢。

6. 異步處理復(fù)雜操作:

在微信小程序中,異步處理復(fù)雜操作是一種常見的優(yōu)化手段,特別是在處理數(shù)據(jù)加載、網(wǎng)絡(luò)請求或計算密集型任務(wù)時。以下是優(yōu)化前后的代碼示例對比:

優(yōu)化前:

在沒有進行異步處理的情況下,可能會直接在主線程中執(zhí)行復(fù)雜操作,這會導(dǎo)致界面卡頓,舉個栗子:

// 假設(shè)有一個計算密集型的操作
calculateData() {
  let result = 0;
  for (let i = 0; i < 10000000; i++) {
    result += Math.sqrt(i);
  }
  this.setData({
    calculationResult: result
  });
}

在這個示例中,計算操作直接在主線程中執(zhí)行,如果計算量很大,會導(dǎo)致界面無法響應(yīng)用戶操作。

優(yōu)化后:

我們使用 setTimeout 或者微信小程序提供的 worker 線程來異步處理復(fù)雜操作,避免阻塞主線程:

// 使用 setTimeout 異步處理
calculateData() {
  setTimeout(() => {
    let result = 0;
    for (let i = 0; i < 10000000; i++) {
      result += Math.sqrt(i);
    }
    this.setData({
      calculationResult: result
    });
  }, 0);
}


// 或者使用 worker 線程異步處理(需要在 app.json 中開啟 worker)
// 在 js 文件中創(chuàng)建 worker
if (wx.canIUse('worker')) {
  const worker = new Worker();
  worker.onMessage((message) => {
    this.setData({
      calculationResult: message.data
    });
  });
  worker.postMessage('start');

  
  // 監(jiān)聽 worker 線程的消息
  worker.onMessage(function (event) {
    this.setData({
      calculationResult: event.data
    });
  });


  // 處理 worker 線程發(fā)送的數(shù)據(jù)
  worker.postMessage('Hello Worker');
}

在這個優(yōu)化后的示例中,我們通過 setTimeout 將計算操作放在異步隊列中執(zhí)行,或者使用 worker 線程來處理,這樣主線程仍然可以響應(yīng)用戶操作,提升用戶體驗。

優(yōu)化說明:

  • 通過異步處理,避免了復(fù)雜操作阻塞主線程,使得界面可以保持流暢。
  • 用戶操作可以得到及時響應(yīng),不會因為后臺操作而等待。
  • 用戶在使用小程序時,不會因為長時間的計算操作而感到卡頓或延遲。

這樣是不是可以讓用戶體驗更加贊呢。

7. 優(yōu)化啟動速度:

在uni-app中,優(yōu)化啟動速度是提升用戶體驗的重要方面。以下是一些優(yōu)化啟動速度的示例和方法:

優(yōu)化前(未進行啟動速度優(yōu)化):

// 在App.vue中全局引入大量樣式和腳本
import Vue from 'vue'
import App from './App'


// 全局樣式
import './styles/global.scss'
// 全局插件
import './plugins/global-plugin'


Vue.config.productionTip = false


App.mpType = 'app'


const app = new Vue({
    ...App
})
app.$mount()

在這種情況下,應(yīng)用在啟動時會加載所有全局樣式和插件,這可能會導(dǎo)致啟動速度變慢。

優(yōu)化后(進行啟動速度優(yōu)化):

// 在App.vue中按需引入資源
import Vue from 'vue'
import App from './App'


// 僅引入必要的全局樣式
import './styles/essential.scss'


Vue.config.productionTip = false


App.mpType = 'app'


const app = new Vue({
    ...App
})
app.$mount()

在優(yōu)化后的示例中,我們只引入了必要的全局樣式,減少了不必要的資源加載,從而加快了啟動速度。

優(yōu)化說明:

  • 只加載應(yīng)用啟動時真正需要的資源,減少不必要的資源加載。
  • 使用Webpack等構(gòu)建工具進行代碼分割,將代碼拆分成多個小塊,按需加載。
  • 利用uni-app的分包加載功能,將應(yīng)用分割成多個子包,減少主包體積。
  • 對資源進行優(yōu)先級排序,確保關(guān)鍵資源優(yōu)先加載。
  • 合理利用緩存,減少重復(fù)加載資源的次數(shù)。

在Webpack中,代碼分割(Code Splitting)是一種常用的優(yōu)化手段,它允許將代碼分離成不同的包(bundles),然后可以按需加載或并行加載這些文件。這不僅可以使應(yīng)用的初始加載更快,還可以控制資源加載的優(yōu)先級,從而顯著減少加載時間。以下是一些代碼分割的示例和優(yōu)化方法:

優(yōu)化前(未進行代碼分割):

假設(shè)你有一個應(yīng)用,其中包含了多個模塊,這些模塊都打包到一個主bundle中:

// main.js
import moduleA from './moduleA';
import moduleB from './moduleB';


function init() {
  // 初始化代碼
  moduleA.doSomething();
  moduleB.doSomething();
}
init();

在這種情況下,所有模塊都在初始加載時被加載,即使某些模塊可能稍后才會用到或根本不會用到。

優(yōu)化后(使用動態(tài)導(dǎo)入進行代碼分割):

使用Webpack的動態(tài)導(dǎo)入功能,可以將模塊分割成不同的chunks,并在需要時加載:

// main.js
function init() {
  // 初始化代碼
  import('./moduleA').then(moduleA => {
    moduleA.default.doSomething();
  });


  // 假設(shè)moduleB只有在用戶點擊按鈕后才需要加載
  document.getElementById('loadButton').addEventListener('click', () => {
    import('./moduleB').then(moduleB => {
      moduleB.default.doSomething();
    });
  });
}
init();

在這個優(yōu)化后的示例中,moduleA 在應(yīng)用啟動時加載,而 moduleB 則在用戶點擊按鈕時才加載。這樣可以減少應(yīng)用的初始加載時間,并在需要時才加載額外的代碼。

優(yōu)化說明:

  • 通過使用 import() 語法,Webpack會將導(dǎo)入的模塊分割成單獨的chunk,并在運行時按需加載。
  • 只加載應(yīng)用啟動時真正需要的代碼,從而減少初始加載的大小。
  • 根據(jù)用戶的行為或應(yīng)用的狀態(tài)來加載代碼,這樣可以提高性能并減少不必要的資源加載。

8. 使用nvue代替vue:

在uni-app中,使用nvue代替vue可以顯著提升頁面性能,尤其是在App端。以下是優(yōu)化前后的代碼示例對比:

優(yōu)化前(使用vue頁面):

<template>
  <view class="container">
    <view v-for="(item, index) in list" :key="index" class="item">
      <text>{{ item.text }}</text>
    </view>
  </view>
</template>


<script>
export default {
  data() {
    return {
      list: [{ text: '短褲' }, { text: '長褲' }, ...]
    };
  }
};
</script>


<style>
.container {
  display: flex;
  flex-direction: column;
}
.item {
  margin-bottom: 10px;
}
</style>

在這個例子中,我們使用了vue頁面來渲染一個列表,每個列表項都是一個簡單的文本。

優(yōu)化后(使用nvue頁面):

<template>
  <view class="container">
    <view v-for="(item, index) in list" :key="index" class="item">
      <text>{{ item.text }}</text>
    </view>
  </view>
</template>


<script>
export default {
  data() {
    return {
      list: [{ text: '短褲' }, { text: '長褲' }, ...]
    };
  }
};
</script>


<style>
.container {
  display: flex;
  flex-direction: column;
}
.item {
  margin-bottom: 10px;
}
</style>

在nvue頁面中,代碼結(jié)構(gòu)與vue頁面相似,但是渲染引擎不同。nvue頁面使用原生渲染引擎,可以提供更好的性能和流暢性。

優(yōu)化說明:

  • nvue頁面基于weex定制的原生渲染引擎,可以實現(xiàn)頁面原生渲染,提高頁面流暢性。這對于滾動列表和動畫效果較多的頁面尤其有效。
  • nvue頁面減少了邏輯層和視圖層之間的通信損耗,從而減少了資源消耗。
  • 對于需要高性能滾動列表、復(fù)雜動畫或者原生控件覆蓋的場景,使用nvue是更好的選擇。

需要注意的是,nvue頁面的CSS支持有限,因此可能需要對樣式進行一些調(diào)整。

9. 避免使用大圖:

在uni-app開發(fā)中,避免使用大圖是優(yōu)化性能的重要措施之一。以下是優(yōu)化前后的代碼示例對比:

優(yōu)化前(使用大圖):

<template>
  <view>
    <image src="path/to/large-image.jpg" class="large-image"></image>
  </view>
</template>


<style>
.large-image {
  width: 100%;
  height: auto;
}
</style>

在這個例子中,我們直接在頁面中使用了一張大圖,這可能會導(dǎo)致頁面加載緩慢,增加內(nèi)存消耗。

優(yōu)化后(使用壓縮后的圖片或適當(dāng)尺寸的圖片):

<template>
  <view>
    <image src="path/to/compressed-image.jpg" class="optimized-image"></image>
  </view>
</template>


<style>
.optimized-image {
  width: 100%;
  height: auto;
}
</style>

在優(yōu)化后的示例中,我們使用了壓縮后的圖片或適當(dāng)尺寸的圖片來替代原始的大圖。這可以通過使用圖片壓縮工具如TinyPNG或在線圖片壓縮工具來實現(xiàn)。

10. 優(yōu)化數(shù)據(jù)更新:

uni-app 中,定義在 data 里面的數(shù)據(jù)每次變化時都會通知視圖層重新渲染頁面。所以如果不是視圖所需要的變量,可以不定義在 data 中,以避免造成資源浪費。優(yōu)化數(shù)據(jù)更新是一個關(guān)鍵的步驟,以提高應(yīng)用的性能和用戶體驗。以下是優(yōu)化前后的代碼示例對比:

優(yōu)化前(頻繁更新整個頁面數(shù)據(jù)):

export default {
  data() {
    return {
      items: [一些敏感數(shù)據(jù),你需要自己模擬一下哦], // 存儲列表數(shù)據(jù)
      otherData: {其它數(shù)據(jù)} // 其他不相關(guān)數(shù)據(jù)
    };
  },
  methods: {
    fetchData() {
      // 假設(shè)這個方法從服務(wù)器獲取數(shù)據(jù)
      this.items = response.data.items;
      this.otherData = response.data.otherData;
    }
  }
}

在這個例子中,每次調(diào)用fetchData方法時,都會更新整個頁面的數(shù)據(jù),包括列表數(shù)據(jù)和其他不相關(guān)的數(shù)據(jù)。這可能導(dǎo)致不必要的渲染和性能損耗。

優(yōu)化后(僅更新必要的數(shù)據(jù)):

export default {
  data() {
    return {
      items: [一些敏感數(shù)據(jù),你需要自己模擬一下哦] // 僅存儲列表數(shù)據(jù)
    };
  },
  methods: {
    fetchItems() {
      // 只更新列表數(shù)據(jù),不更新其他不相關(guān)的數(shù)據(jù)
      this.items = response.data.items;
    }
  }
}

在優(yōu)化后的示例中,我們只更新了視圖真正需要的數(shù)據(jù),即列表數(shù)據(jù)items,而沒有更新其他不相關(guān)的數(shù)據(jù)。這樣可以減少不必要的數(shù)據(jù)綁定更新,提高性能。

優(yōu)化說明:

  • 不是所有數(shù)據(jù)變化都需要反映到視圖上,有時候只需要更新部分?jǐn)?shù)據(jù)。

11. 長列表優(yōu)化:

長列表中如果每個 item 有一個點贊按鈕,點擊后點贊數(shù)字+1,此時點贊組件必須是一個單獨引用的組件,才能做到差量數(shù)據(jù)更新。否則會造成整個列表數(shù)據(jù)重載。

優(yōu)化前(使用普通循環(huán)渲染):

<template>
  <scroll-view scroll-y="true" class="scroll-view">
    <view v-for="(item, index) in longList" :key="index">
      {{ item.content }}
    </view>
  </scroll-view>
</template>


<script>
export default {
  data() {
    return {
      longList: Array(1000).fill().map((_, index) => ({ content: `Item ${index + 1}` }))
    };
  }
};
</script>


<style>
.scroll-view {
  height: 100%;
}
</style>

在這個例子中,我們使用了一個scroll-view組件來渲染一個長列表,列表中的每個項都是通過v-for指令循環(huán)生成的。當(dāng)列表項非常多時,這種渲染方式會導(dǎo)致性能問題,因為所有的列表項都會被渲染,即使它們不在屏幕內(nèi)。

優(yōu)化后(使用<list>組件):

<template>
  <list class="list">
    <cell v-for="(item, index) in longList" :key="index">
      {{ item.content }}
    </cell>
  </list>
</template>


<script>
export default {
  data() {
    return {
      longList: Array(1000).fill().map((_, index) => ({ content: `Item ${index + 1}` }))
    };
  }
};
</script>


<style>
.list {
  height: 100%;
}
</style>

在優(yōu)化后的示例中,我們使用了<list>組件來渲染長列表。<list>組件是專門為長列表優(yōu)化的,它會自動回收不在屏幕內(nèi)的列表項的渲染資源,從而提高性能和流暢度。這種方式特別適合App端的nvue頁面,因為它使用了原生的渲染機制 。

優(yōu)化說明:

  • 通過使用<list>組件,只有用戶可見區(qū)域內(nèi)的列表項會被渲染,從而減少了不必要的渲染和內(nèi)存消耗。
  • <list>組件的滾動性能通常優(yōu)于<scroll-view>,因為它專門為長列表優(yōu)化,能夠提供更流暢的滾動體驗。
  • 通過回收不在屏幕內(nèi)的列表項資源,<list>組件減少了內(nèi)存的使用,避免了因渲染大量列表項而導(dǎo)致的內(nèi)存溢出問題。

12. 優(yōu)化頁面切換動畫:

頁面初始化時若存在大量圖片或原生組件渲染和大量數(shù)據(jù)通訊,會發(fā)生新頁面渲染和窗體進入動畫搶資源,造成頁面切換卡頓、掉幀。我們可以延時渲染圖片或復(fù)雜原生組件,分批進行數(shù)據(jù)加載。

優(yōu)化前(無動畫或簡單動畫):

<template>
  <view @click="goToNextPage">
    點擊前往下一頁
  </view>
</template>


<script>
export default {
  methods: {
    goToNextPage() {
      uni.navigateTo({
        url: 'path/to/next/page'
      });
    }
  }
}
</script>

這個示例中頁面切換時沒有特別的動畫效果,或者只使用了簡單的淡入淡出效果。

優(yōu)化后(自定義動畫效果):

<template>
  <view @click="goToNextPage">
    點擊前往下一頁
  </view>
</template>


<script>
export default {
  methods: {
    goToNextPage() {
      const animation = uni.createAnimation({
        duration: 300, // 動畫持續(xù)時間
        timingFunction: 'ease-in-out', // 動畫的效果
      });
      animation.scale(0.95, 0.95).rotate(15).step(); // 縮小并旋轉(zhuǎn)
      this.setData({
        animationData: animation.export(),
      });
      uni.navigateTo({
        url: 'path/to/next/page',
        animationType: 'pop-in', // 使用系統(tǒng)動畫
        animationDuration: 300, // 動畫持續(xù)時間,與上面保持一致
      });
    }
  }
}
</script>


<style>
/* 可以在這里定義動畫樣式 */
</style>

在優(yōu)化后的示例中,我們使用了uni.createAnimation來創(chuàng)建一個自定義的動畫效果,使得點擊時有一個縮小并旋轉(zhuǎn)的動畫,然后頁面切換時使用了系統(tǒng)的pop-in動畫效果。

優(yōu)化說明:

  • 通過uni.createAnimation可以創(chuàng)建復(fù)雜的動畫效果,使頁面切換更加生動有趣。
  • uni.navigateTouni.redirectTo等頁面跳轉(zhuǎn)方法中,可以指定系統(tǒng)提供的動畫效果,如pop-in、pop-out等。
  • 保持自定義動畫和系統(tǒng)動畫的持續(xù)時間一致,以確保動畫效果的流暢性。
  • 在頁面初始化時,如果有大量圖片或原生組件渲染和大量數(shù)據(jù)通訊,可能會與頁面進入動畫搶資源,造成卡頓或掉幀。建議延時渲染圖片或復(fù)雜原生組件,分批進行數(shù)據(jù)通信,以減少一次性渲染的節(jié)點數(shù)量。

13. 優(yōu)化樣式渲染速度:

如果頁面背景是深色,在vue頁面中可能會發(fā)生新窗體剛開始動畫時是灰白色背景,動畫結(jié)束時才變?yōu)樯钌尘?,造成閃屏。此時需將樣式寫在 App.vue 里,可以加速頁面樣式渲染速度。

優(yōu)化前(使用大量DOM和復(fù)雜的CSS):

<template>
  <view class="container">
    <view v-for="(item, index) in items" :key="index" class="item">
      <text class="text">{{ item.text }}</text>
    </view>
  </view>
</template>


<style>
.container {
  background-image: url('path/to/large-background-image.jpg');
}
.item {
  background-color: rgba(255, 255, 255, 0.8);
  border-radius: 10px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
}
.text {
  font-size: 16px;
  color: #333;
}
</style>

在這個例子中,頁面使用了大型背景圖片,并且每個列表項都有復(fù)雜的樣式,這可能導(dǎo)致樣式計算和渲染變慢。

優(yōu)化后(減少DOM數(shù)量和簡化CSS):

<template>
  <view class="container">
    <text v-for="(item, index) in items" :key="index" class="text">{{ item.text }}</text>
  </view>
</template>


<style>
.container {
  background-color: #fff; /* 使用純色背景代替圖片 */
}
.text {
  font-size: 16px;
  color: #333;
  margin: 10px;
  padding: 10px;
  background-color: rgba(255, 255, 255, 0.8);
  border-radius: 5px;
  box-shadow: none; /* 移除陰影效果 */
}
</style>

在優(yōu)化后的示例中,我們做了以下改動:

  1. 移除了.item類,直接將文本包裹在<text>標(biāo)簽中,減少了DOM數(shù)量。
  2. 使用純色背景代替大型背景圖片,減少了圖片加載時間。
  3. 簡化了.text類的樣式,移除了陰影效果,減少了樣式計算的復(fù)雜度。

優(yōu)化說明:

  • 減少頁面中的DOM元素數(shù)量,可以減少瀏覽器的渲染負擔(dān),提高渲染效率。
  • 簡化CSS樣式,避免復(fù)雜的盒模型計算和陰影效果,可以減少樣式計算時間。
  • 使用小圖或純色背景代替大圖,可以減少圖片加載時間,加快頁面渲染速度。

通過這樣的優(yōu)化,可以顯著提升頁面的渲染速度,使得用戶體驗更加流暢。同時,也要注意在App.vue中設(shè)置全局樣式,以加速頁面樣式的渲染速度。如果是在App端,還可以在pages.json中配置頁面的原生背景色,以避免新頁面進入時背景閃白的問題。

最后

以上優(yōu)化小技巧,可以顯著提升微信小程序的響應(yīng)速度和用戶體驗,你還有哪些在實際開發(fā)中的經(jīng)驗,可以在評論區(qū)與大家一起分享,感謝你的支持,歡迎關(guān)注威哥愛編程,創(chuàng)造不易,點個贊唄。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號