国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

客服訂單詳情頁體驗升級之路

開發(fā) 前端
關(guān)于動態(tài)路由頁面的多平臺復(fù)用:跨技術(shù)棧使用單實例的iframe通信,配合雙向的postMessage事件監(jiān)聽用戶行為觸發(fā)交互;微應(yīng)用內(nèi)使用Module Federation通信,在保障客服使用體驗的同時,節(jié)省了開發(fā)維護成本。


一、背景

作為客服域訪問量最大的頁面之一,訂單詳情頁在客服的日常工作中被用來查閱用戶的訂單信息,以此為進線的買賣家用戶提供更好的購買服務(wù),進而提升用戶的滿意度。無論是一二線客服還是客服管理者,都能在日常使用的系統(tǒng)中直接訪問到詳情頁,因此客服訂單詳情頁的入口也比較多,目前已經(jīng)超過了10處。

圖片圖片

隨著得物業(yè)務(wù)的快速發(fā)展,客服訂單詳情頁需要展示的信息越來越多,需要支持的操作也越來越多,在頁面改版前,一個頁面首屏就需要展示80條訂單信息,具體數(shù)量會根據(jù)訂單類型、交易狀態(tài)、物流狀態(tài)等因素而改變。一個頁面最多情況會有200條信息、60個按鈕以及20個訂單標(biāo)簽(不含用戶標(biāo)簽、商品標(biāo)簽),所以會出現(xiàn)一個現(xiàn)象,一個1920*1080分辨率的顯示器(客服常用的分辨率),鼠標(biāo)滾輪需要滾2次才能從頁面的最上方滑到最下方,詳情頁信息截圖如下所示。

圖片圖片

另一方面,貿(mào)然調(diào)整反而會降低客服同學(xué)的工作效率。頁面內(nèi)容、交互變化太大對客服同學(xué)也存有不小的培訓(xùn)成本,因此秉持著變更影響最小化的原則,信息量一直保持著只增不減。

經(jīng)過一段時間的沉淀與打磨,客服訂單詳情頁無論是客服的使用體驗,還是開發(fā)體驗都得到了顯著提升,訂單相關(guān)的TS問題近半年一直保持清零狀態(tài)。這期間做了很多嘗試和漸進式優(yōu)化,本文主要從以下三點具體聊聊對客服訂單詳情頁體驗升級做的一些思考和優(yōu)化。

  • 這么信息全的頁面,幾乎所有客服域平臺都要能直接訪問查閱,一個頁面如何多個系統(tǒng)使用,在保障客服同學(xué)使用體驗的同時,還能節(jié)省開發(fā)同學(xué)維護成本。
  • 信息量大數(shù)據(jù)源多導(dǎo)致頁面加載慢,客服同學(xué)經(jīng)常反饋卡頓,如何對頁面首屏進行秒開優(yōu)化,進一步提升客服同學(xué)的使用體驗。
  • 簡單的改動也需要投入資源,信息模塊復(fù)用率低,如何建設(shè)信息自由編排、信息模塊拔插的能力,最大程度解放產(chǎn)研運同學(xué)生產(chǎn)力。

二、多入口的頁面復(fù)用

1、多實例iframe

最早訂單詳情頁只是客服工單系統(tǒng)中的一個頁面,使用的是Vue2、ElementUI的技術(shù)棧。客服工單系統(tǒng)的定位是后臺管理系統(tǒng),使用門檻較高,更適合管理者使用,所以需要一個面向一二線客服的平臺,章魚工作臺就誕生了。章魚工作臺是基于qiankun微應(yīng)用搭建的,其子應(yīng)用最開始使用Vue3、Vite和Ant Design,那時,如果要在章魚工作臺中訪問客服訂單詳情頁屬于跨應(yīng)用、跨技術(shù)棧通信,使用iframe是成本最小,也是初期最合適的一種方式,這也是頁面復(fù)用的第一個階段:在子應(yīng)用使用多個iframe容器嵌入工單系統(tǒng)中的訂單詳情頁。

圖片圖片

所有訂單詳情頁的使用方只需要在本地創(chuàng)建iframe容器,然后在嵌入訂單詳情頁的訪問地址時傳一些必要的參數(shù)如訂單號、求購單號就能夠正常訪問了,十分便捷。還可以支持一些高級配置供使用方選用,如支持通過url query傳參的方式控制頁面樣式,當(dāng)用于外部嵌入時隱藏主應(yīng)用的菜單和頂部tab欄等等。

圖片圖片

這個階段,初步解決了頁面復(fù)用的問題。但大家都知道iframe的弊端,一二線客服同學(xué)的日常工作中會出現(xiàn)大量的頁面切換,這樣一來,iframe的內(nèi)存占用高、加載緩慢的缺點就被放大開來,這個階段一二線客服經(jīng)常會反饋頁面卡頓,所以迫切需要進一步優(yōu)化。

2、單實例iframe搭配MF遠程組件

