小程序性能优化实践

今天的分享由导师Uncle13提供。

小程序性能是评价小程序在微信APP或其他宿主APP中运行效率的关键因素,具体涵盖了加载速度、呈现效果以及用户交互响应的敏捷度。若小程序性能不佳,不仅会导致渲染缓慢、响应滞后,甚至可能出现无法正常启动的情况,这无疑会严重损害用户体验,进而造成用户流失。

在面试中,小程序的性能优化是小程序项目开发的中比较有价值的亮点。

下文着重讲两个实践操作:

关键阶段以及相关指标

  • LoadPackage :指小程序代码包下载阶段。在此阶段,小程序需要从服务器下载代码包以执行后续的逻辑。代码包大小和下载速度会影响小程序的启动性能。获取方式: 可通过网络监控工具或浏览器开发者工具查看网络请求的时间和代码包大小等信息。

  • First Paint (FP) :页面首次绘制是浏览器开始将内容呈现在屏幕上的时间点。此时用户无法与页面交互,但首次绘制仍可显示部分内容,向用户展示页面正在加载。获取方式: 通过浏览器性能分析工具或Performance API来捕获此事件,并了解页面渲染启动时间。

  • First Contentful Paint (FCP) :页面的第一个内容块被绘制到屏幕上的时间点。用户可以看到页面的某些部分,但是页面尚未完全加载。获取方式:  通过Chrome DevTools 的 Performance 面板或Lighthouse 等工具可以获取该指标。

  • First Meaningful Paint (FMP) :用户认为有用内容被展示在屏幕上的时间点。FMP 更准确地反映用户感知到的页面加载速度,因为它考虑了页面加载时的实际内容。获取方式: 通过用户体验监控工具、Web Vitals 库或Chrome User Experience Report 等方式可以收集数据并分析用户感知到的页面加载速度。

  • Largest Contentful Paint (LCP) :页面中最大的内容元素(如图片、文本等)被绘制到屏幕上且变得可见的时间点。LCP 是衡量用户认为页面已可交互的重要指标之一,优化 LCP 可提升用户体验和页面加载速度。获取方式: 通过Chrome DevTools 的Performance 面板、Web Vitals 库或PageSpeed Insights 等工具来获取和分析 LCP 数据。

优化策略

1,代码包体积优化(提升小程序初始化效率)

1.1 分包策略

独立分包允许小程序页面独立运行,无需依赖主包或其他分包。当从独立分包页面进入小程序时,用户无需等待主包下载,从而显著提升了启动速度。

  • 主包:包含小程序的初始启动逻辑、基础框架和一些常用页面等内容。用户打开小程序时会首先下载主包。
  • 分包:除了主包以外的其他代码包,每个分包可以包含若干个页面或组件。分包相对独立于主包运行,可以根据业务逻辑将相关页面或组件划分到不同的分包中。
1.2 分包异步化

分包异步化进一步细化了小程序的分包粒度,从页面级别深入到组件甚至文件级别。这使得原本只能放在主包内的部分插件、组件和代码逻辑得以剥离到分包中,并在运行时异步加载。这一技术有效解决了主包过度膨胀的问题,进一步降低了启动时的代码加载量。

app.json 配置

    "subpackages": [
         {
             "root""pages/goods/",
             "name""goods"
         }
     ]

