uni-app微信小程序性能优化技巧 | 13个实用方法

2024-12-18 11:09 更新

大家好,我是威哥,在使用uni-app开发微信小程序时,性能优化是提升用户体验的关键。今天的内容,整理了以下13个有效的性能优化技巧,供你在开发中参考:

1. 减少页面层级和组件嵌套:

减少页面层级和组件嵌套是前端性能优化中的常见做法,它有助于减少浏览器的渲染负担,提高页面的响应速度。我们通过以下优化前后的示例对比来说明:

优化前:

假设我们有一个电商应用的商品详情页,页面结构如下:

  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>产地:</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-headerproduct-bodyproduct-footerproduct-body 下又嵌套了 product-imageproduct-info,而 product-info 下还有多个 info-item

优化后:

我们可以将一些不需要单独样式或行为的子元素合并到父元素中,以减少层级:

  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>产地:</text>
  14. <text>东莞</text>
  15. </view>
  16. <!-- 更多 info-item -->
  17. </view>
  18. <button class="product-footer buy-button">购买</button>
  19. </view>

在这个优化后的示例中,我们做了以下改动:

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

优化说明:

  • 减少DOM元素数量:优化后的代码减少了不必要的 <view> 元素,这减少了DOM树的深度,使得浏览器渲染成本降低。
  • 简化结构:简化的页面结构使得维护和理解代码变得更加容易。
  • 提高性能:较少的DOM操作和更少的重排重绘,可以提高页面的响应速度和流畅度。

通过这样的优化,我们能够提升页面的性能,使得用户在使用小程序时能够获得更好的体验。

2. 避免频繁的数据更新:

避免频繁的数据更新是提升性能的一个重要方面,特别是在数据绑定频繁更新时,可能会导致页面渲染性能问题。以下是优化前后的示例对比说明,我们来看一下:

优化前:

假设我们有一个商品列表页面,每个商品项都有一个“加入购物车”的按钮,点击后商品数量会增加。我们可能会这样编写代码:

  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>

在这个例子中,每次点击“加入购物车”按钮,都会触发 addToCart 方法,该方法直接修改了 product.quantity 的值,导致视图重新渲染。

优化后:

我们可以优化数据更新的方式,减少不必要的数据绑定和视图渲染:

  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>

在这个优化后的示例中,我们做了以下改动:

  1. addToCart 方法现在接收商品的索引而不是商品对象本身。
  2. 添加了一个新的 updateQuantity 方法,用于更新商品数量,并触发视图更新。

优化说明:

  • 减少数据绑定:通过避免直接在事件处理函数中修改数据,我们可以减少数据绑定的更新次数。
  • 使用 $set 方法:Vue 提供了 $set 方法来确保对象属性的添加和删除能够触发视图更新。在这个例子中,我们可以使用 $set 来更新商品数量,而不是直接修改 product.quantity
  • 避免不必要的渲染:通过减少数据更新的次数,我们可以避免不必要的视图渲染,从而提高性能。

通过这样的优化,我们可以减少数据更新对性能的影响,使得页面响应更加迅速,提升用户体验。

3. 使用小程序自带组件:

在微信小程序开发中,使用小程序自带组件而不是自定义组件可以显著提升性能。这是因为自带组件经过了微信团队的优化,能够更高效地渲染和更新。以下是优化前后的代码示例对比,来看一下:

优化前:

假设我们正在开发一个商品列表页,可能会使用自定义的<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>可能包含复杂的结构和样式,增加了渲染的负担。

优化后:

我们改用微信小程序提供的<view><text>等基础组件来实现同样的功能:

  1. <!-- 在页面 wxml 中使用小程序基础组件 -->
  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>

在这个优化后的示例中,我们直接使用<view><text>标签来展示商品信息,减少了自定义组件的使用,从而降低了页面的渲染时间。