對客服工單系統(tǒng)、章魚工作臺兩個平臺的用戶特點、作業(yè)行為進行分析,發(fā)現(xiàn)章魚工作臺的用戶對頁面的體驗要求更高,于是對詳情頁做了第一次優(yōu)化,步入了第二個階段:將訂單詳情頁遷移至章魚工單工作臺,其構(gòu)建方式也由Vite變更為Webpack5,子應(yīng)用之間利用Webpack5的Module Federation特性通過遠程組件的方式進行數(shù)據(jù)通信。另一方面,盡管iframe的缺點明顯,但仍是跨技術(shù)棧應(yīng)用間頁面通信的不錯選擇,將iframe控制在單實例容器中可以最大程度限制其對內(nèi)存的占用。

圖片圖片

這樣一來,詳情頁的入口雖然有10多個,但通信方式都收攏成了三種:遠程組件、單實例iframe、本地組件。所有場景都能覆蓋到,后續(xù)各個入口有復(fù)雜交互的變更或者自定義事件,都能夠在頁面主體做到監(jiān)控和收口,不需要頁面的使用方做額外開發(fā)。

3、技術(shù)實現(xiàn)

3.1、單實例iframe通信

內(nèi)容提供方

  • 詳情接口響應(yīng)后注冊message事件。
  • 監(jiān)聽iframe父級攜帶數(shù)據(jù)變化,更新本地頁面數(shù)據(jù)。
  • 本地頁面交互事件被遠端觸發(fā),發(fā)送當(dāng)前的數(shù)據(jù)給遠端做自定義交互。
/** Vue3 */
/** 1. 詳情接口響應(yīng)后注冊message事件 */
onMounted(() => {
   /** 請求詳情接口 */
  fetchOrderDetail(() => {
    /** query上打上iframe標(biāo)簽,用于確定注冊時機 */
    route.query.iframeRoute && watchParentMessage()
  })
})


/** 2. 監(jiān)聽iframe父級攜帶數(shù)據(jù)變化,更新本地頁面數(shù)據(jù) */
const watchParentMessage = () => {
  window.addEventListener('message', event => {
    const orderNo = event.data.data.orderNo
    if (event.data.type === 'ORDER_CHANGE' && orderNo) {
      /** 更新訂單信息*/
      initStream(orderNo)
    }
  })
}
/** 3. 本地頁面交互事件被遠端觸發(fā),發(fā)送當(dāng)前的數(shù)據(jù)給遠端 */
window.parent.postMessage(
  /** payload: 攜帶的數(shù)據(jù)*/
  {
    type: 'workbenchRoute',
    params: {
      /** 跳轉(zhuǎn)退貨詳情頁 */
      name: 'refundDetail',
      query: {
        // 攜帶數(shù)據(jù)
      },
    },
  },
  /** orgin: 如果想要傳遞給任意窗口,可以將這個參數(shù)設(shè)置為'*' ,為了安全起見,不建議設(shè)置為'*'*/
  '*'
)

內(nèi)容使用方

  • 頁面初始化時注冊message事件。
  • 監(jiān)聽本地訂單單號變化,將新的數(shù)據(jù)傳給遠端。
  • 監(jiān)聽遠端交互和數(shù)據(jù)變化,根據(jù)交互類型做不同的本地處理。
/** Vue2 */


