首頁 >微信小程式 >小程式開發 >深入聊聊小程式中怎麼進行圖片優化

深入聊聊小程式中怎麼進行圖片優化

青灯夜游
青灯夜游轉載
2021-11-19 19:58:444876瀏覽

這篇文章跟大家分享一個小程式實戰,看看小程式中怎麼進行圖片優化,希望對大家有幫助!

深入聊聊小程式中怎麼進行圖片優化

前端的效能最佳化,圖片優化是不可或缺的重要環節,大部分網站頁面的組成都少不了圖片的渲染。尤其在電商類項目,往往存在大量的圖片,如 banner 廣告圖,菜單導航圖,商品列表圖等。圖片載入數量多以及圖片體積過大往往會影響頁面載入速度,造成不良的使用者體驗。 【相關學習推薦:小程式開發教學

優化方案

基於上述問題的主要問題是圖片數量和圖片體積,所以應該怎麼提高圖片載入速度,提升使用者體驗。其實圖片優化有非常多且優秀的方案,都可以從中藉鑑,最後我們將圖片進行不同方向的整體優化。

深入聊聊小程式中怎麼進行圖片優化

使用適當的圖片格式

#目前廣泛應用的WEB 圖片格式有JPEG/JPG、PNG、GIF、WebP、 Base64、SVG 等,這些格式都有各自的特點,以下大概簡單總結如下:

深入聊聊小程式中怎麼進行圖片優化

使用合適的圖片格式通常可以帶來更小的圖片位元組大小,透過合理壓縮率,可以減少圖片大小,且不影響圖片品質。

降低網路傳輸

小程式使用騰訊雲圖片伺服器,提供許多圖片處理功能,例如圖片縮放、圖片降質,格式轉換,圖片裁切、圖片圓角等功能。這些功能可以透過在圖片URL中加入規定參數就能實現,圖片伺服器會根據參數設定提前將圖片處理完成並儲存到CDN伺服器,如此大大的減少圖片傳輸大小。

目前後台介面下發回傳的圖片URL 都是未設定圖片參數預處理,例如一張800x800 尺寸高畫質的商品圖,體積大概300k 左右,這樣就很容易導致圖片載入和渲染慢、使用者流量消耗大,嚴重影響了使用者體驗。所以我們結合騰訊雲的圖片處理功能,網路圖片載入前,先偵測是否為騰訊雲網域的圖片URL,如果網域名稱匹配,對圖片URL進行預處理,預處理包含新增縮放參數新增降質參數新增WebP參數的方式減少圖片網路傳輸大小

我們先看一張透過圖片伺服器是騰訊雲圖片處理能力,透過設定圖片縮放/降質/WebP,一張尺寸800x800,體積246KB圖片,最後輸出生成25.6KB,圖片體積足足減少了80%,效果顯著。

深入聊聊小程式中怎麼進行圖片優化

圖片縮放

目前業務後台都是原圖上傳,原始圖尺寸可能比客戶端實際顯示的尺寸要大,一方面導致圖片加載慢,另一方面導致用戶流量的浪費,其​​中如果是一張很大尺寸圖片加載也會影響渲染性能,會讓用戶感覺卡頓,影響用戶體驗。透過新增縮放參數的方式,指定圖片伺服器下發更小和更符合實際顯示size的圖片尺寸。

圖片降質

圖片伺服器支援圖片質量,取值範圍0-100,預設值為原圖質量,透過降低圖片品質可以減少圖片大小,但是品質降低太多也會影響圖片的顯示效果,網路預設降圖片品質參數設定為85,同時透過小程式提供的:wx.getNetworkTypewx.onNetworkStatusChangeoffNetworkStatusChange的介面監聽網路狀態變化來取得目前使用者的網路類型networkType##4G網絡,則圖片品質會動態設定為80,對於大部分業務狀況,一方面可以大幅減少圖片下載大小和保證使用者使用體驗,另一方面節省使用者瀏覽,目前新增圖片降質參數至少可以減少

30-40%###的圖片大小。 ###
/**
 * 设置网络情况
 */