优化说明:

  • 减少组件嵌套:使用基础组件代替自定义组件,减少了组件嵌套的层级,简化了DOM树。
  • 提高渲染效率:基础组件由于其简单性,能够更快地被渲染,特别是在列表渲染等高频更新的场景中。
  • 降低内存占用:自定义组件可能会包含额外的逻辑和样式,这会增加内存的占用。使用基础组件可以减少不必要的内存使用。

通过这样的优化,是不是提升小程序的渲染性能了呢,使得页面滑动更加流畅,提升用户体验。

4. 优化图片资源:

优化图片资源是提升小程序性能的重要手段,尤其是在移动网络环境下,合理的图片优化可以显著减少加载时间,提升用户体验。以下是优化前后的代码示例对比:

优化前:

在小程序中,我们可能会直接使用较大的图片资源,没有进行任何优化:

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

如果这里的large-image.jpg是一个高分辨率的图片,加载时间较长,就会影响用户体验。

优化后:

我们可以采取以下措施进行优化:

  1. 图片压缩:使用工具压缩图片,减少文件大小。
  2. 图片懒加载:仅在图片即将进入视口时才开始加载。
  3. 使用合适的图片格式:如WebP格式,它通常比JPEG或PNG格式的文件更小。
  4. 使用CDN托管:将图片资源托管在内容分发网络(CDN)上,加快加载速度。

优化后的代码可能如下:

  1. <!-- 在 wxml 中使用优化后的图片 -->
  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. }

优化说明:

  • 通过压缩工具减小图片文件的大小,而不损失太多视觉质量。
  • 通过延迟非视口内图片的加载,减少初次页面加载的数据量,提升首屏加载速度。
  • 利用CDN的分布式服务器,用户可以从距离自己最近的服务器获取资源,加快加载速度。
  • WebP等现代图片格式在保持相同质量的前提下,文件大小通常更小。

通过这样的优化,可以减少图片资源对小程序性能的影响,提高页面的加载速度和用户体验。

5. 分页加载大量数据:

在微信小程序中,处理大量数据时,分页加载是一种常见的优化手段。以下是优化前后的代码示例对比:

优化前:

在没有进行分页处理的情况下,可能会一次性加载所有数据,这会导致加载缓慢,用户体验差:

  1. // 假设有一个获取所有数据的方法
  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. }

这种方法会一次性请求所有数据,如果数据量大,会导致页面响应慢。

优化后:

采用分页加载,每次只加载一部分数据,用户可以触发加载更多或者上拉加载更多:

  1. // 页面数据
  2. data: {
  3. items: [], // 当前页面的数据列表
  4. currentPage: 1, // 当前页码
  5. pageSize: 10, // 每页显示的条数
  6. hasMore: true // 是否还有更多数据
  7. },
  8. // 加载数据的方法
  9. loadData() {
  10. if (!this.data.hasMore) {
  11. return; // 如果没有更多数据,则不执行加载
  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); // 将新数据追加到旧数据后面
  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 // 如果返回的数据少于pageSize,说明没有更多数据了
  28. });
  29. }
  30. }
  31. });
  32. },
  33. // 上拉触底加载更多
  34. onReachBottom() {
  35. this.loadData();
  36. },
  37. // 页面加载时触发
  38. onLoad() {
  39. this.loadData();
  40. }

在这个优化后的示例中,我们通过currentPagepageSize控制每次请求的数据量,并且只有当用户滚动到页面底部时才会触发onReachBottom事件,加载更多数据。

优化说明:

  • 分页加载可以减少单次请求的数据量,避免一次性加载大量数据导致的性能问题。
  • 用户可以更快地看到首批数据,提升用户体验。
  • 服务器和客户端都不需要一次性处理大量数据,节省了资源消耗。

通过分页加载,我们可以有效地提升小程序处理大量数据时的性能,使得用户体验更加流畅。

6. 异步处理复杂操作:

在微信小程序中,异步处理复杂操作是一种常见的优化手段,特别是在处理数据加载、网络请求或计算密集型任务时。以下是优化前后的代码示例对比:

优化前:

在没有进行异步处理的情况下,可能会直接在主线程中执行复杂操作,这会导致界面卡顿,举个栗子:

  1. // 假设有一个计算密集型的操作
  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. }

在这个示例中,计算操作直接在主线程中执行,如果计算量很大,会导致界面无法响应用户操作。

优化后:

我们使用 setTimeout 或者微信小程序提供的 worker 线程来异步处理复杂操作,避免阻塞主线程:

  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 文件中创建 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. // 监听 worker 线程的消息
  24. worker.onMessage(function (event) {
  25. this.setData({
  26. calculationResult: event.data
  27. });
  28. });
  29. // 处理 worker 线程发送的数据
  30. worker.postMessage('Hello Worker');
  31. }

在这个优化后的示例中,我们通过 setTimeout 将计算操作放在异步队列中执行,或者使用 worker 线程来处理,这样主线程仍然可以响应用户操作,提升用户体验。

优化说明:

  • 通过异步处理,避免了复杂操作阻塞主线程,使得界面可以保持流畅。
  • 用户操作可以得到及时响应,不会因为后台操作而等待。
  • 用户在使用小程序时,不会因为长时间的计算操作而感到卡顿或延迟。

这样是不是可以让用户体验更加赞呢。

7. 优化启动速度:

在uni-app中,优化启动速度是提升用户体验的重要方面。以下是一些优化启动速度的示例和方法:

优化前(未进行启动速度优化):

  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()

在这种情况下,应用在启动时会加载所有全局样式和插件,这可能会导致启动速度变慢。

优化后(进行启动速度优化):

  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()

在优化后的示例中,我们只引入了必要的全局样式,减少了不必要的资源加载,从而加快了启动速度。

优化说明:

  • 只加载应用启动时真正需要的资源,减少不必要的资源加载。
  • 使用Webpack等构建工具进行代码分割,将代码拆分成多个小块,按需加载。
  • 利用uni-app的分包加载功能,将应用分割成多个子包,减少主包体积。
  • 对资源进行优先级排序,确保关键资源优先加载。
  • 合理利用缓存,减少重复加载资源的次数。

在Webpack中,代码分割(Code Splitting)是一种常用的优化手段,它允许将代码分离成不同的包(bundles),然后可以按需加载或并行加载这些文件。这不仅可以使应用的初始加载更快,还可以控制资源加载的优先级,从而显著减少加载时间。以下是一些代码分割的示例和优化方法:

优化前(未进行代码分割):

假设你有一个应用,其中包含了多个模块,这些模块都打包到一个主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();

在这种情况下,所有模块都在初始加载时被加载,即使某些模块可能稍后才会用到或根本不会用到。

优化后(使用动态导入进行代码分割):

使用Webpack的动态导入功能,可以将模块分割成不同的chunks,并在需要时加载:

  1. // main.js
  2. function init() {
  3. // 初始化代码
  4. import('./moduleA').then(moduleA => {
  5. moduleA.default.doSomething();
  6. });
  7. // 假设moduleB只有在用户点击按钮后才需要加载
  8. document.getElementById('loadButton').addEventListener('click', () => {
  9. import('./moduleB').then(moduleB => {
  10. moduleB.default.doSomething();
  11. });
  12. });
  13. }
  14. init();

在这个优化后的示例中,moduleA 在应用启动时加载,而 moduleB 则在用户点击按钮时才加载。这样可以减少应用的初始加载时间,并在需要时才加载额外的代码。

优化说明:

  • 通过使用 import() 语法,Webpack会将导入的模块分割成单独的chunk,并在运行时按需加载。
  • 只加载应用启动时真正需要的代码,从而减少初始加载的大小。
  • 根据用户的行为或应用的状态来加载代码,这样可以提高性能并减少不必要的资源加载。

8. 使用nvue代替vue:

在uni-app中,使用nvue代替vue可以显著提升页面性能,尤其是在App端。以下是优化前后的代码示例对比:

优化前(使用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页面来渲染一个列表,每个列表项都是一个简单的文本。

优化后(使用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页面中,代码结构与vue页面相似,但是渲染引擎不同。nvue页面使用原生渲染引擎,可以提供更好的性能和流畅性。

优化说明:

  • nvue页面基于weex定制的原生渲染引擎,可以实现页面原生渲染,提高页面流畅性。这对于滚动列表和动画效果较多的页面尤其有效。
  • nvue页面减少了逻辑层和视图层之间的通信损耗,从而减少了资源消耗。
  • 对于需要高性能滚动列表、复杂动画或者原生控件覆盖的场景,使用nvue是更好的选择。

需要注意的是,nvue页面的CSS支持有限,因此可能需要对样式进行一些调整。

9. 避免使用大图:

在uni-app开发中,避免使用大图是优化性能的重要措施之一。以下是优化前后的代码示例对比:

优化前(使用大图):

  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>

在这个例子中,我们直接在页面中使用了一张大图,这可能会导致页面加载缓慢,增加内存消耗。

优化后(使用压缩后的图片或适当尺寸的图片):

  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>

在优化后的示例中,我们使用了压缩后的图片或适当尺寸的图片来替代原始的大图。这可以通过使用图片压缩工具如TinyPNG或在线图片压缩工具来实现。

10. 优化数据更新:

uni-app 中,定义在 data 里面的数据每次变化时都会通知视图层重新渲染页面。所以如果不是视图所需要的变量,可以不定义在 data 中,以避免造成资源浪费。优化数据更新是一个关键的步骤,以提高应用的性能和用户体验。以下是优化前后的代码示例对比:

优化前(频繁更新整个页面数据):

  1. export default {
  2. data() {
  3. return {
  4. items: [一些敏感数据,你需要自己模拟一下哦], // 存储列表数据
  5. otherData: {其它数据} // 其他不相关数据
  6. };
  7. },
  8. methods: {
  9. fetchData() {
  10. // 假设这个方法从服务器获取数据
  11. this.items = response.data.items;
  12. this.otherData = response.data.otherData;
  13. }
  14. }
  15. }

在这个例子中,每次调用fetchData方法时,都会更新整个页面的数据,包括列表数据和其他不相关的数据。这可能导致不必要的渲染和性能损耗。

优化后(仅更新必要的数据):

  1. export default {
  2. data() {
  3. return {
  4. items: [一些敏感数据,你需要自己模拟一下哦] // 仅存储列表数据
  5. };
  6. },
  7. methods: {
  8. fetchItems() {
  9. // 只更新列表数据,不更新其他不相关的数据
  10. this.items = response.data.items;
  11. }
  12. }
  13. }

在优化后的示例中,我们只更新了视图真正需要的数据,即列表数据items,而没有更新其他不相关的数据。这样可以减少不必要的数据绑定更新,提高性能。

优化说明:

  • 不是所有数据变化都需要反映到视图上,有时候只需要更新部分数据。

11. 长列表优化:

长列表中如果每个 item 有一个点赞按钮,点击后点赞数字+1,此时点赞组件必须是一个单独引用的组件,才能做到差量数据更新。否则会造成整个列表数据重载。

优化前(使用普通循环渲染):

  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指令循环生成的。当列表项非常多时,这种渲染方式会导致性能问题,因为所有的列表项都会被渲染,即使它们不在屏幕内。

优化后(使用<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>

在优化后的示例中,我们使用了<list>组件来渲染长列表。<list>组件是专门为长列表优化的,它会自动回收不在屏幕内的列表项的渲染资源,从而提高性能和流畅度。这种方式特别适合App端的nvue页面,因为它使用了原生的渲染机制 。

优化说明:

  • 通过使用<list>组件,只有用户可见区域内的列表项会被渲染,从而减少了不必要的渲染和内存消耗。
  • <list>组件的滚动性能通常优于<scroll-view>,因为它专门为长列表优化,能够提供更流畅的滚动体验。
  • 通过回收不在屏幕内的列表项资源,<list>组件减少了内存的使用,避免了因渲染大量列表项而导致的内存溢出问题。

12. 优化页面切换动画:

页面初始化时若存在大量图片或原生组件渲染和大量数据通讯,会发生新页面渲染和窗体进入动画抢资源,造成页面切换卡顿、掉帧。我们可以延时渲染图片或复杂原生组件,分批进行数据加载。

优化前(无动画或简单动画):

  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>

这个示例中页面切换时没有特别的动画效果,或者只使用了简单的淡入淡出效果。

优化后(自定义动画效果):

  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, // 动画持续时间
  12. timingFunction: 'ease-in-out', // 动画的效果
  13. });
  14. animation.scale(0.95, 0.95).rotate(15).step(); // 缩小并旋转
  15. this.setData({
  16. animationData: animation.export(),
  17. });
  18. uni.navigateTo({
  19. url: 'path/to/next/page',
  20. animationType: 'pop-in', // 使用系统动画
  21. animationDuration: 300, // 动画持续时间,与上面保持一致
  22. });
  23. }
  24. }
  25. }
  26. </script>
  27. <style>
  28. /* 可以在这里定义动画样式 */
  29. </style>

