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)如下:

  1. <view class="product-detail">
  2. <view class="product-header">
  3. <view class="product-title">一條瑜伽褲</view>
  4. <view class="product-price">¥199</view>
  5. </view>
  6. <view class="product-body">
  7. <view class="product-image">
  8. <image src="path/to/img-ku"></image>
  9. </view>
  10. <view class="product-info">
  11. <view class="info-item">
  12. <text>品牌:</text>
  13. <text>VG牌</text>
  14. </view>
  15. <view class="info-item">
  16. <text>產(chǎn)地:</text>
  17. <text>東莞</text>
  18. </view>
  19. <!-- 更多 info-item -->
  20. </view>
  21. </view>
  22. <view class="product-footer">
  23. <button class="buy-button">購買</button>
  24. </view>
  25. </view>

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

優(yōu)化后:

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

  1. <view class="product-detail">
  2. <view class="product-header">
  3. <text class="product-title">一條瑜伽褲</text>
  4. <text class="product-price">¥199</text>
  5. </view>
  6. <image class="product-image" src="path/to/image"></image>
  7. <view class="product-info">
  8. <view class="info-item">
  9. <text>品牌:</text>
  10. <text>VG牌</text>
  11. </view>
  12. <view class="info-item">
  13. <text>產(chǎn)地:</text>
  14. <text>東莞</text>
  15. </view>
  16. <!-- 更多 info-item -->
  17. </view>
  18. <button class="product-footer buy-button">購買</button>
  19. </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ù)量會增加。我們可能會這樣編寫代碼:

  1. <template>
  2. <view class="product-list">
  3. <view v-for="(product, index) in products" :key="index" class="product-item">
  4. <text class="product-name">{{ product.name }}</text>
  5. <text class="product-quantity">{{ product.quantity }}</text>
  6. <button @click="addToCart(product)">加入購物車</button>
  7. </view>
  8. </view>
  9. </template>
  10. <script>
  11. export default {
  12. data() {
  13. return {
  14. products: [
  15. { name: '商品1-瑜伽褲', quantity: 0 },
  16. { name: '商品2-瑜伽衣', quantity: 0 },
  17. // 更多商品
  18. ]
  19. };
  20. },
  21. methods: {
  22. addToCart(product) {
  23. product.quantity += 1;
  24. }
  25. }
  26. };
  27. </script>

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

優(yōu)化后:

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

  1. <template>
  2. <view class="product-list">
  3. <view v-for="(product, index) in products" :key="index" class="product-item">
  4. <text class="product-name">{{ product.name }}</text>
  5. <text class="product-quantity">{{ product.quantity }}</text>
  6. <button @click="addToCart(index)">加入購物車</button>
  7. </view>
  8. </view>
  9. </template>
  10. <script>
  11. export default {
  12. data() {
  13. return {
  14. products: [
  15. { name: '商品1-瑜伽褲', quantity: 0 },
  16. { name: '商品2-瑜伽衣', quantity: 0 },
  17. // 更多商品
  18. ]
  19. };
  20. },
  21. methods: {
  22. addToCart(index) {
  23. this.products[index].quantity += 1;
  24. },
  25. updateQuantity(product) {
  26. this.$set(this.products, product.index, { ...product });
  27. }
  28. }
  29. };
  30. </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>組件來展示每個商品項:

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

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

優(yōu)化后:

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

  1. <!-- 在頁面 wxml 中使用小程序基礎(chǔ)組件 -->
  2. <view class="product-list">
  3. <view wx:for="{{products}}" wx:key="id" class="product-item">
  4. <text class="product-name">{{item.name}}</text>
  5. <text class="product-price">{{item.price}}</text>
  6. </view>
  7. </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)化:

  1. <!-- 在 wxml 中直接使用大圖 -->
  2. <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)化后的代碼可能如下:

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

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

  1. {
  2. "lazyLoad": true
  3. }

優(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)致加載緩慢,用戶體驗差:

  1. // 假設(shè)有一個獲取所有數(shù)據(jù)的方法
  2. getData() {
  3. wx.request({
  4. url: 'https://api.vg.com/data',
  5. success: (res) => {
  6. this.setData({
  7. items: res.data
  8. });
  9. }
  10. });
  11. }

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