/** 1. 頁面初始化時注冊message事件*/
mounted() {
    window.addEventListener('message', this.callBack, false)
},
/** 2. 監(jiān)聽本地訂單單號變化,將新的數(shù)據(jù)傳給遠端*/
watch: {
    orderNo(newOrderNo) {
        /** 在iframe的contentWindow屬性上掛載postMessage方法*/
       detailIframeRef.contentWindow.postMessage(
        /** payload: 攜帶的數(shù)據(jù)*/
        {
          type: 'ORDER_CHANGE',
          data: {
            orderNo:newOrderNo,
            //其他數(shù)據(jù)
          },
        },
        /** orgin: 如果想要傳遞給任意窗口,可以將這個參數(shù)設(shè)置為'*' ,為了安全起見,不建議設(shè)置為'*'*/
        '*',
      )
    },
},
/** 3. 監(jiān)聽遠端交互和數(shù)據(jù)變化,根據(jù)交互類型做不同的本地處理 */
method: {
    /** callBack: 遠端事件被觸發(fā)后,處理本地回調(diào)邏輯 */
    callBack(event) {
      try {
        if (event.data.type === 'workbenchRoute') {
         switch (event.data.params.name) {
            case 'orderdetail':
              //跳轉(zhuǎn)訂單詳情的handler
              break
            case 'detail':
              //跳轉(zhuǎn)工單詳情的handler
              break
            // 其他交互
            default: 
              //兜底處理
          }
        }
    } catch(error) {
      //異常處理
    }
}

內(nèi)容提供方

  • 配置webpack的MF插件,將整個訂單詳情頁exposes出去
  • 維護詳情頁的props
/** 配置webpack MF插件,將訂單詳情頁exposes出去*/
 new ModuleFederationPlugin({
    filename: 'remoteEntry.js?[hash]',
    library: { type: 'window', name: 'app_ticket' },
    name: 'app_ticket',
    shared: {
    /** 需要共享的依賴 */
    },
    exposes: {
        /** 提供訂單詳情遠程組件*/
      './OrderDetail': './src/views/orderdetail/Index.tsx',
    },
  }),
  • webpack配置需要建議通信的遠端應(yīng)用
  • 使用defineAsyncComponent注冊組件
  • 像本地組件一樣使用遠程組件
/** 1.webpack配置遠端應(yīng)用 */
remotes: {
  app_ticket: getRemoteUrl('app_ticket'),
},
/** 2. 使用defineAsyncComponent注冊組件*/
'OrderDetail': defineAsyncComponent(() => import('app_ticket/OrderDetail')),
/** 3. 像本地組件一樣使用遠程組件*/
<OrderDetail orderNo={orderNo} {...props} />

4、總結(jié)

頁面使用iframe的首屏耗時平均在7076ms,非首屏在2594ms,而MF的首屏只需要1279ms,非首屏更是只需428ms,渲染時間降低了6倍。

圖片圖片

單個頁面的內(nèi)存占用減少到了之前的1/10以內(nèi),關(guān)于模塊聯(lián)邦和遠程組件的更多細節(jié)可以查看Module Federation 在得物客服工單業(yè)務(wù)中的最佳實踐。

圖片圖片

三、首屏秒開優(yōu)化

上一章節(jié)說到使用MF的方式解決了架構(gòu)層面的卡頓問題,但無緩存下頁面仍要2~3s甚至更久才能刷出訂單信息,這時要怎么辦?是的,可以改交互、拆接口。但如果數(shù)據(jù)依賴了大量外域服務(wù)、沒有外域產(chǎn)研資源介入,且要在一周時間做到有效的優(yōu)化,那還能做些什么呢?

1、緩慢原因

由于一些歷史原因,客服訂單詳情頁需要同時展示100+的訂單信息,所有的訂單信息、訂單操作涉及的字段接近200個,而這么多字段其中90%都在一個http接口里面,這個大接口包含了36個dubbo接口,這些接口來自交易正向、逆向、供應(yīng)鏈、商家、商品、用戶以及其他BU。并行的調(diào)用一定會出現(xiàn)短板效應(yīng),只要有一個接口RT(Reaction Time,響應(yīng)時間)慢,就會拉慢整個http接口的響應(yīng)速度,同時出現(xiàn)Timeout的概率也會上升,再加上頁面本身對資源的渲染時間,無緩存下仍要2~3s甚至更久才能刷出訂單信息。這個大接口的平均RT在500ms,P99線的RT達到了1.3s,下圖就是生產(chǎn)環(huán)境下某一次的調(diào)用詳情,耗時在782ms,降RT優(yōu)化首屏渲染刻不容緩。

圖片圖片

除了接口RT耗時高的問題,還有首屏接口并行調(diào)用的問題。90%的字段都在一個大接口里面,剩下10%都是在零零散散的一些小接口里,把這些小接口加起來頁面首屏接口超過6個。我們知道一個Chrome頁簽最多并行處理6個http請求,如果有第7個接口就會進入到Stalled(熄火)狀態(tài),等待前面的某一個接口響應(yīng)完畢后再發(fā)起請求,下圖是一個示例,getTrackTicketInfo接口是頁面首屏的第7個接口,255.14ms就是需要等待的時間。

圖片圖片

根據(jù)上述問題現(xiàn)狀,初步的方案就是接口先聚合再拆分,把所有接口的數(shù)據(jù)聚合到一塊,然后再根據(jù)信息模塊拆分成若干個接口,前端再根據(jù)業(yè)務(wù)場景和用戶行為,去對拆分出來的接口的調(diào)用時機進行優(yōu)化。但是,理想很豐滿,現(xiàn)實很骨感,數(shù)據(jù)量擺在這,很難在短時間去做到這件事情。光把字段梳理全,數(shù)據(jù)來源理清楚就用掉了兩天時間,再考慮到成本和收益后,我們的最終方案就是新增快慢接口,快接口的RT要在200ms以內(nèi),所有拖慢RT的數(shù)據(jù)都放到慢接口中,前端再根據(jù)接口的特性將所有接口分為2個梯隊在不同時間進行調(diào)用,最大程度的減少頁面的首屏渲染時間。

2、接口調(diào)用優(yōu)化

2.1、技術(shù)方案

為了控制頁面并行請求接口數(shù)量和頁面數(shù)據(jù)渲染次數(shù),將除了快慢接口之外,所有零散小接口分為如下兩個梯隊:不依賴詳情大接口反參的首屏信息接口;依賴詳情大接口反參的首屏信息接口、非首屏信息接口。

最終詳情頁首屏接口調(diào)用情況示意圖如下,在能夠聚合依賴大接口反參的首屏信息接口的情況下,頁面只會渲染兩次,第一次是在快詳情接口和第一梯隊接口請求回來之后(使用Promise.all控制數(shù)據(jù)的渲染時機),第二次就是在慢詳情接口請求回來之后。

圖片圖片

使用Promise.all來保證快詳情接口和第一梯隊的接口信息同時渲染,減少頁面渲染次數(shù),從而減少頁面抖動的情況。Promise.all有個缺點就是其中有一個Promise異常,整個就會拋出異常,所以需要對Promise.all包裹的Promise進行二次封裝,保證有一個Promise報錯不會干擾其他接口的請求,具體代碼實現(xiàn)方式如下:

/** 處理promise,保證promise.all使用時相互獨立 */
export const handlerPromise = (api, params) => {
  return new Promise(resolve => {
    api(params)
      .then(resolve)
      .catch(() => resolve({ error: true }))
  })
}


/** 詳情頁首屏請求函數(shù) */
 const fetchOrderDetail = (callback?) => {
 /** 使用handlerPromise封裝過的promise,保證有一個報錯不干擾其他接口請求 */
  Promise.all([quickDetail(), firstLevel1(), firstLevel2()])
    .then(([quickDetailData, firstLevelData1, firstLevelData2]) => {
      // 快詳情接口
      !quickDetailData?.error && quickDetailHandler(quickDetailData)
      // 第一梯隊接口調(diào)用:不依賴詳情反參的首屏信息接口
      !firstLevelData1?.error && firstLevelHandler1(firstLevelData1)
      !firstLevelData2?.error && firstLevelHandler2(firstLevelData2)
      // 執(zhí)行回調(diào)
      nextTick(callback)
    })
    .then(() => {
      // 第二梯隊接口調(diào)用:依賴詳情反參的首屏信息接口、非首屏接口
        secondLevelHandler1()
        secondLevelHandler2()
    })
  // 執(zhí)行慢接口
  fetchSlowOrderDetail()
}

接口調(diào)用順序確認后還有一點需要注意,因為慢接口響應(yīng)耗時較高,在客服同學(xué)快速查詢的工作場景中,可能會在慢接口還在pending,就已經(jīng)切換到下一個訂單了,頁面單實例的場景下,這個時候如果不處理可能會將出現(xiàn)數(shù)據(jù)串臺的情況,不屬于該訂單的數(shù)據(jù)顯示了出來,關(guān)于這一點,需要在慢接口的handler上做如下處理。

/** 慢詳情接口請求 */
 const fetchSlowOrderDetail = () => {
      slowLoading.value = true
      orderApi
        .getDetail(params)
        .then(slowData => {
          /** 防止快速切換訂單導(dǎo)致的數(shù)據(jù)串臺問題 */
          if (slowData?.topInfo?.orderNo === orderNo.value) {
            orderDetail.value = slowData
          }
          slowLoading.value = false
        })
        .catch(() => {
          slowLoading.value = false
        })
    }

2.2、最終效果

優(yōu)化后的Waterfall圖就如下所示,不會再出現(xiàn)灰色的stalled耗時了,而且在228ms后首屏的數(shù)據(jù)就已經(jīng)請求回來了。

圖片圖片

3、大接口優(yōu)化

上面一點解決了首屏接口的調(diào)用問題,接下來是對大詳情接口具體做的一些優(yōu)化:

  • 接口協(xié)議由POST改為GET請求,GET的總耗時是POST的三分之二;Chrome下如果檢測到GET請求的是靜態(tài)資源,則會緩存,如果兩次傳輸?shù)臄?shù)據(jù)相同,第二次以后耗費的時間將在10ms以內(nèi)。另一方面也為后續(xù)工作臺引入Service Worker技術(shù)打下基礎(chǔ)。
  • 新增快詳情接口,將大接口中的響應(yīng)耗時較高的字段整理出來,快接口不再包含這些字段。這些高耗時的字段新增字段級別的loading效果,為了避免快慢接口耗時差異較大,導(dǎo)致一些經(jīng)驗豐富的客服同學(xué)誤以為快接口沒返回數(shù)據(jù)的字段是空數(shù)據(jù),但是這個loading數(shù)量不會超過3處,保持頁面的整潔易讀。

