简单A/BTest验证图片懒加载效果
Demo視頻
文章結構
文章基本思路:“目的 => 方案 => 驗證 => 總結啟發”
一,圖片懶加載實現
二,預期效果
三,A/BTest驗證
四,總結
一,圖片懶加載實現
實現圖片懶加載的目的是在不影響用戶體驗的前提下,盡可能節省用戶流量甚至是電量。(可以參考Why lazy load images or video instead of just loading them?)
方案選擇
圖片懶加載的本質是將某一圖片的加載推遲到用戶看到或即將看到該圖片的時候。實現圖片懶加載目前有三種方案:
| 一. 小程序image組件的lazy-load屬性 | 小程序 - image | ①不支持配置(加載時機,預加載數量) ②僅在page和scroll-view中生效(意味著很難通用) |
| 二,頁面滾動監聽 | 小程序頁面監聽頁面滾動(onPageScroll),滾動時逐一比較圖片節點的top值(可由wx.createSelectorQuery().select('yourselector’).boundingClientRect((ret)=>{}).exec()獲得)與滾動位置的關系 | 監聽滑動 & 遍歷所有節點會對滾動性能產生一定的影響(如果節點從上到下遍歷,能做一些優化,也能達到較好的效果) |
| 三,IntersectionObserver | 采用IntersectionObserver API,交由瀏覽器內核底層判斷圖片是否與視窗相交,減少內核層與js層的跨進程通信,性能更好(小程序基礎庫1.9.3開始支持) | 不兼容低版本瀏覽器內核 |
補充:
①除了方案一,方案二三都同時支持小程序和H5,這里僅以小程序為例。
②如有別的方案歡迎分享補充_
基于上面的方案分析和當前用戶系統占用率分布(IntersectionObserver API支持率大于80%),我決定采用IntersectionObserver API來對當前項目做漸進式增強,后續隨著用戶設備更新,將能實現100%的優化覆蓋。
方案實現
參考性能更優越的小程序圖片懶加載方式,感謝分享!注意:原文章方案存在Android快速滾動到底部沒有觸發加載 的問題。
從前面的視頻我們可以看到,優化的對象是商品詳情圖片列表,考慮到復用性,我把圖片列表封裝成lazyload-list組件,源碼如下:
/*** lazyload-list* imgs: 圖片鏈接數組,* lazyload: 是否開啟lazyload功能,默認開啟* <lazyload-list imgs="{{intros}}"></lazyload-list>*/ Component({properties: {imgs: {type: Array,value: [],},lazyload: {type: Boolean,value: true,}},data: {lazyImgs: [],classNote: 'lazy-img-'},ready: function() {// 接口兼容性判斷,不支持新特性則回退到即時加載的方案if (!this.createIntersectionObserver) {// @TODO 可以改用基于滾動檢測 & 高度判斷的實現方案this.setData({ lazyload: false });} else {var lazyImgs = [];this.data.imgs.forEach(function(img) {lazyImgs.push({url: img,loaded: false})});this.setData({ lazyImgs: lazyImgs });this.lazyloadImg();}},methods: {// 說明:原方案用同一個observer監聽第一張圖片加載,然后再監聽下一張圖片加載,// 但在安卓系統下極快速滑動會出現第二張圖片沒有觸發加載就跳到后面的圖片的情況,導致后面的圖片都加載不出來。// 因此為了穩妥起見,給每一張圖片設置單獨的observer。lazyloadImg: function () {var that = this;this.data.lazyImgs.forEach(function(img, i) {var intersectionObserver = that.createIntersectionObserver();var observeSelector = '.' + that.data.classNote + i; // css選擇器// bottom:300 指距離底部以下300px即會觸發事件intersectionObserver.relativeToViewport({bottom: 300}).observe(observeSelector, function(res) {intersectionObserver.disconnect();img.loaded = true;that.setData({['lazyImgs['+ i +']']: img})})});}} }) <view><view wx:for="{{lazyImgs}}" wx:key="{{item}}" class="{{classNote + index}}"><image class="img" mode="widthFix" src="{{lazyload && !item.loaded ? '' : item.url}}"/></view> </view> .img {width: 100%;display: block; }實現過程:
具體接口請參考:小程序中的IntersectionObserver接口
補充-體驗相關:圖片應設置默認寬高(小程序本身有設置),圖片加載前后高度變化盡可能小一些,對頁面結構影響相對小,給用戶觀感會好很多。
二,預期效果
圖片懶加載主要節省了用戶沒看到的圖片的加載流量,節省流量在邏輯上是可以預期的。
但不同業務,不同場景用戶的瀏覽情況不一樣,例如當用戶想買這個商品時,一般會認真瀏覽所有的商品圖片,這個時候是會加載完所有的圖片的,當然用戶也沒有浪費流量。而當用戶只是從列表頁點進來看看簡單的介紹時,用戶往往不會看商品詳情圖片,或者說不會看完所有的,那這部分沒有顯示圖片的流量就能被節省下來。
邏輯推導出來的效果沒有問題,符合預期。下面我們來看看在線上產品中的效果如何:到底能為用戶節省多少流量?
三,A/BTest驗證
對比驗證
核心在于控制變量法。
為了知道使用圖片懶加載列表組件**“到底能為用戶節省多少流量”,我們需要對比優化策略上線前后平均每個用戶在商品詳情頁花費的流量多少**。
簡化到方便統計:
↓
↓
↓
傳統方法
先統計原來一周內“平均每個用戶在商品詳情頁加載的圖片比例”,再統計圖片加載優化策略上線后接下來一周內加載比例,進行對比,共耗時兩周。(取完整一周作為統計周期是為了排除時間因素帶來的影響)
實際統計過程如下:
高效的A/BTest
A/BTest相信大家都理解,A/BTest的核心優勢在于能在線上并行測試多個方案。例如上面為了獲取前后兩個圖片加載比率,我們需要耗時兩周,而如果采用A/BTest,隨機將用戶分成兩半,一半執行原有的圖片加載策略,一半執行優化后的圖片加載策略,我們只需要耗費一周就能得到我們想要的結果。
兩周 => 一周 是A/BTest給我們帶來最直觀的收益,畢竟時間先機對于互聯網公司的重要性不用再多說,而A/BTest因其并行性帶來測試環境更加相似的特點則能減少別的無關因素影響(例如這一周沒有搞活動,下一周確搞了運營活動,統計數據可能會產生誤差),A/BTest更多相關內容請參考數據分析領域的沉淀,我就不班門弄斧了。
** 真的需要A/BTest嗎?**看到這里說不定有同學已經發現,上面這個優化對比,根本不需要測兩個圖片加載比例,因為優化前的圖片加載比例就是100%(全加載),因此根本用不上A/BTest,光測優化后的圖片加載比例就行。說得很對!這個優化比較簡單,理論上也能直觀推導出結果。但如果是要在這個圖片方案上做調整,例如對比上面提到的方案二,我們就不能直觀推導出結果了,此時A/BTest將能發揮重要作用!
統計過程和上面傳統方法的類似,就不贅述了,區別僅在于上報的時候加上參數來區分兩種圖片加載方案,下面重點說說:
簡單的A/BTest實現 - 隨機選取用戶開啟圖片加載優化:
四,總結啟發
經過一周的統計分析,使用圖片懶加載列表組件后,圖片加載比例:
// 2018-11-09~11-11線上數據
100% => 58% ↓42%
以上僅是特定項目特定頁面的統計數據,僅供大家參考。
總結
從結果數據可以看到圖片懶加載是web流量優化的基礎,尤其是在長圖片列表有明顯的差異。應該將列表圖片懶加載優化看做雪碧圖壓縮這種基礎優化,有助于提升web應用的整體表現。
優化雖不復雜,但“確定目標,方案分析選擇,預期推導,A/BTest驗證,決策”這個方法能穩妥地解決問題。
啟發
也叫TodoList,或者社區說法,挖坑。
需求繁忙,期待學有余力的朋友們共同探索。
總結
以上是生活随笔為你收集整理的简单A/BTest验证图片懒加载效果的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 中国移动、阿里云、百度天工三大物联网平台
- 下一篇: LDM522-MINI射频读卡模块 迷你