優(yōu)化后:

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

  1. // 頁面數(shù)據(jù)
  2. data: {
  3. items: [], // 當(dāng)前頁面的數(shù)據(jù)列表
  4. currentPage: 1, // 當(dāng)前頁碼
  5. pageSize: 10, // 每頁顯示的條數(shù)
  6. hasMore: true // 是否還有更多數(shù)據(jù)
  7. },
  8. // 加載數(shù)據(jù)的方法
  9. loadData() {
  10. if (!this.data.hasMore) {
  11. return; // 如果沒有更多數(shù)據(jù),則不執(zhí)行加載
  12. }
  13. wx.request({
  14. url: 'https://api.vg.com/data',
  15. data: {
  16. page: this.data.currentPage,
  17. pageSize: this.data.pageSize
  18. },
  19. success: (res) => {
  20. let newItems = this.data.items.concat(res.data); // 將新數(shù)據(jù)追加到舊數(shù)據(jù)后面
  21. this.setData({
  22. items: newItems,
  23. currentPage: this.data.currentPage + 1
  24. });
  25. if (res.data.length < this.data.pageSize) {
  26. this.setData({
  27. hasMore: false // 如果返回的數(shù)據(jù)少于pageSize,說明沒有更多數(shù)據(jù)了
  28. });
  29. }
  30. }
  31. });
  32. },
  33. // 上拉觸底加載更多
  34. onReachBottom() {
  35. this.loadData();
  36. },
  37. // 頁面加載時觸發(fā)
  38. onLoad() {
  39. this.loadData();
  40. }

在這個優(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)致界面卡頓,舉個栗子:

  1. // 假設(shè)有一個計算密集型的操作
  2. calculateData() {
  3. let result = 0;
  4. for (let i = 0; i < 10000000; i++) {
  5. result += Math.sqrt(i);
  6. }
  7. this.setData({
  8. calculationResult: result
  9. });
  10. }

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

優(yōu)化后:

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

  1. // 使用 setTimeout 異步處理
  2. calculateData() {
  3. setTimeout(() => {
  4. let result = 0;
  5. for (let i = 0; i < 10000000; i++) {
  6. result += Math.sqrt(i);
  7. }
  8. this.setData({
  9. calculationResult: result
  10. });
  11. }, 0);
  12. }
  13. // 或者使用 worker 線程異步處理(需要在 app.json 中開啟 worker)
  14. // 在 js 文件中創(chuàng)建 worker
  15. if (wx.canIUse('worker')) {
  16. const worker = new Worker();
  17. worker.onMessage((message) => {
  18. this.setData({
  19. calculationResult: message.data
  20. });
  21. });
  22. worker.postMessage('start');
  23. // 監(jiān)聽 worker 線程的消息
  24. worker.onMessage(function (event) {
  25. this.setData({
  26. calculationResult: event.data
  27. });
  28. });
  29. // 處理 worker 線程發(fā)送的數(shù)據(jù)
  30. worker.postMessage('Hello Worker');
  31. }

在這個優(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)化):

  1. // 在App.vue中全局引入大量樣式和腳本
  2. import Vue from 'vue'
  3. import App from './App'
  4. // 全局樣式
  5. import './styles/global.scss'
  6. // 全局插件
  7. import './plugins/global-plugin'
  8. Vue.config.productionTip = false
  9. App.mpType = 'app'
  10. const app = new Vue({
  11. ...App
  12. })
  13. app.$mount()

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

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

  1. // 在App.vue中按需引入資源
  2. import Vue from 'vue'
  3. import App from './App'
  4. // 僅引入必要的全局樣式
  5. import './styles/essential.scss'
  6. Vue.config.productionTip = false
  7. App.mpType = 'app'
  8. const app = new Vue({
  9. ...App
  10. })
  11. 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中:

  1. // main.js
  2. import moduleA from './moduleA';
  3. import moduleB from './moduleB';
  4. function init() {
  5. // 初始化代碼
  6. moduleA.doSomething();
  7. moduleB.doSomething();
  8. }
  9. init();

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

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

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

  1. // main.js
  2. function init() {
  3. // 初始化代碼
  4. import('./moduleA').then(moduleA => {
  5. moduleA.default.doSomething();
  6. });
  7. // 假設(shè)moduleB只有在用戶點擊按鈕后才需要加載
  8. document.getElementById('loadButton').addEventListener('click', () => {
  9. import('./moduleB').then(moduleB => {
  10. moduleB.default.doSomething();
  11. });
  12. });
  13. }
  14. 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頁面):

  1. <template>
  2. <view class="container">
  3. <view v-for="(item, index) in list" :key="index" class="item">
  4. <text>{{ item.text }}</text>
  5. </view>
  6. </view>
  7. </template>
  8. <script>
  9. export default {
  10. data() {
  11. return {
  12. list: [{ text: '短褲' }, { text: '長褲' }, ...]
  13. };
  14. }
  15. };
  16. </script>
  17. <style>
  18. .container {
  19. display: flex;
  20. flex-direction: column;
  21. }
  22. .item {
  23. margin-bottom: 10px;
  24. }
  25. </style>

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

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

  1. <template>
  2. <view class="container">
  3. <view v-for="(item, index) in list" :key="index" class="item">
  4. <text>{{ item.text }}</text>
  5. </view>
  6. </view>
  7. </template>
  8. <script>
  9. export default {
  10. data() {
  11. return {
  12. list: [{ text: '短褲' }, { text: '長褲' }, ...]
  13. };
  14. }
  15. };
  16. </script>
  17. <style>
  18. .container {
  19. display: flex;
  20. flex-direction: column;
  21. }
  22. .item {
  23. margin-bottom: 10px;
  24. }
  25. </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)化前(使用大圖):

  1. <template>
  2. <view>
  3. <image src="path/to/large-image.jpg" class="large-image"></image>
  4. </view>
  5. </template>
  6. <style>
  7. .large-image {
  8. width: 100%;
  9. height: auto;
  10. }
  11. </style>

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

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

  1. <template>
  2. <view>
  3. <image src="path/to/compressed-image.jpg" class="optimized-image"></image>
  4. </view>
  5. </template>
  6. <style>
  7. .optimized-image {
  8. width: 100%;
  9. height: auto;
  10. }
  11. </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ù)):

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

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

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

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