动态引入

    wx.loadSubPackage({
         root'pages/goods/',
         successfunction(res{
             // 分包加载成功后的回调
         },
         failfunction(res{
             // 分包加载失败处理
         }
     });

1.3 分包预下载机制

尽管分包加载能够提升启动速度,但当用户跳转到分包内页面时,仍需等待分包下载,这可能导致页面切换的延迟。为解决这一问题,需要引入了分包预下载机制。该机制允许小程序在后台预先下载分包,确保用户在首次进入分包页面时无需等待下载,从而提升了页面切换的流畅性。

预下载原理:
  • 分包预下载机制利用小程序框架的预加载能力,在用户打开小程序时提前加载分包资源,使得当用户需要访问对应分包页面时,可以更快地展示内容,减少加载等待时间。

  • 预下载机制通常会在主包的某些关键页面或事件触发时开始执行,提前下载分包所需的资源文件,如 JS、CSS、图片等。

实现步骤:
  • 识别关键页面:需要确定哪些页面是用户经常访问的重要页面,这些页面通常会被定义为关键页面,可以考虑在这些页面触发时启动预下载机制。

  • 触发预下载:在合适的时机,例如用户打开小程序时或进入关键页面时,调用相应的预下载函数或方法,开始下载分包资源。

  • 资源加载:下载完成后,将分包资源缓存至本地,以便在用户访问分包页面时直接使用已下载的资源,避免重新下载。

实际项目场景:
  • 图片密集页面:对于包含大量图片的分包页面(如相册、产品展示页),通过预下载图片资源可以提高用户体验。

  • 复杂交互页面:对于交互复杂的分包页面(如地图、视频播放页),提前加载相关组件和数据能够加快页面展示速度。

2,数据预加载

数据预加载是一个比较有效的优化手段,必要的数据前加载未来要使用的数据并缓存到本地,以减少在用户需要这些数据时的加载时间,从而提升用户体验。这种能力对于小程序而言尤为重要,因为加载速度是影响用户体验的关键因素之一。

下面以用户的认证信息讲一下

2.1 缓存用户认证信息

当用户在小程序中完成登录后,将用户的认证信息(如token、用户ID等)缓存到小程序的本地存储中。这可以通过使用小程序提供的API如wx.setStorageSyncwx.setStorage来实现。

// 假设用户登录成功后,我们获得了用户的认证信息
const userAuthInfo = {
  token'user_token_here',
  userId'user_id_here'
};

// 将认证信息缓存到本地存储
wx.setStorageSync('userAuthInfo', userAuthInfo);
2.2 小程序启动时预加载认证信息

当小程序启动时(例如在ApponLaunchonShow生命周期函数中),从本地存储中读取缓存的用户认证信息。

// 在App的onLaunch或onShow中预加载用户认证信息
App({
  onLaunchfunction ({
    // 尝试从本地存储中获取用户认证信息
    const userAuthInfo = wx.getStorageSync('userAuthInfo');
    
    // 如果存在认证信息,则可以直接使用;如果不存在,则可能需要用户重新登录
    if (userAuthInfo) {
      // 认证信息已加载,可以进行后续操作
      this.globalData.userAuthInfo = userAuthInfo;
    } else {
      // 认证信息不存在,可能需要跳转到登录页面
      // 这里可以设置一个标志位,在后续页面加载时判断是否需要登录
    }
  },
  
  globalData: {
    userAuthInfonull
  }
});
2.3 页面加载时使用预加载的认证信息
// 在某个页面的onLoad或onShow函数中
Page({
  onLoadfunction ({
    const app = getApp();
    const userAuthInfo = app.globalData.userAuthInfo;
    
    if (userAuthInfo) {
      // 使用预加载的认证信息进行后续操作,如请求用户数据等
      this.fetchUserData(userAuthInfo.token);
    } else {
      // 跳转到登录页面或显示登录提示
    }
  },
  
  fetchUserDatafunction (token{
    // 使用token发起网络请求获取用户数据
    // ...
  }
});
2.4 处理认证信息过期或无效的情况
// 在网络请求返回认证失败时
if (response.data.error === 'auth_failed') {
  // 清除本地存储中的认证信息
  wx.removeStorageSync('userAuthInfo');
  // 跳转到登录页面或显示登录提示
}

其他优化方式(常规优化,具体问题具体分析)

  1. 图片优化:使用适当的图片格式(如WebP)和压缩算法来减小图片体积,提高加载速度。同时,可以利用懒加载技术,只在用户滚动到图片可见区域时再进行加载。

  2. 减少HTTP请求次数:通过合并和减少资源文件,以及使用缓存技术,来减少小程序与服务器之间的HTTP请求次数,从而提高性能。

  3. 使用Page级别数据缓存:对于在多个页面之间共享的数据,使用Page级别的数据缓存可以减少不必要的网络请求。

  4. 减少setData调用:setData()是触发小程序视图更新的方法,频繁调用可能会影响性能。因此,应尽量减少setData的调用次数,并尽量合并多次修改到一次setData调用中。

  5. 骨架屏:骨架屏以灰色区块展示页面大致结构,避免用户看到空白页面或误以为加载失败。同时,骨架屏还能减少因异步渲染导致的页面内容跳动,为用户提供更流畅的加载体验。


最后

还没有使用过我们刷题网站(https://fe.ecool.fun/)或者前端面试题宝典的同学,如果近期准备或者正在找工作,千万不要错过,我们的题库主打无广告和更新快哦~。

老规矩,也给我们团队的辅导服务打个广告。