4、總結(jié)

經(jīng)過上述優(yōu)化,快詳情接口RT只需要平均190ms,從之前大接口的470ms下降了41%,首屏渲染時間從873ms降至376ms,下降了57%,95分位567ms,下降了62%。

圖片圖片

首屏優(yōu)化效果明顯,很難再看到反饋詳情頁加載緩慢的VOC了,一定程度地提升了客服的平臺體驗滿意度。

四、信息編排、模版插拔能力建設(shè)

解決了頁面卡頓和首屏加載慢的問題,但仍存在一些問題。這一次在產(chǎn)研運同學(xué)的通力協(xié)作下,如何進一步提升技術(shù)同學(xué)的開發(fā)體驗和客服同學(xué)的使用體驗?zāi)亍?/p>

1、仍面臨的問題

雖然詳情頁中堆疊的字段已經(jīng)多達200處,隨著業(yè)務(wù)高速發(fā)展仍會存在部分信息缺失、不準(zhǔn)確的情況,對客服日常作業(yè)產(chǎn)生了一定的負向影響。另一方面,在開發(fā)訂單類需求中,約60%的都是配合外域或者內(nèi)部進行字段增刪改,如果建立了訂單信息的編排能力,后續(xù)字段類需求將可配置,從而能夠解放這部分需求的產(chǎn)研生產(chǎn)力,達到降本增效;同時若前端模塊能夠支持模塊拔插能力,也能為后續(xù)訂單信息模塊復(fù)用到坐席輔助及其他客服工作臺提供技術(shù)支撐。

2、信息編排能力建設(shè)

將訂單基本信息及關(guān)聯(lián)信息通過統(tǒng)一Schema維護。大家知道Schema(結(jié)構(gòu)化的數(shù)據(jù)類型)只要約定的足夠復(fù)雜是可以用來描述所有場景的數(shù)據(jù)的,所以使用Schema第一步就是要控制好這個邊界,在能夠覆蓋大部分業(yè)務(wù)場景前提下不能太復(fù)雜。首先可將訂單信息做3層細分:信息塊、信息組、信息元素。做到配置信息塊、信息元素對于訂單詳情頁的場景來說都不太合適,所以這里選擇約定到信息組的格式。