在優(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)渲染):

  1. <template>
  2. <scroll-view scroll-y="true" class="scroll-view">
  3. <view v-for="(item, index) in longList" :key="index">
  4. {{ item.content }}
  5. </view>
  6. </scroll-view>
  7. </template>
  8. <script>
  9. export default {
  10. data() {
  11. return {
  12. longList: Array(1000).fill().map((_, index) => ({ content: `Item ${index + 1}` }))
  13. };
  14. }
  15. };
  16. </script>
  17. <style>
  18. .scroll-view {
  19. height: 100%;
  20. }
  21. </style>

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

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

  1. <template>
  2. <list class="list">
  3. <cell v-for="(item, index) in longList" :key="index">
  4. {{ item.content }}
  5. </cell>
  6. </list>
  7. </template>
  8. <script>
  9. export default {
  10. data() {
  11. return {
  12. longList: Array(1000).fill().map((_, index) => ({ content: `Item ${index + 1}` }))
  13. };
  14. }
  15. };
  16. </script>
  17. <style>
  18. .list {
  19. height: 100%;
  20. }
  21. </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)化前(無動畫或簡單動畫):

  1. <template>
  2. <view @click="goToNextPage">
  3. 點擊前往下一頁
  4. </view>
  5. </template>
  6. <script>
  7. export default {
  8. methods: {
  9. goToNextPage() {
  10. uni.navigateTo({
  11. url: 'path/to/next/page'
  12. });
  13. }
  14. }
  15. }
  16. </script>

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

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

  1. <template>
  2. <view @click="goToNextPage">
  3. 點擊前往下一頁
  4. </view>
  5. </template>
  6. <script>
  7. export default {
  8. methods: {
  9. goToNextPage() {
  10. const animation = uni.createAnimation({
  11. duration: 300, // 動畫持續(xù)時間
  12. timingFunction: 'ease-in-out', // 動畫的效果
  13. });
  14. animation.scale(0.95, 0.95).rotate(15).step(); // 縮小并旋轉(zhuǎn)
  15. this.setData({
  16. animationData: animation.export(),
  17. });
  18. uni.navigateTo({
  19. url: 'path/to/next/page',
  20. animationType: 'pop-in', // 使用系統(tǒng)動畫
  21. animationDuration: 300, // 動畫持續(xù)時間,與上面保持一致
  22. });
  23. }
  24. }
  25. }
  26. </script>
  27. <style>
  28. /* 可以在這里定義動畫樣式 */
  29. </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):

  1. <template>
  2. <view class="container">
  3. <view v-for="(item, index) in items" :key="index" class="item">
  4. <text class="text">{{ item.text }}</text>
  5. </view>
  6. </view>
  7. </template>
  8. <style>
  9. .container {
  10. background-image: url('path/to/large-background-image.jpg');
  11. }
  12. .item {
  13. background-color: rgba(255, 255, 255, 0.8);
  14. border-radius: 10px;
  15. box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
  16. }
  17. .text {
  18. font-size: 16px;
  19. color: #333;
  20. }
  21. </style>

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

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

  1. <template>
  2. <view class="container">
  3. <text v-for="(item, index) in items" :key="index" class="text">{{ item.text }}</text>
  4. </view>
  5. </template>
  6. <style>
  7. .container {
  8. background-color: #fff; /* 使用純色背景代替圖片 */
  9. }
  10. .text {
  11. font-size: 16px;
  12. color: #333;
  13. margin: 10px;
  14. padding: 10px;
  15. background-color: rgba(255, 255, 255, 0.8);
  16. border-radius: 5px;
  17. box-shadow: none; /* 移除陰影效果 */
  18. }
  19. </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

公眾號
微信公眾號

編程獅公眾號