在优化后的示例中,我们使用了uni.createAnimation来创建一个自定义的动画效果,使得点击时有一个缩小并旋转的动画,然后页面切换时使用了系统的pop-in动画效果。

优化说明:

  • 通过uni.createAnimation可以创建复杂的动画效果,使页面切换更加生动有趣。
  • uni.navigateTouni.redirectTo等页面跳转方法中,可以指定系统提供的动画效果,如pop-inpop-out等。
  • 保持自定义动画和系统动画的持续时间一致,以确保动画效果的流畅性。
  • 在页面初始化时,如果有大量图片或原生组件渲染和大量数据通讯,可能会与页面进入动画抢资源,造成卡顿或掉帧。建议延时渲染图片或复杂原生组件,分批进行数据通信,以减少一次性渲染的节点数量。

13. 优化样式渲染速度:

如果页面背景是深色,在vue页面中可能会发生新窗体刚开始动画时是灰白色背景,动画结束时才变为深色背景,造成闪屏。此时需将样式写在 App.vue 里,可以加速页面样式渲染速度。

优化前(使用大量DOM和复杂的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>

在这个例子中,页面使用了大型背景图片,并且每个列表项都有复杂的样式,这可能导致样式计算和渲染变慢。

优化后(减少DOM数量和简化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>

在优化后的示例中,我们做了以下改动:

  1. 移除了.item类,直接将文本包裹在<text>标签中,减少了DOM数量。
  2. 使用纯色背景代替大型背景图片,减少了图片加载时间。
  3. 简化了.text类的样式,移除了阴影效果,减少了样式计算的复杂度。

优化说明:

  • 减少页面中的DOM元素数量,可以减少浏览器的渲染负担,提高渲染效率。
  • 简化CSS样式,避免复杂的盒模型计算和阴影效果,可以减少样式计算时间。
  • 使用小图或纯色背景代替大图,可以减少图片加载时间,加快页面渲染速度。

通过这样的优化,可以显著提升页面的渲染速度,使得用户体验更加流畅。同时,也要注意在App.vue中设置全局样式,以加速页面样式的渲染速度。如果是在App端,还可以在pages.json中配置页面的原生背景色,以避免新页面进入时背景闪白的问题。

最后

以上优化小技巧,可以显著提升微信小程序的响应速度和用户体验,你还有哪些在实际开发中的经验,可以在评论区与大家一起分享,感谢你的支持,欢迎关注威哥爱编程,创造不易,点个赞呗。

以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号