圖片圖片

2.1、Schema格式

上面圖示中兩組信息組可用下述Schema描述出來,利用數(shù)組的有序性,從左到右、從上到下對信息組進行渲染,實現(xiàn)訂單信息的編排配置能力。

schemaData : [
    {
        label: '訂單類型'
        text:'普通現(xiàn)貨'
        children: [
            {
                id: 'orderTypeDetail'
                text: '詳情',
                show: true,
                toolType: 'linkBtn', /** linkBtn, primaryBtn, tag */
                eventType: 'click', /** dbclick, hover*/
                interactiveType: 'popover', /** modal, popover, message*/   
                children: [
                     //** popover彈出的內(nèi)容 */
                    { label: , text: '', children: //..}]
                    { label: , text: ''}
                ]   
            },
            {
                text: '晚到必賠',
                show: true
                toolType: 'tag', 
            },
            {
                text: '退運服務(wù)',
                show: true
                toolType: 'tag', 
            },
        ]
    },
    {
        id: 'tradeStatus'
        label: '支付狀態(tài)'
        text:'已經(jīng)支付'
        children: [
           {
                text: '七天風(fēng)控',
                show: true
                toolType: 'tag', 
            },
        ]
    }
],

使用Schema可以滿足大部分的字段渲染場景,但是對于一些復(fù)雜的交互和自定義的樣式仍需要前端去實現(xiàn),這個時候每個信息元素中的id就發(fā)揮了作用,前端可以根據(jù)id去綁定交互事件和自定義樣式,具體實現(xiàn)如下:

/** 信息元素枚舉*/
enum INFO_ElEMENT_MAP {
    /** 訂單類型詳情按鈕 */
    ORDERTYPE_DETAIL: 'orderTypeDetail'


}


/** 信息元素*/
const infoElementMap = {
        INFO_ElEMENT_MAP.ORDERTYPE_DETAIL: {
            /** 綁定事件 */
            onClick: () => {
                orderTypeDetailClickHandler()
            },
            /** 綁定樣式 */
            className: [styles.marginLeft],
        },
      /** 其他需要添加復(fù)雜交互和樣式*/
    }

2.3、模版解析

約定好了Schema和規(guī)范,前端再編寫對應(yīng)模版解析代碼去渲染頁面,對應(yīng)渲染圖如下所示。

圖片圖片

最外層的渲染器代碼如下:

const SchemaRender = () => {
     //TODO 健壯性代碼
      return (
        <div>
          {schemaData.length ? (
            <Row>
              {schemaTemplate.map(item => {
                // 分隔符 
                if (item.key === TemplateKeyEnum.dividedLine) {
                  return <Divider />
                }
                return (
                  <Col span={12}>
                    <InfoItem
                      key={item.key}
                      label={item.label}
                      text={item.text}
                      infoList={item.children.map(child => {
                        return {
                          text: popoverRender(child),
                          hide: !child.show,
                        }
                      })}
                    />
                  </Col>
                )
              })}
            </Row>
          ) : (
            <Skeleton title={false} active paragraph={{ rows: 3 }} />
          )}
        </div>
      )
    }

最終,Schema加上模版渲染就能渲染出訂單詳情頁的信息,后續(xù)此類型的需求除了和外域約定字段,就不再需要額外資源投入了。

3、模塊插拔能力建設(shè)

實現(xiàn)了信息快速編排,還有信息模塊高耦合的問題。其實不同角色的客服同學(xué)關(guān)注的信息是不一樣的,所以新的訂單詳情頁要根據(jù)客服的身份去展示不同的信息;而且隨著屏幕大小的不同,所適合布局也不同。另一方面,工單詳情、坐席輔助都需要展示訂單信息的某一個信息模塊(整個頁面展示就太重了),這時就需要訂單信息模塊有可插拔的能力了。

3.1、技術(shù)方案

初步方案是后端維護一個信息模塊池,提供出一個接口,前端通過傳一個標(biāo)識,能夠返回對應(yīng)標(biāo)識需要的模塊組合,然后根據(jù)數(shù)據(jù)組合渲染數(shù)據(jù)。這個方案可以實現(xiàn)信息可拔插能力。

圖片圖片

上述方案可以解決問題,也比較簡單,但是控制數(shù)據(jù)的還是前端,這其實違背了最初建設(shè)信息編排能力的初衷。于是最終改為后端同學(xué)從客服同學(xué)的登錄態(tài)拿到userId,根據(jù)id拿到其所在處理組,是買家處理組就返回買家版訂單信息,賣家版就返回賣家版訂單信息。另一方面,前端也根據(jù)屏幕大小做布局的自適應(yīng)。

3.2、最終效果

  • 大屏下頁面布局:

圖片圖片

  • 小屏下頁面布局(1440*900以下):

圖片圖片

  • 工單詳情使用訂單詳情中的物流記錄、服務(wù)記錄訂單信息模塊:

圖片圖片

4、總結(jié)

從改版以來近8個迭代的資源投入數(shù)據(jù)來看,訂單需求開發(fā)成本降低了66.7%。

五、灰度和埋點方案

1、灰度方案

新版詳情頁改動較大需要根據(jù)客服所在處理組進行灰度,但是一線和二線的處理組分配又不太一樣,所以需要根據(jù)入口來源判斷使用哪套AB方案接口。另一方面,訂單詳情頁的入口非常多,所以在每個入口做灰度不太現(xiàn)實,改動較大,所以選擇收口到詳情頁主頁面區(qū)分新老頁面。

1.1、技術(shù)方案

  • 根據(jù)來源區(qū)分使用一線AB方案還是二線AB方案,偽代碼如下:
/** 獲取來源區(qū)分IM、工單灰度組信息 */
watch(
  () => props.platformCode,
  code => {
    try {
     switch (code) {
       case PLATFORM_TYPE.IM:
         /** 一線灰度走一線灰度接口 */
        isGray.value = true
        break
       case PLATFORM_TYPE.TICKET:
        /** 二線灰度走二線灰度接口 */
        isGray.value = true
        break
       default:
        isGray.value = false
    } catch {
      isGray.value = false
    }
  },
  {
    immediate: true,
  }
)
  • 在主頁面根據(jù)灰度情況渲染詳情模版:
return () => isGray.value ? (
    <>
      <Button type="link" notallow={clickHandler} >
        返回{isOld.value ? '新版' : '老版'}
      </Button>
      {isOld.value ? <OldDetail {...props} /> : <Detail {...props} />}
    </>
  ) : <OldDetail {...props} />

1.2、總結(jié)

根據(jù)培訓(xùn)進度開放灰度名單給客服使用新版頁面,同時對新老版頁面的數(shù)據(jù)進行監(jiān)控 。支持可監(jiān)控、可灰度、可回滾,確保了在頁面大改動情況下的系統(tǒng)質(zhì)量穩(wěn)定。

2、埋點方案

為了體現(xiàn)訂單信息優(yōu)化的收益和價值,需要對客服同學(xué)在新老訂單詳情頁的停留時間、跳出訂單詳情頁次數(shù)進行比對。

  • 訂單詳情頁停留時間:有效的停留時間越長一定程度能說明頁面的查閱費力度越高。
  • 訂單詳情頁跳出率:跳出率越高說明當(dāng)前訂單詳情信息不能滿足客服的查閱需求,需要去其他頁面查看。是信息不全、不清晰的一種體現(xiàn)。而且跳出頁面會重新加載新的頁面,等待時間會長于頁面內(nèi)獲取信息,增加客服獲取信息的時間。

2.1、頁面停留時間

使用監(jiān)聽路由的方法去計算頁面停留時間。這里只對其中一種做分析,其他兩種類似。

  • 確定路由:https://xxx-xxx.xxx/orderdetail/:id
  • 只需要考慮上一個路由是訂單頁面的情況
  • 數(shù)據(jù)過濾:小于3s,大于30min視為無效數(shù)據(jù)
  • 如果最近的路由是訂單頁面,則重置時間
/** 數(shù)據(jù)上報 */
const uplog = (current, last, constant, type) => {
  /** b: 只用考慮上一個路由是訂單頁面的情況 */
  if (constant === last) {
    const nowTime = getNowTime()
    const stayTime = nowTime - stayOrderDetailTime.currentTime
    /** c: 小于3s,大于30min視為無效數(shù)據(jù) */
    if (stayTime > 3000 && stayTime < 1000 * 60 * 30) {
      orderDuLog('ORDER_STAY_TIME', {
        orderNo: orderNo.value,
        stayTime,
        type,
      })
    }
    stayOrderDetailTime.currentTime = nowTime
  }
  /** d:如果最近的路由是訂單頁面,則重置時間*/
  if (constant === current) {
    stayOrderDetailTime.currentTime = getNowTime()
  }
}


/** 監(jiān)聽路由 */
watch(
  () => {
    return { name: route.name, id: route.params?.id }
  },
  throttle(
    (currentRoute, lastRoute) => {
      /** 從工單出發(fā):只用考慮上一個路由是訂單頁面的情況 */
      uplog(currentRoute?.name, lastRoute?.name, `${globalConfig.backstageCode}_orderdetail`, 'routeChange')
    },
    100,
    { leading: true, trailing: false }
  ),
  {
    deep: true,
    immediate: true,
  }
)

2.2、頁面跳出次數(shù)

頁面跳出次數(shù)就比較簡單了,只需要在跳出事件的handler里加上數(shù)據(jù)上報方法,比如查看商品詳情、退換貨詳情、用戶分期信息、工單詳情等等,最后計算跳出總量即可。

2.3、總結(jié)

老版頁面平均停留時間15.6s,新版頁面的平均停留時間8.5s,客服每次查詢信息的時長縮短7.1s,可根據(jù)詳情頁PV換算日均可降低客服同學(xué)工作時長。

圖片圖片

同時,客服查詢特定訂單信息時需要跳到別的頁面查詢,這說明訂單信息是有缺失和或者客服是對信息準(zhǔn)確性是有懷疑的,老版頁面跳出率11.4%(約8.7次訪問跳出1次),新版頁面跳出率7.92%(約12.6次訪問跳出1次)。客服查看訂單信息時跳出的率也下降3.48pp。

圖片圖片

圖片圖片

六、總結(jié)&規(guī)劃

1、總結(jié)

  • 關(guān)于動態(tài)路由頁面的多平臺復(fù)用:跨技術(shù)棧使用單實例的iframe通信,配合雙向的postMessage事件監(jiān)聽用戶行為觸發(fā)交互;微應(yīng)用內(nèi)使用Module Federation通信,在保障客服使用體驗的同時,節(jié)省了開發(fā)維護成本。

MF的首屏需要1279ms,非首屏只需428ms,渲染時間降低了6倍。

單個頁面的內(nèi)存占用減少到了之前的1/10以內(nèi)。

  • 關(guān)于大數(shù)據(jù)量的頁面首屏優(yōu)化:基于業(yè)務(wù)優(yōu)化接口調(diào)用時機,保證同時不超過6個接口請求,避免出現(xiàn)Stalled耗時,對大接口RT進行優(yōu)化,場景允許的話可改為GET協(xié)議類型,降低首屏響應(yīng)時間,提升客服體驗。
  • 首屏請求6個以上接口時不再出現(xiàn)Stalled耗時,大接口改為GET后總耗時是POST的2/3。

  • 快詳情接口RT只需要平均190ms,從之前大接口的470ms下降了41%,首屏渲染時間從873ms降至376ms,下降了57%,95分位567ms,下降了62%。

  • 關(guān)于信息編排、模塊拔插能力建設(shè):根據(jù)業(yè)務(wù)分析字段特點,約定合適的Schema格式使得信息內(nèi)容可靈活配置;對用戶的職能特點、設(shè)備情況進行分析,使得用戶所訪問頁面的布局、內(nèi)容做到區(qū)分,做到給用戶看到合適的內(nèi)容,降低坐席的查詢信息的費力度。

  • 訂單需求開發(fā)成本能夠降低66.7%。

  • 老版頁面平均停留時間15.6s,新版頁面的平均停留時間8.5s,客服每次查詢信息的時長縮短7.1s,根據(jù)訂單詳情頁的PV可換算出每日可降低客服同學(xué)的查詢時長。

  • 老版頁面跳出率11.4%(約8.7次訪問跳出1次),新版頁面跳出率7.92%(約12.6次訪問跳出1次)。客服查看訂單信息時跳出率下降了3.48pp。

2、后續(xù)規(guī)劃

雖然客服訂單詳情頁的使用體驗已經(jīng)得到提升,但是體驗升級之路仍在繼續(xù):

  • 模塊聯(lián)邦雖然很快,但是對公共依賴維護成本較大,也會導(dǎo)致應(yīng)用構(gòu)建速度下降。后續(xù)會基于無界對訂單子應(yīng)用進行遷移,建設(shè)專門存放遠程組件的應(yīng)用容器,提升子應(yīng)用的秒開和快速切換體驗,同時也能提升工單子應(yīng)用構(gòu)建速率,解耦橫向訂單功能的發(fā)布。可期待后續(xù)內(nèi)容。
責(zé)任編輯:武曉燕 來源: 得物技術(shù)
相關(guān)推薦

2017-01-15 18:51:57

京東手機商品詳情頁

2016-11-28 09:58:53

京東服務(wù)閉環(huán)實踐

2024-07-12 14:52:20

2016-11-23 15:26:01

詳情頁單品頁前端

2016-01-04 15:16:01

京東詳情頁實踐

2025-08-14 02:55:00

2024-11-27 13:01:22

應(yīng)用層領(lǐng)域?qū)?/a>對接層

2018-12-13 15:34:10

小米MIUImiui

2017-01-22 17:55:30

Android布局架構(gòu)功能實現(xiàn)

2018-05-22 10:10:20

網(wǎng)利寶

2024-04-02 07:59:06

G行科技客服

2019-11-20 12:03:42

Python數(shù)據(jù)爬蟲

2021-08-12 11:59:09

數(shù)字化

2009-06-05 10:36:22

智能客服呼叫中心

2012-12-28 13:35:37

網(wǎng)絡(luò)無線網(wǎng)絡(luò)

2023-09-01 08:53:01

Windows 11微軟
點贊
收藏

51CTO技術(shù)棧公眾號

成人精品3d动漫| 亚洲免费一级视频| 国产欧美一区二区精品久久久| 日韩精品一区二| 国产视频网站一区二区三区| 91av国产在线| 日韩欧美精品综合| 色999日韩自偷自拍美女| 久久免费的精品国产v∧| 九九热免费精品视频| 亚洲蜜臀av乱码久久精品蜜桃| 成人看av片| 热99精品里视频精品| 懂色av中文一区二区三区| 欧美日本韩国一区二区| 欧美性视频网站| 亚洲国产成人午夜在线一区| 91国内精品在线视频| 国产精品国产三级国产aⅴ原创| 琪琪五月天综合婷婷| 亚洲网址你懂得| 日日骚欧美日韩| 岛国大片在线观看| 欧美一区二区影院| 成人看片黄a免费看在线| 成a人片在线观看www视频| 久久精品国产欧美激情| 成人高清av| 一区二区三区观看| 欧美日韩一区二区在线 | 欧美在线|欧美| 日韩三级不卡| 日韩久久久久久久久久久久| 欧美一区二区三区影视| 亚洲综合国产激情另类一区| 91蜜桃在线视频| 色999日韩欧美国产| 97欧美成人| 欧美激情xxxx性bbbb| 国产日韩欧美在线播放不卡| 在线免费观看高清视频色| 5566中文字幕一区二区| 色狠狠色噜噜噜综合网| 久久99国产精品视频| 免费黄视频网站| 91精品国产高清| 国产精品一区二区三区乱码| 国产黄色大片在线观看| 久久精品国产美女| 欧美精选在线播放| 日本亚洲天堂网| 欧美成人h版| 亚洲成人av免费看| 国产91色在线免费| 91久久国产最好的精华液| 日韩午夜在线| 日韩精品久久久久久久软件91| 亚洲国产资源| 国产精品久久久久免费a∨大胸| 国产精品久久久久久久久久10秀| 乱熟女高潮一区二区在线| 亚洲成av人影院在线观看| 99久久免费国产| 1024日韩| 日韩欧美激情| 毛片毛片毛片毛片| 青青草原国产免费| 色综合影院在线| 亚洲欧洲日韩在线| 在线日韩av| 日韩制服一区| 中文字幕桃花岛| 九9re精品视频在线观看re6| 丝袜一区二区三区| 婷婷成人综合网| 国产成人精品三级| 亚洲天堂一区二区三区四区| a一区二区三区| 美女永久在线网站| 日本一区视频在线播放| 亚洲第一网站男人都懂| 裸体在线国模精品偷拍| 人人草在线视频| 99re资源| 精品久久久久久电影| 亚洲成人直播| 国内在线高清免费视频| 欧美中在线观看| 精品动漫一区二区三区| 亚洲精品一二三区区别| 日韩成人伦理| 中文在线网在线中文| 成人免费淫片在线费观看| 日本黄网站色大片免费观看| 91免费在线视频| 日韩在线观看高清| 精品国产亚洲在线| 天天色天天爱天天射综合| 久久久综合网站| 国产一区在线观看视频| 奇米亚洲午夜久久精品| 一本久道综合久久精品| 99九九热只有国产精品| 成人3d精品动漫精品一二三| 妖精一区二区三区精品视频| 亚洲精品一区av| 免费在线观看一区| 在线观看爽视频| 色爱综合区网| 日韩大片免费观看| xxxxx.日韩| jizz大全欧美jizzcom| 欧美激情国产精品| 欧美日本在线一区| 日韩一区中文字幕| 一区二区三区四区日韩| 老司机在线看片网av| 爽爽免费视频| 国产黄色在线网站| 香蕉久久一区| 蜜桃一区二区| 欧美va天堂在线| 欧美成人嫩草网站| 日韩高清国产一区在线| 国产精品一级片在线观看| 91亚洲精品久久久蜜桃| 亚洲激情成人在线| 91成人国产精品| 日韩av在线网站| 国产午夜精品久久久| 怡红院精品视频| 欧美日韩高清区| 国产精品成人久久久久| 91福利视频导航| 国产成人免费高清视频| 国产一区二区在线免费播放| 在线视频手机国产| 99视频免费在线观看| 你懂得影院夜精品a| 黄色影院在线看| 男生女生差差差的视频在线观看| 8x8ⅹ国产精品一区二区二区| 亚洲色欲综合一区二区三区| 视频一区二区三区国产 | 亚洲色图在线观看| 美女黄色丝袜一区| 黄色小网站91| 播放灌醉水嫩大学生国内精品| 色爱综合网站| 色呦呦在线播放| 日韩免费视频| 91亚洲国产成人精品一区二区三 | 麻豆影视在线观看| jizz性欧美10| 国产亚洲一卡2卡3卡4卡新区| 日韩成人午夜精品| 亚洲九九爱视频| 日韩精品久久久久| 国产精品高清在线观看| 人妻av中文系列| 天堂在线观看一卡二卡三卡四卡| 黄色在线免费观看大全| 久久综合色播| 色悠悠久久综合网| 北岛玲一区二区三区| 欧美涩涩视频| kk眼镜猥琐国模调教系列一区二区| 欧美日韩亚洲成人| 精品乱人伦一区二区三区| 91在线视频导航| 日本最黄一级片免费在线| 国产99久久久国产精品免费看 | 成人黄色在线网站| 欧美亚洲另类制服自拍| 你懂的在线观看视频网站| 久久精品国产亚洲一区二区三区| 欧美激情区在线播放| 青青青青在线| 国产日韩欧美高清在线| 欧美精品一区二| 人九九综合九九宗合| 国产精品一色哟哟| 欧洲一区二区三区| 视频一区欧美日韩| 欧美亚洲一区二区在线| 午夜精品久久久99热福利| 国产综合色香蕉精品| 国产精品久久久影院| 青青影院在线观看| 香蕉视频一区| 欧美综合国产| 国产精品国产三级国产三级人妇| 中文字幕亚洲无线码在线一区| 成人黄色在线免费观看| 男女超爽视频免费播放| 欧美日韩在线精品一区二区三区激情综合 | 性金发美女69hd大尺寸| 中文字幕一区二区三区四区五区 | 精品亚洲一区二区| 超碰免费在线公开|