優(yōu)化前
這里我挑選了一些項目里面比較大的圖片,還有我之前保存的一些背景圖,共計12
張,上傳到阿里云oss
,然后寫了一個demo去渲染圖片,這里我們先看看加載時間。
可以看到,一旦文件大小到了1M
以上,加載基本都在1秒
以上了,而且加載最慢的一張圖片大小為2.4M
;加載耗時5.27
秒。然而在這個小程序中,有非常多的瀑布流圖片展示,需要加載的圖片也非常多,這對于這種圖片展示類的小程序來說,簡直是非常糟糕的體驗。下面我們就分析一下,如何提升用戶體驗,縮短加載時間。
分析優(yōu)化
這里我總結(jié)了一些常見圖片優(yōu)化策略,方法如下:
下面我們就根據(jù)總結(jié)的優(yōu)化策略進行優(yōu)化,具體如下:
優(yōu)化1:使用webp
格式的圖片
首先我們知道,在小程序中是支持webp
格式的圖片的,所以我們可以將圖片轉(zhuǎn)換為webp
格式,這樣可以減少圖片體積,提升加載速度。
公司使用的阿里云oss
進行圖片存儲,阿里云oss是支持格式轉(zhuǎn)換的,只需要在圖片url后面加一定的參數(shù)即可,我們可以給圖片后面加上?x-oss-process=image/format,webp
即可。
// 原本圖片路徑:
let url =' https://lonjin.oss-cn-beijing.aliyuncs.com/weixin-test/3%20%282%2917047050403470042.png'
// 轉(zhuǎn)化為webp格式的圖片路徑:
let url =' https://lonjin.oss-cn-beijing.aliyuncs.com/weixin-test/3%20%282%2917047050403470042.png?x-oss-process=image/format,webp'
清除緩存,刷新頁面,再來看加載時間:
可以看到,加載時間大幅縮短,圖片格式轉(zhuǎn)化后,圖片大小已經(jīng)非常小了,最大的一張圖片僅僅有730kb
;隨之加載時間也大幅縮短,最慢的一張圖片從之前的5.27秒縮短為1.71秒,加載速度提升了3倍
!其他的圖片加載基本都在500ms
左右,加載速度提升也是比較明顯。
這里我們還需要注意一下webp
圖片格式的支持范圍,我這里使用的uni-app
做為demo,查了一下文檔,支持范圍如下:
Android4以上(含)、iOS14以上(含)系統(tǒng)內(nèi)置支持webp,此時,不管web、小程序、app,也不管vue/nvue/uvue都可以直接使用webp; iOS14以下,app-vue下,iOS不支持;app-nvue/uvue下,iOS支持;微信小程序2.9.0起,配置屬性webp為true時iOS支持;
所以如果考慮一些特殊情況,我們可以進行一些特殊情況下的處理。
如果文件是直接放在服務(wù)器上的,我們可以借助一些第三方工具來把圖片批量轉(zhuǎn)化為webp
格式;比如convertio.co
優(yōu)化2:根據(jù)需求設(shè)置適當(dāng)?shù)姆直媛?/h3>
阿里云oss支持在圖片后面加上參數(shù)來設(shè)置圖片的分辨率,我這里寫的demo中,image
標(biāo)簽圖片寬度均為小程序圖片默認(rèn)寬度;即為width: 320px;
,所以我們可以給圖片url后面加上/resize,w_320
即可,其中w_320
表示圖片寬度為320px
。
// 原本圖片路徑:
let url =' https://lonjin.oss-cn-beijing.aliyuncs.com/weixin-test/3%20%282%2917047050403470042.png?x-oss-process=image/format,webp'
// 設(shè)置寬度后的圖片路徑:
let url =' https://lonjin.oss-cn-beijing.aliyuncs.com/weixin-test/3%20%282%2917047050403470042.png?x-oss-process=image/format,webp/resize,w_320'
清除緩存,刷新頁面,再來看加載時間:
圖片大小大幅度減少,最大的一張圖片僅僅有15.4 kB
;隨之加載時間也大幅縮短,最慢的一張圖片從之前的1.71秒縮短為316毫秒,加載速度提升了5倍
!這時候所有圖片的加載速度全部沒有超過1秒,最大不超過350ms
;基本上算是質(zhì)的飛躍了。不過需要注意的是,圖片分辨率還是需要結(jié)合業(yè)務(wù)需求進行調(diào)整的,如果要求必須高清,不建議設(shè)置太小的分辨率。不過我們可以寫一個檢測用戶網(wǎng)絡(luò)狀態(tài)的方法;在不同的網(wǎng)絡(luò)環(huán)境下加載不同分辨率的圖片。
優(yōu)化3:使用雪碧圖
雪碧圖,也叫Sprite
,是將多個小圖片合并成一張大圖,然后在頁面中使用background-image
和background-position
屬性來顯示其中的某一張圖片。這樣可以減少圖片的加載次數(shù),減少圖片的大小,同時減少圖片的加載時間。在項目中難免會有很多小圖標(biāo),我們就可以使用雪碧圖的方式來使用,減少請求次數(shù)。這里我就不做展示了。
優(yōu)化4:合理使用占位圖片
通常情況下,為了內(nèi)容的動態(tài)展示,需要通過網(wǎng)絡(luò)請求從接口中獲取圖片的url。如果在網(wǎng)絡(luò)慢的情況下,image加載圖片的過程可能會非常慢,在請求完成之前頁面都會因為沒有數(shù)據(jù)而呈現(xiàn)一片空白,這是非常差的用戶體驗,這里我們可以借助小程序image標(biāo)簽上的@error
和@load
事件來實現(xiàn)占位圖片的展示。我們可以根據(jù)需求去封裝一個LoadImage
組件統(tǒng)一處理,上面提到的優(yōu)化1
、優(yōu)化2
也可以通過定義參數(shù)實現(xiàn)批量添加,同時我們也可以給組件加上lazyLoad
,減輕小程序加載壓力。
組件具體代碼如下:
<template>
<view class="loadImage-wrapper">
<image v-if="isLoading" :src="defaultImage" :mode="mode" :lazy-load="lazyLoad" />
<image :class="[isLoading ? 'before-load' : '']" :src="imageUrl" :mode="mode" :lazy-load="lazyLoad"
@load="imageLoad" />
</view>
</template>
<script>
export default {
props: {
/**
* 占位圖
* @default /static/images/load-image.png
*/
defaultImage: {
type: String,
default: '/static/load-image.png',
},
/**
* 是否使用webp
* @default false
*/
useWebp: {
type: Boolean,
default: false,
},
/**
* 圖片的顯示模式
* @default scaleToFill
*/
mode: {
type: String,
default: 'scaleToFill',
},
/**
* 圖片加載分辨率-寬度
* @default
*/
width: {
type: String,
default: '',
},
/**
* 是否懶加載
* @default true
*/
lazyLoad: {
type: Boolean,
default: true,
},
/**
* 圖片地址
* @default
*/
src: {
type: String,
default: '',
},
},
data() {
return {
isLoading: true,
}
},
methods: {
imageLoad() {
this.isLoading = false
},
},
computed: {
imageUrl() {
let url = this.src + '?'
this.useWebp && (url += 'x-oss-process=image/format,webp')
this.width && (url += '/resize,w_' + this.width)
return url
}
},
}
</script>
<style lang="scss" scoped>
.loadImage-wrapper {
.before-load {
width: 0;
height: 0;
opacity: 0;
}
}
</style>
使用方式如下:
<template>
<view class="list">
<load-image v-for="(item, index) in list" :src="item" :lazyLoad="false" useWebp :width="320" :key="index" />
</view>
</template>
優(yōu)化后效果對比
我們再來看一下優(yōu)化前后的加載時間對比:
- 優(yōu)化前:
- 優(yōu)化后:
我們用一張圖片來做對比:
圖片名稱 | 大小 | 加載時間 | |
---|---|---|---|
優(yōu)化前 | wallhaven-we3z86.jpeg | 2.4MB | 5.27s |
優(yōu)化后 | wallhaven-we3z86.jpeg | 15.3KB | 23ms |
可以看到相對體積而言,縮小了99.4%
;相對加載時間,縮短了5.25
秒,在幾乎不影響圖片質(zhì)量的情況下,極大的提升了用戶體驗。
總結(jié)
關(guān)于小程序的圖片優(yōu)化,我們可以根據(jù)業(yè)務(wù)需求以及技術(shù)支持來選擇不同的方案,這里我只列出了幾個最常用的方案,如果業(yè)務(wù)需求比較復(fù)雜,可以多嘗試一些方案。
原文作者:隴錦