您當前位置>首頁 » 新聞資(zī)訊 » 小程序相關(guān) >
58安居客小程序平台化與多小程序開發探索與實踐
發表時間:2021-1-11
發布人:葵宇科技
浏覽次數:75
導語
本文(wén)分享58安居客小程序團隊在小程序向平台化轉型、多小程序同步開發過程中(zhōng)遇到的問(wèn)題、解決方案與實踐。
背景
在提效、服務進階的大背景下(xià),為了讓同一支團隊,把一個(gè)業(yè)務做精做深,提高研發效率,HBG的産研團隊,進行了新的劃分:分線開發。
分線開發以後,安居客二手房(fáng)前端團隊要維護小程序從 1 變成 4 個(gè)。
小程序 | 技術(shù)棧 |
安居客微信小程序 | 微信原生開發 |
安居客百度小程序 | 百度原生開發 |
58二手房(fáng)小程序 | mpvue |
58同城小程序房(fáng)産二手房(fáng)業(yè)務 | 插件方式接入,技術(shù)不限 |
與此同時,随着移動(dòng)互聯網的流量紅利逐步減少(shǎo),小程序無疑是新的流量風口,為了搶占更多免費流量,推動(dòng)業(yè)務快速發展,産品希望我們安居客微信、百度小程序可(kě)以同步開發,以及未來可(kě)以支持更多小程序,如(rú)快應用等。
在多小程序技術(shù)框架不同、業(yè)務邏輯不同、基礎能力不同的情況下(xià),給我們的小程序開發帶來了以下(xià)挑戰:
1、在人力不變的情況下(xià),我們要如(rú)何支持多個(gè)小程序業(yè)務需求快速疊代?
2、作為平台方,我們要如(rú)何與業(yè)務方協作開發?
3、如(rú)何支持房(fáng)産垂直業(yè)務在其他小程序平移?
面對這種變化,我們聯合房(fáng)産各業(yè)務前端、産品、UED、QA等多個(gè)團隊,一起發起了小程序七巧闆項目,也開啟了58安居客小程序打怪升級刷新副本之路(lù),接下(xià)來我将娓娓道來我們是如(rú)何刷新副本的。
現狀分析與設計
面對多小程序同步開發的需求,我們應該如(rú)何做呢(ne)?
1) 方案一:按照小程序端配備開發資(zī)源,疊代開發速度不變,人力需要成倍增加。雖然技術(shù)不用做大的改動(dòng),但是人力成本太高。
2) 方案二:做技術(shù)升級改造,實現技術(shù)棧業(yè)務的統一。房(fáng)産小程序其中(zhōng)包含了很多業(yè)務(租房(fáng)、商(shāng)業(yè)地産、二手房(fáng)、新房(fáng)),幾百個(gè)頁面,大家都停下(xià)業(yè)務去做技術(shù)棧的統一,顯然是不現實的。
考慮到這些實際情況,技術(shù)方案上隻能考慮邊做業(yè)務邊重構,逐步去做統一。
2、 整體設計從業(yè)務方的角度來看,我們希望所有小程序平台盡可(kě)能提供相同的通(tōng)用能力,減少(shǎo)業(yè)務的适配,業(yè)務開發隻需關(guān)心業(yè)務開發,以及實現多小程序端的适配。
從平台方的角度來說,盡可(kě)能為業(yè)務方提供便利,減少(shǎo)兼容和(hé)适配成本。
針對以上情況,我們做出如(rú)下(xià)設計:
小程序七巧闆架構圖
不難看出:
1) 作為平台方,我們有以下(xià)任務:
A、多小程序提供統一通(tōng)用平台能力接口,即宿主環境。
B、統一基礎能力,減少(shǎo)宿主環境的适配
C、統一宿主小程序,從而達到可(kě)以快速落地其他小程序目标。
2) 作為業(yè)務方,實現二手房(fáng)業(yè)務可(kě)在多小程序同步開發。
為了支持業(yè)務的快速落地,所以我們把平台建設優先級排在第一位。接下(xià)來我将從平台化以及二手房(fáng)業(yè)務适配多小程序開發兩個(gè)維度來闡述。
小程序平台化建設
截止到目前為止,僅微信平台支持插件,百度和(hé)輕應用等暫不支持插件。
考慮到插件和(hé)分包的特點以及各業(yè)務實際情況,作為平台方我們插件和(hé)分包的接入方式均做了支持。業(yè)務方可(kě)根據自身業(yè)務場景,選擇合适的接入方式。
2、 确認平台通(tōng)用能力宿主環境要解決什麼問(wèn)題?
1) 提供平台基礎能力和(hé)公共方法的調用
2)抹平不同平台的差異
3) 支持業(yè)務插件和(hé)分包無縫切換
4) 一套代碼在宿主環境中(zhōng)一次測試,多端上線
梳理清楚我們要做什麼之後,緊接着進入緊鑼密鼓的調研設計中(zhōng),通(tōng)過全方位調研我們得知, 58同城微信小程序已經有開發過宿主環境,但無通(tōng)用SDK。房(fáng)産的宿主環境要兼容房(fáng)産多個(gè)小程序之間的差異,有很重業(yè)務屬性,也不能複用58同城宿主。
所以最終我們的宿主環境設計如(rú)下(xià):
1) 支持新老開發方式共存,推薦使用基于宿主環境開發
2) API方法名、出參、入參和(hé)58同城小程序宿主保持一緻
3) 安居客特有業(yè)務,加入新的API
4) 提供完整demo、完善的文(wén)檔、測試環境
3、 技術(shù)選型工欲善其事必先利其器(qì),要同時開發多個(gè)小程序以及未來可(kě)能要支持更多小程序,借助一些優秀的框架進行開發,一定會事半功倍。調研了Taro、WePY、uni-app、mpvue、chameleon、百度小程序轉換工具以及其他工具,結合團隊實際情況,最後我們選擇Taro作為我們的開發框架。選擇Taro的主要原因:
1) 支持逐步替換,降低項目風險
2) 團隊有React 開發經驗,也要維護部分React Native業(yè)務,技術(shù)棧盡量統一
3) 支持動(dòng)态編譯、條件編譯,可(kě)實現定制化58、安居客主題皮膚
4) 提供轉換工具,可(kě)把現有微信小程序直接轉成 Taro,降低遷移成本
5) 庫維護更新比較穩定,社區活躍
4、 小程序基礎能力統一随着宿主環境需求分析、技術(shù)選型、開發完成以及配合業(yè)務方接入過程中(zhōng),為了減少(shǎo)業(yè)務方的适配,我們通(tōng)用能力做了三個(gè)統一:
1) 賬号體系:統一接入雲賬号,統一賬号體系
2) 微聊:統一多小程序微聊接入方式和(hé)版本以及通(tōng)用能力,減少(shǎo)宿主和(hé)業(yè)務的适配
3) 與TEG在雲賬号、微聊等基礎公共能力上,盡量保持多小程序在接入方式、接口設計上統一,減少(shǎo)接入成本。
5、 小程序性能優化前期我們以宿主環境的開發、支持業(yè)務快速接入為主,随着業(yè)務逐步灰度接入,小程序的包大小也越來越大,性能問(wèn)題也越來越明顯,以微信小程序為例,我們發現:
1) 小程序包大小越來越大
2) 小程序下(xià)載耗時明顯增加
3) 小程序啟動(dòng)耗時明顯增加
那麼如(rú)何優化呢(ne)?通(tōng)讀了一遍官網的性能優化文(wén)檔,總結出性能優化的三大塊
1) 包體積優化(分包、圖片CDN、延遲非必須插件、分包預加載等)
2) 請求優化(請求次數、請求階段等)
3) 首次渲染優化(setData優化、DOM渲染優化等)
問(wèn)題又來了,如(rú)何來找出我們的小程序,這三大塊需要優化的具體影響點在哪裡?
在開發工具中(zhōng)使用help()方法,使用其中(zhōng)的openVendor方法打開開發工具在小程序框架所在目錄。其中(zhōng)有包括以基礎庫命名的目錄和(hé)其他幫助文(wén)件。如(rú)其中(zhōng)有兩個(gè)工具wcc和(hé)wcsc。wcc工具可(kě)把 wxml 轉換為對應的 JS 函數$gwx(path, global),wcsc 可(kě)将 wxss 轉換為 css。而基礎庫目錄包括WAService.js 和(hé) WAWebview.js 文(wén)件。結合開發者工具命令行中(zhōng)使用document.head可(kě)以查看小程序的整個(gè)啟動(dòng)流程大緻如(rú)下(xià):
結合微信包的啟動(dòng)流程和(hé)微信開發工具的Sources、Audits面闆進行性能分析。我們發現可(kě)以通(tōng)過以下(xià)幾種方式來進行了優化:
1) 減少(shǎo)包的文(wén)件大小
A、小程序本地圖片一律替換成從CDN加載
B、在平台化過程中(zhōng),随着業(yè)務接入、灰度、全量上線,及時下(xià)掉老代碼
C、删除曆史無用代碼
D、延遲第三方依賴的加載
2) 優化首屏數據請求,來加速首屏速度選擇。首屏 非 必須 的數據,延遲加載
3) 優化 setData存儲和(hé)調用
A、減少(shǎo) setData 的頻繁調用
B、減少(shǎo) data 上的數據冗餘,非必要數據不要在 data 上存儲
接下(xià)來,以安居客微信小程序為例,介紹一下(xià)針對延遲第三方依賴的加載,我們是如(rú)何做優化的:
1) 業(yè)務插件肯定是要延遲加載的,插件在各業(yè)務分包引入,這點毋庸置疑
2) 賬号體系,我們是直接對接雲賬号的插件,最開始的做法是在主包中(zhōng)直接引入,文(wén)件比較大(434kb)。後續,雲賬号插件做了重構和(hé)升級,文(wén)件大小:80.5kb,并且支持分包引入。進而,我們升級了雲賬号插件版本、以分包的方式引入雲賬号插件。最終,主包大小減少(shǎo)了 434kb。
3) 微聊,安居客微信小程序最開始引入的是微聊 JS SDK、自己實現 UI,文(wén)件大小:20kb。為了統一多小程序微聊通(tōng)用能力和(hé)複用微聊插件現有卡片功能,我們決定微聊統一接入微聊插件,微聊插件大小:335kb。那我們應該如(rú)何引入微聊SDK呢(ne)?顯而易見,2種方案:
A、直接在主包中(zhōng)引入微聊插件,對主包大小影響比較大,首頁、房(fáng)源列表等可(kě)以拿到微聊消息數,現有功能不會受到影響。
B、不在主包中(zhōng)引入微聊插件,首頁、房(fáng)源列表等業(yè)務拿不到微聊消息數。
首頁、房(fáng)源列表效果圖如(rú)下(xià)圖,那我們該怎麼辦呢(ne)?
圖左是首頁,圖右是二手房(fáng)房(fáng)源列表
針對上述問(wèn)題和(hé)業(yè)務場景與微聊開發溝通(tōng),他們可(kě)以提供一個(gè)消息總數的接口,但是這個(gè)消息總數和(hé)微聊插件的總數可(kě)能不一緻,業(yè)務上需要做一下(xià)降級,與産品一起溝通(tōng)之後,也能接受這部分的降級。所以,最後微聊插件SDK,我們以分包的方式做了接入,盡可(kě)能的保證了主包的大小以及下(xià)載速度。
其他優化,就不在這裡一一展開了,通(tōng)過以上初步優化,我們可(kě)以看到啟動(dòng)耗時時間、初次渲染時間有了明顯的下(xià)降,下(xià)圖是我們優化後小程序性能變化,後面我們将持續優化,為用戶提供更好的用戶體驗。
小程序下(xià)載耗時
小程序初次渲染耗時
6、 規範化、流程化
俗話說的好,打江山容易守江山難,這句話在我們小程序平台化的過程中(zhōng)也适用。
通(tōng)過一系列開發和(hé)技術(shù)方案的落地,我們提供了宿主環境和(hé)完整的接入文(wén)檔、開發demo。配合房(fáng)産各個(gè)業(yè)務方完成了首次接入,希望後面不費吹灰之力的更新版本即可(kě)。然而理想是豐滿的,現實很骨感,比如(rú)以下(xià)問(wèn)題:
1) 開發過程中(zhōng)遇到宿主環境的Bug找誰解決
2) 平台方測試和(hé)業(yè)務方測試如(rú)何配合
3) 業(yè)務方測試完成後如(rú)何交接給平台方
4) 誰負責上線,新的需求怎麼對接等等
通(tōng)過解決這些問(wèn)題并且實際落地實施,我們一起梳理一套完善的标準和(hé)規劃的開發流程,通(tōng)過流程的規範化、标準化,來保證我們項目高效開發、溝通(tōng)、以及項目的順利上線。
二手房(fáng)業(yè)務跨平台開發
随着平台化的标準化、統一和(hé)完善,不難看出,隻要58二手房(fáng)小程序也接入标準的宿主接口,那麼二手房(fáng)業(yè)務要适配的小程序的能力基本上就統一了,接下(xià)來隻需要考慮業(yè)務的實現即可(kě)。
圖左58二手房(fáng)房(fáng)源列表,圖右安居客二手房(fáng)房(fáng)源列表
通(tōng)過以上圖片對比,我們發現業(yè)務邏輯差異較大,想要同步開發還存在不少(shǎo)困難,經過與産品、UED一起溝通(tōng)協商(shāng),58、安居客保證頁面結構統一,支持業(yè)務、皮膚差異性。借助Taro支持多小程序轉換,考慮如(rú)何實現定制皮膚與實現業(yè)務差異化即可(kě)。整體設計如(rú)下(xià):
打包和(hé)集成
1) 打包配置
我們按平台、終端打包需要,在 package.json 增加對應 scripts,然後利用 cross-env這個(gè)包來設置環境變量,比如(rú)在打包安居客微信小程序的時候,設置環境變量 WEAPP=anjuke,代碼如(rú)下(xià):
{
"scripts": {
"build:weapp": "taro build --type weapp",
"dev:weapp": "npm run build:weapp -- --watch",
"build:anjuke": "cross-env WEAPP=anjuke && npm run build:weapp",
"dev:anjuke": "cross-env WEAPP=anjuke && npm run dev:weapp"
}
}
然後在config/index.js裡面利用環境變量加載對應小程序的自定義配置,具體代碼代碼如(rú)下(xià):
const WEAPP = process.env.WEAPP ? process.env.WEAPP : 'anjuke'
module.exports = function(merge) {
return merge({}, config, require(`./${WEAPP}`));
};
此處 config 代表打包通(tōng)用配置以及默認配置。如(rú) babel、源碼目錄等。
為了讓每個(gè)平台、終端打包出來的代碼大小都是最優的,利用配置defineConstants 屬性配置編譯時的全局變量,從而實現小程序按照平台、終端、功能差異上實現條件編譯。我們的實踐是按照業(yè)務平台、平台屬性、小程序終端做了劃分:
const config = {
defineConstants: {
PLATFORM, // 網站(zhàn)平台 anjuke 或 58
PLATFORM_ABBR, // 小程序名字簡寫,用來區分同平台同類型小程序
RUN_END, // 運行端 weapp、swan、quickapp
IS_AJK, // 是否是 anjuke
IS_WUBA, // 是否是 58
IS_WEAPP, // 是否是 微信
IS_SWAN, // 是否是 百度
IS_QUICK_APP // 是否是 快應用
}
}
在編譯的時候,根據目标小程序的特性,為上面變量注入對應的值。
2) 皮膚差異化
二手房(fáng)業(yè)務要同時支持58同城、安居客兩個(gè)平台。二者之間頁面結構是一緻的,但各自有些主題色,我們将主題色提取成Sass變量,在編譯打包時,按照平台引入平台主題色,從而達到換膚的功能。比如(rú)在安居客小程序打包是通(tōng)過plugins引入安居客主題色:
const path = require("path");
module.exports = {
plugins: {
sass: {
resource: [
"src/scss/ajktheme.scss"
],
projectDirectory: path.resolve(__dirname, "..")
}
}
};
58、安居客在業(yè)務上存在諸多差異,如(rú)賬号鑒權、城市、房(fáng)源展示邏輯等,為了保證小程序在多平台、多終端通(tōng)用功能統一、前端數據展示邏輯統一,API 接口做了平台、業(yè)務、端的兼容,統一了數據接口格式,間接的支持了小程序一套代碼在多平台、多端運行。目前我們的落地方案:
1) 按照業(yè)務平台劃分 API 域名,如(rú)安居客小程序接口使用anjuke.om域名,58小程序接口使用58.com域名
2) 按照公參區分終端,如(rú)我們通(tōng)過weapp 公參區分是百度、微信還是其他小程序
以房(fáng)源列表為例,之前安居客和(hé)58房(fáng)源展示邏輯、扣費邏輯、API接口數據格式等各不相同,重構之後,API根據域名封裝業(yè)務邏輯,統一接口數據輸出格式,比如(rú)前端獲取列表數據代碼如(rú)下(xià):
import { fetchList } from "./api";
fetchList({
page: this.list.page,
page_size: PAGE_SIZE,
user_id: userInfo.userId || "",
open_id: userInfo.openId || "",
union_id: userInfo.udid || "",
...this.filterOptions
}).then(res => {
// do some thing
})
然後我們在 api.js 底層針對58、安居客平台适配一下(xià)API接口域名,代碼如(rú)下(xià):
import { base } from './config';
const urlBase = isOldAjk => {
if (IS_WUBA) return base.wbBase;
if (isOldAjk) return base.oldAjkBase;
if (IS_AJK) return base.ajkBase;
};
通(tōng)過API 适配平台、業(yè)務邏輯的差異,使前端邏輯在多小程序之間保持獨立、統一,從而達到多小程序平移的目的,前端專注于數據展示和(hé)交互即可(kě)。
同一套代碼要運行在多個(gè)小程序上,雖然宿主提供了通(tōng)用标準的能力,但是還有一些差異在短(duǎn)期沒有辦法解決。為了讓同一代碼可(kě)以在多個(gè)小程序之間無縫平移,必然要引用一些中(zhōng)間層屏蔽底層和(hé)環境的差異,簡化業(yè)務調用方式,提高開發效率。
以跳轉協議為例,房(fáng)産二手房(fáng)的業(yè)務要分别以插件的方式集成在58同城微信小程序、以分包的形式集成在安居客微信小程序,那插件和(hé)分包在路(lù)徑跳轉方面是不同,為此,有了我們的跳轉中(zhōng)間層:
export const goToPage = (wx, params, type) => {
if (MAIN.Common.isWubaPlugin()) {
let isObject = typeof params === 'object';
let entry = isObject ? params : { url: params };
entry.url = `plugin-private://${ pluginId }` + entry.url;
MAIN.Common.goToPage(wx, entry, type);
} else {
MAIN.Common.goToPage(wx, params, type);
}
};
現有的多個(gè)小程序,之前頁面的路(lù)由均不一樣,在路(lù)由跳轉管理上、維護和(hé)開發成本很高。針對這個(gè)問(wèn)題,我們做了以下(xià)幾步做了優化提效:
1) 新開發頁面多小程序路(lù)由保持統一
2) 借鑒58APP協議下(xià)發機制,跳轉協議統一改為後端下(xià)發
這樣不僅解決了路(lù)由管理維護成本,而且支持更精細化的灰度,做到優雅降級。在我們業(yè)務統一逐步切換中(zhōng),灰度必不可(kě)少(shǎo),有完善的灰度降級方案,也有助于最大限度的降低影響。
具體到業(yè)務場景中(zhōng):以微信小程序為例,提交版本給小程序審核需要時間,在從發版到更新到所有用戶,最長需要 24 小時。如(rú)果我們新改版的頁面上線了,突然發現某些機型打開白頁。我們可(kě)以快速将下(xià)發協議成老頁面,甚至換成一個(gè)H5的頁面,把損失降低到最小。
總結和(hé)展望
回顧過去,通(tōng)過半年多技術(shù)和(hé)業(yè)務的升級和(hé)統一。安居客實現了微信、百度、快應用等小程序的平台化,支持房(fáng)産垂直業(yè)務在多小程序上實現無縫平移,可(kě)以快速落地生成更多的小程序,同時二手房(fáng)核心業(yè)務完成在多小程序的同步開發,大幅度的提升了小程序開發效率,在小程序的流量風口上為業(yè)務落地做好後勤保障。
接下(xià)來我們會持續優化小程序性能、完善性能監控、JS錯誤監控等。擁抱公司小程序協同項目,持續完善安居客小程序平台建設,為業(yè)務快速接入、落地做好準備。
寫到最後
安居客小程序實現平台化以及實現二手房(fáng)核心業(yè)務重構與順利落地,離(lí)不開其他前端、後端、QA等兄弟團隊的支持與積極配合,另一方面,在我們統一小程序基礎功能,如(rú)雲賬号、微聊等方面,也離(lí)不開 TEG同學的大力支持與幫助,因此在此對你(nǐ)們說一聲感謝。個(gè)人能力也有限,如(rú)果大家發現文(wén)章中(zhōng)的錯誤或者實現方案上的不完美,歡迎交流指正。
參考文(wén)獻
1、https://developers.weixin.qq.com/miniprogram/dev/framework/
2、https://nervjs.github.io/taro/docs/config.html
3、https://developers.weixin.qq.com/miniprogram/dev/framework/audits/performance.html
作者簡介
李永超,58集團/資(zī)深前端工程師(shī)。
張素沙,58集團/高級前端工程師(shī)。
閱讀推薦