日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

简单A/BTest验证图片懒加载效果

發布時間:2023/12/20 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 简单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; }

實現過程

  • 根據傳入的圖片鏈接數組渲染image標簽:
  • 設置src為空;
  • 設置唯一的class(用于查找到唯一的標簽,添加監聽);
  • 在DOM渲染完成后(ready事件),添加IntersectionObserver監聽:
  • 接口兼容性判斷,向后兼容;
  • 根據上面設置的唯一class找到DOM節點,給所有圖片DOM節點添加IntersectionObserver監聽;
  • 用戶滾動(或者一進到頁面就看到了圖片)觸發添加IntersectionObserver回調,加載圖片
  • 設置當前圖片鏈接,加載圖片;
  • 刪除當前節點監聽;
  • 具體接口請參考:小程序中的IntersectionObserver接口

    補充-體驗相關:圖片應設置默認寬高(小程序本身有設置),圖片加載前后高度變化盡可能小一些,對頁面結構影響相對小,給用戶觀感會好很多。

    二,預期效果

    圖片懶加載主要節省了用戶沒看到的圖片的加載流量,節省流量在邏輯上是可以預期的。

    但不同業務,不同場景用戶的瀏覽情況不一樣,例如當用戶想買這個商品時,一般會認真瀏覽所有的商品圖片,這個時候是會加載完所有的圖片的,當然用戶也沒有浪費流量。而當用戶只是從列表頁點進來看看簡單的介紹時,用戶往往不會看商品詳情圖片,或者說不會看完所有的,那這部分沒有顯示圖片的流量就能被節省下來。

    邏輯推導出來的效果沒有問題,符合預期。下面我們來看看在線上產品中的效果如何:到底能為用戶節省多少流量?

    三,A/BTest驗證

    對比驗證

    核心在于控制變量法。

    為了知道使用圖片懶加載列表組件**“到底能為用戶節省多少流量”,我們需要對比優化策略上線前后平均每個用戶在商品詳情頁花費的流量多少**。

    簡化到方便統計:

  • 平均每個用戶在商品詳情頁花費的流量
  • 平均每個用戶在商品詳情頁瀏覽的圖片數量(假設每張圖片的大小一致,實際上是30k~150k/張)
  • 平均每個用戶在商品詳情頁加載的圖片比例(抹平不同商品詳情頁圖片數量不一樣的差異)
  • 結論推導:如果圖片加載比例在應用了優化策略后下降很多,說明圖片懶加載優化能節省用戶大量流量,如果下降不多,證明該業務該場景下實際優化意義不大。
  • 傳統方法

    先統計原來一周內“平均每個用戶在商品詳情頁加載的圖片比例”,再統計圖片加載優化策略上線后接下來一周內加載比例,進行對比,共耗時兩周。(取完整一周作為統計周期是為了排除時間因素帶來的影響)

    實際統計過程如下:

  • 給所有image標簽綁定bindload事件,圖片加載完成后計數 + 1;
  • 離開頁面前(onUnload,onHide / 或別的觸發頁面跳走的事件),計算加載比例 = 圖片加載數量 / 圖片總數
  • 上報該比例;
  • 后臺統計:平均圖片加載比例 = 所有上報加載比例之和 / 上報次數
  • 高效的A/BTest

    A/BTest相信大家都理解,A/BTest的核心優勢在于能在線上并行測試多個方案。例如上面為了獲取前后兩個圖片加載比率,我們需要耗時兩周,而如果采用A/BTest,隨機將用戶分成兩半,一半執行原有的圖片加載策略,一半執行優化后的圖片加載策略,我們只需要耗費一周就能得到我們想要的結果。

    兩周 => 一周 是A/BTest給我們帶來最直觀的收益,畢竟時間先機對于互聯網公司的重要性不用再多說,而A/BTest因其并行性帶來測試環境更加相似的特點則能減少別的無關因素影響(例如這一周沒有搞活動,下一周確搞了運營活動,統計數據可能會產生誤差),A/BTest更多相關內容請參考數據分析領域的沉淀,我就不班門弄斧了。

    ** 真的需要A/BTest嗎?**看到這里說不定有同學已經發現,上面這個優化對比,根本不需要測兩個圖片加載比例,因為優化前的圖片加載比例就是100%(全加載),因此根本用不上A/BTest,光測優化后的圖片加載比例就行。說得很對!這個優化比較簡單,理論上也能直觀推導出結果。但如果是要在這個圖片方案上做調整,例如對比上面提到的方案二,我們就不能直觀推導出結果了,此時A/BTest將能發揮重要作用!

    統計過程和上面傳統方法的類似,就不贅述了,區別僅在于上報的時候加上參數來區分兩種圖片加載方案,下面重點說說:

    簡單的A/BTest實現 - 隨機選取用戶開啟圖片加載優化:

  • 頁面加載時,Math.random() > 0.5將用戶隨機分成兩半;
  • 將該用戶類型記錄進cookie里,避免下次進來再次被分組;
  • 一般用戶開啟lazyload;
  • 統計上報;
  • /*** lazyload-list* imgs: 圖片鏈接數組,* lazyload: 是否開啟lazyload功能,默認開啟* preloadCount: 預加載圖片數量* <lazyload-list imgs="{{intros}}"></lazyload-list>*/ Component({properties: {imgs: {type: Array,value: [],},lazyload: {type: Boolean,value: true,},preloadCount: {type: Number,value: 1}},data: {lazyImgs: [],classNote: 'lazy-img-',loadedCount: 0 // 圖片加載數量統計},ready: function() {// A/BTest: 隨機選取用戶var key = 'lazyloadUserType';var userType = wx.getStorageSync(key);if (!userType) {// 設置用戶類型var lazyloadOn = Math.random() > 0.5;userType = lazyloadOn ? 'lazy' : 'normal';wx.setStorageSync(key, userType);}// 根據用戶類型啟用不同加載策略if (userType === 'lazy') {// 接口兼容性判斷,不支持新特性則回退到即時加載的方案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();}} else {this.setData({ lazyload: false });}},detached: function() {// 圖片加載比例計算var loadRate = (this.data.loadedCount/this.data.imgs.length).toFixed(4);// console.log(loadRate);// 數據上報},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})})});},onImgLoad: function (e) {// 圖片加載數量統計this.data.loadedCount += 1;}} })

    四,總結啟發

    經過一周的統計分析,使用圖片懶加載列表組件后,圖片加載比例:

    // 2018-11-09~11-11線上數據

    100% => 58% ↓42%

    以上僅是特定項目特定頁面的統計數據,僅供大家參考。

    總結

    從結果數據可以看到圖片懶加載是web流量優化的基礎,尤其是在長圖片列表有明顯的差異。應該將列表圖片懶加載優化看做雪碧圖壓縮這種基礎優化,有助于提升web應用的整體表現。

    優化雖不復雜,但“確定目標,方案分析選擇,預期推導,A/BTest驗證,決策”這個方法能穩妥地解決問題。

    啟發

    也叫TodoList,或者社區說法,挖坑。
    需求繁忙,期待學有余力的朋友們共同探索。

  • 采用方案二覆蓋低版本機型 - 開源社區以及有很多版本;
  • 封裝純js邏輯,方便swiper等組件實現圖片懶加載;
  • 學習現成的A/BTest系統:技術賦能產品做決策;
  • 總結

    以上是生活随笔為你收集整理的简单A/BTest验证图片懒加载效果的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。