const setNetwork = (res: Record<string, any>) => {
  const { isConnected = true, networkType = &#39;wifi&#39; } = res;

  this.globalData.isConnected = isConnected;
  this.globalData.networkType = networkType.toLowerCase();
  this.events.emit(EventsEnum.UPDATE_NETWORK, networkType);
};

wx.getNetworkType({ success: (res) => setNetwork(res) });
wx.offNetworkStatusChange((res) => setNetwork(res));
wx.onNetworkStatusChange((res) => setNetwork(res));
/**
 * 根据网络环境设置不同质量图片
 */
const ImageQuality: Record<string, number> = {
  wifi: 85,
  &#39;5g&#39;: 85,
  &#39;4g&#39;: 80,
  &#39;3g&#39;: 60,
  &#39;2g&#39;: 60,
};

/**
 * 获取图片质量
 */
export const getImageQuality = () => ImageQuality[getApp().globalData.networkType ?? &#39;wifi&#39;];
使用WebP

前面簡單介紹不同的圖片格式都有各自的優缺點和使用場景,其中WebP 圖片格式提供有損壓縮與無損壓縮的圖片格式。依照Google官方的數據,與PNG相比,WebP無損圖像的位元組數要少26% WebP有損圖像比同類JPG圖像位元組數少25-34%。現如今各大網路公司的產品都已經使用了,如淘寶、京東和美團等。

這裡放一個 WebP 範例連結(GIF、PNG、JPG 轉 Webp),直覺感受 WebP 在圖片大小上的優點。

深入聊聊小程式中怎麼進行圖片優化

在行動端中WebP的相容性,大部分數位用戶都已經支援了Can I use... Support tables for HTML5, CSS3, etc

深入聊聊小程式中怎麼進行圖片優化

針對png/jpg圖片格式,自動新增WebP參數,轉成WebP圖片格式。雖然WebP比較png/jpg圖片解碼可能需要更長時間,但相對網路傳輸速度提升還是很大。目前 ios 13系統版本有不少用戶量的佔比,小程式端取得目前系統版本,降級處理不加入WebP參數。

// 检查是否支持webp格式
const checkSupportWebp = () => {
  const { system } = wx.getSystemInfoSync();
  const [platform, version] = system.split(&#39; &#39;);

  if (platform.toLocaleUpperCase() === PlatformEnum.IOS) {
    return Number(version.split(&#39;.&#39;)[0]) > IOS_VERSION_13;
  }

  return true; // 默认支持webp格式
};

提示:由於目前圖片伺服器不支援、SVG、GIFWebP,並沒有做處理

優化效果

測試我們小程式首頁清單介面載入圖片,來比較優化前後的效果

##10523K315K #248M10069M #38M

深入聊聊小程式中怎麼進行圖片優化

经过我们通过使用腾讯云图片服务器的图片处理功能,以及动态处理图片格式的方式,减少图片体积,提高图片加载速度,带来的收益比非常可观的

图片懒加载

懒加载是一种性能优化的方式,将页面内未出现在可视区域内的图片先不做加载, 等到滚动到可视区域后再去加载,对于页面加载性能上会有很大的提升,也提高了用户体验。

实现原理

使用小程序提供Intersection Observer API,监听某些节点是否可以被用户看见、有多大比例可以被用户看见。这样我们就能判断图片元素是否在可是范围中,进行图片加载。

我们基于小程序的Intersection Observer API,封装一个监听模块曝光 IntersectionObserver函数工具,提供以下用法

import IntersectionObserver from &#39;utils/observer/observer&#39;;

const ob = new IntersectionObserver({
  selector: &#39;.goods-item&#39;, // 指定监听的目标节点元素
  observeAll: true, // 是否同时观测多个目标节点
  context: this, // 小程序 this 对象实例
  delay: 200, // 调用 onFinal 方法的间隔时间,默认 200ms
  onEach: ({ dataset }) => {
    // 每一次触发监听调用时,触发 onEach 方法,可以对数据进行一些过滤处理
    const { key } = dataset || {};
    return key;
  },
  onFinal: (data) => {
    // 在触发监听调用一段时间 delay 后,会调用一次 onFinal 方法,可以进行埋点上报
    if (!data) return;
    console.log(&#39;module view data&#39;, data);
  },
});

// 内置函数方法,如下:
ob.connect(); // 开始监听
ob.disconnect(); // 停止监听
ob.reconnect(); // 重置监听

然后在我们的FreeImage图片组件,添加可视区域加载图片的功能,以下是部分代码

import IntersectionObserver from &#39;utils/observer&#39;;

Component({
  properties: {
    src: String,
    /**
     * 是否开启可视区域加载图片
     */
    observer: {
      type: Boolean,
      value: false,
    },
    ....
  },

  data: {
    isObserver: false,
    ...
  },

  lifetimes: {
    attached() {
      // 开启可视区域加载图片
      if (this.data.observer) {
        this.createObserver();
      }
    },
  },
  methods: {
    ...

    /**
     * 监听图片是否进入可视区域
     */
    createObserver() {
      const ob = new IntersectionObserver({
        selector: &#39;.free-image&#39;,
        observeAll: true,
        context: this,
        onFinal: (data = []) => {
          data.forEach((item: any) => {
            this.setData({
              isObserver: true,
            });
            ob.disconnect(); // 取消监听
          });
        },
      });

      ob.connect(); // 开始监听
    }
  }
})
<free-image observer src="{{ src }}" />

优化效果

测试我们小程序首页列表,使用图片懒加载的效果

深入聊聊小程式中怎麼進行圖片優化

通过使用图片懒加载的功能,减少图片数量的加载,有效提高页面加载性能。在上述我们已经对图片体积进行优化过,所以在我们小程序中,只有在网络情况较差的情况下,才会自动开启图片懒加载功能。

优化请求数

我们项目中有很多本地图片资源,比如一些 icon 图标、标签类切图、背景图、图片按钮等。而小程序分包大小是有限制:整个小程序所有分包大小不超过 20M,而单个分包/主包大小不能超过 2M。所以为了减轻小程序体积,本地图片资源需要进行调整,比如图片压缩、上传到 CDN 服务器。这样能减少了小程序主包大小,而大部分图片都在腾讯云 CDN 服务器中,虽然可以加速资源的请求速度,当页面打开需要同时下载大量的图片的话,就会严重影响了用户的使用体验。

针对此问题,需要找到权衡点来实现来优化请求数,首先我们把图片资源进行分类,以及使用场景,最后确定我们方案如下:

  • 较大体积的图片,选择上传到 CDN 服务器
  • 单色图标使用 iconfont 字体图标,多彩图标则使用svg格式
  • 标签类的图片,则生成雪碧图之后上传到 CDN 服务器
  • 图片体积小于10KB,结合使用场景,则考虑base64 ,比如一张图片体积为3KB的背景图,由于小程序css background不支持本地图片引入,可以使用 base64 方式实现

其他策略

大图检测

实现大图检测机制,及时发现图片不符合规范的问题,当发现图片尺寸太大,不符合商品图尺寸标准时会进行上报。在小程序开发版/体验版中,当我们设置开启Debug模式,图片组件FreeImage会自动检测到大图片时,显示当前图片尺寸、以及设置图片高亮/翻转的方式提醒运营同学和设计同学进行处理

深入聊聊小程式中怎麼進行圖片優化

加载失败处理

使用腾讯云图片处理功能,URL预处理转换后得新 URL,可能会存在少量图片不存在的异常场景导致加载失败。遇到图片加载失败时,我们还是需要重新加载原始图片 URL, 之后会将错误图片 URL 上报到监控平台,方便之后调整 URL 预处理转换规则,同时也发现一部分错误的图片 URL 推动业务修改。

这是我们图片组件FreeImage 处理图片加载失败,以下是部分代码

onError(event: WechatMiniprogram.TouchEvent) {
  const { src, useCosImage } = this.data;

  this.setData({
    loading: false,
    error: true,
    lazy: &#39;error&#39;,
  });

  // 判断是否腾讯云服务的图片
  if (useCosImage) {
    wx.nextTick(() => {
      // 重新加载原生图片
      this.setData({
        formattedSrc: src, // src 是原图地址
      });
    });
  }

  // 上报图片加载失败
  app.aegis.report(AegisEnum.IMAGE_LOAD_FAIL, {
    src,
    errMsg: event?.detail.errMsg,
  });

  this.triggerEvent(&#39;error&#39;, event.detail);
}
图片请求数检查

使用小程序开发者工具的体验评分功能,体验评分是一项给小程序的体验好坏打分的功能,它会在小程序运行过程中实时检查,分析出一些可能导致体验不好的地方,并且定位出哪里有问题,以及给出一些优化建议。

深入聊聊小程式中怎麼進行圖片優化

通过体验评分的结果,可以分析我们存在短时间内发起太多的图片请求,以及存在图片太大而有效显示区域较小。所以根据分析的结果,开发需要合理控制数量,可考虑使用雪碧图技术、拆分域名或在屏幕外的图片使用懒加载等。

上传压缩

图片在上传前在保持可接受的清晰度范围内同时减少文件大小,进行合理压缩。现如今有很多不错的图片压缩插件工具,就不在详情介绍了。

推荐一个比较优秀的图片压缩网站:TinyPNG使用智能有损压缩技术将您的 WebP, PNG and JPEG 图片的文件大小降低

更多编程相关知识,请访问:编程入门!!

優化前 圖片數 不支援WebP 支援WebP
#2300K (降低77% ) (降低86% )
(降低72% ) (降低84% )

以上是深入聊聊小程式中怎麼進行圖片優化的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:juejin.cn。如有侵權,請聯絡admin@php.cn刪除