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

    歡迎訪問 生活随笔!

    生活随笔

    當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

    编程问答

    导入第三方组件_大型 web 应用公共组件架构是如何来的?

    發(fā)布時(shí)間:2024/1/23 编程问答 48 豆豆
    生活随笔 收集整理的這篇文章主要介紹了 导入第三方组件_大型 web 应用公共组件架构是如何来的? 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

    來(lái)源:騰訊AlloyTeam

    https://mp.weixin.qq.com/s/gVUJRF_nLHOT_iXDXQ8F-w

    騰訊文檔公共組件歷史包袱

    1. 架構(gòu)問題——開發(fā)層面

    騰訊文檔管理的公共組件, 設(shè)計(jì)之初,采用了各種便于快速迭代的設(shè)計(jì)方式,組件代碼結(jié)構(gòu)和規(guī)范也缺乏統(tǒng)一,在長(zhǎng)期的開發(fā)過程中質(zhì)量沒有得到保障。隨著需求不斷累積,目前存在比較大的歷史包袱。大量組件錯(cuò)綜復(fù)雜,相互輯合緊密,而導(dǎo)致不管多么小的改動(dòng)都需要數(shù)天的惡戰(zhàn)才能完,對(duì)于開發(fā)新功能和修復(fù)缺陷的同時(shí)時(shí),都異常痛苦。主要存在的問題是以下幾點(diǎn)。

    1.1 難以預(yù)料第三方公共組件導(dǎo)致的卡頓

    騰訊文檔管理的公共組件(以下稱FC)主要通過 script-loader 動(dòng)態(tài)加載承載了各個(gè)頁(yè)面的公共業(yè)務(wù)邏輯,然后將腳本注入到品類的 HTML 中,比如登陸、分享,權(quán)限等。這些邏輯都是同一個(gè)線程中執(zhí)行的。

    第三方組件是由不同團(tuán)隊(duì)和開發(fā)人員在維護(hù)著,往往有著不可控制的預(yù)期,品類方難以保證引入某一個(gè)組件的性能是否合理,從而容易導(dǎo)致品類編輯發(fā)生卡頓,及性能數(shù)據(jù)下降。

    目前在 excel 調(diào)用公共組件過程中,會(huì)手動(dòng)停止卡頓監(jiān)控,從而讓公共組件邏輯不影響詳情頁(yè)的卡頓數(shù)據(jù)。然而,這無(wú)法從根本上改變用戶主進(jìn)程卡頓的體驗(yàn)問題。

    // 以下偽代碼async loadModule(name){ ? ?// 卡頓監(jiān)控停止 ? ?jank.stopReport(); ? ?await dosomeThingToLoadModule(name); ? ?jank.restartReport();}

    【案例】 打開權(quán)限組件 cpu 暴漲,表格卡頓。

    1.2 script-loader 加載形式鏈路非常長(zhǎng),公共組價(jià)加載異常延遲。

    首先需要加載 assets.json 依賴映射文件,然后再異步加載需要功能的 js 代碼,最后再初始化組件,向后臺(tái)請(qǐng)求組件所需數(shù)據(jù),進(jìn)行渲染,最終才能完整展示。這是一個(gè)非常長(zhǎng)的鏈路,導(dǎo)致用戶使用體驗(yàn)相關(guān)功能非常耗時(shí)。

    1.3 發(fā)布沒有版本控制。

    “一次更新,多端升級(jí)” 本來(lái)是 FC 設(shè)計(jì)之初的一種考慮,但在日積月累的迭代中,我們積累了無(wú)數(shù) bug,每一次常規(guī)發(fā)布之夜都伴隨著驚恐與噩夢(mèng)。由于模塊A 發(fā)布修復(fù)了某個(gè) ppt 的 bug,帶了某個(gè) word 的新 bug; 由于某一個(gè)版本的升級(jí),帶來(lái)全品類功能的崩潰。缺乏版本控制的后果就是,為了節(jié)省半個(gè)小時(shí)的包升級(jí)時(shí)間,帶來(lái)了大量調(diào)用品類方之間的缺陷連鎖反應(yīng)。我們的設(shè)計(jì)目標(biāo)除了盡可能保證發(fā)布效率,發(fā)布的質(zhì)量和穩(wěn)定性也是非常重要的。

    1.4 組件調(diào)用形式不規(guī)范和統(tǒng)一

    // 以下偽代碼 // 業(yè)務(wù)A const someModule = await loadModule('someModule'); someModule.init({ ? ?xxx: 'yyyy', ? ?zzz: 'hello', ? ?from: 'xxx' })

    // 以下偽代碼// 業(yè)務(wù)B const someModule = await loadModule('someModule'); someModule.init({ ? ?bbb: 'yyyy', ? ?ccc: 'hello' })

    公共組件沒有統(tǒng)一的入?yún)⒁?guī)范。每次開發(fā)的步驟是,在品類 A 已經(jīng)提前接入前提某組件下,品類 B、C直接復(fù)制黏貼過去,然后完事。由此帶來(lái)的問題是:我們發(fā)現(xiàn)大量由于品類直接差異性導(dǎo)致的公共組件 bug 。

    1.5 通信機(jī)制混亂

    script-loader 即承擔(dān)了模塊加載的職責(zé),內(nèi)部有又事件通信的邏輯。而公共組件和各個(gè)品類的通信除了使用SLR.listen 外,同時(shí)又摻雜 window.addEventListener,導(dǎo)致很多地方重復(fù)監(jiān)聽,同時(shí)在定位問題時(shí)帶來(lái)了困擾。示例:excel 和 word 對(duì)應(yīng)的通信不一樣。

    // 偽代碼window.something.listen('someEvent', ()=>{})

    // 偽代碼document.addEventlistener.listen('someEvent', ()=>{})

    1.6 內(nèi)部大量使用全局變量

    FC 倉(cāng)庫(kù)僅 xxx 這個(gè)變量就有500 多處調(diào)用方。公共組件使用全局變量容易會(huì)造成對(duì)詳情頁(yè)的污染,同時(shí)讓組件邏輯與品類的特定變量耦合,一旦某一個(gè)品類對(duì)應(yīng)的字段在迭代中發(fā)生變化,就會(huì)造成意外 bug 。

    2. 架構(gòu)問題——產(chǎn)品層面

    架構(gòu)的不合理設(shè)計(jì),會(huì)帶來(lái)一些很大的負(fù)面影響,尤其是在需求的開發(fā)周期上。這本身是一個(gè)惡性循環(huán):

    解決方案思考

    綜上所述,我們可以發(fā)現(xiàn),目前我們?cè)瓉?lái)對(duì)第三方公用組件的設(shè)計(jì)思路是——把公用組件當(dāng)作編輯頁(yè)不可或缺的耦合部分。實(shí)際上,公共組件,例如,權(quán)限,分享,通知等功能,具備獨(dú)立應(yīng)用的功能,它們應(yīng)該更像是一個(gè)可拔插的插件,品類不應(yīng)該關(guān)心插件的內(nèi)部細(xì)節(jié),插件也不應(yīng)該有權(quán)限影響和破壞外部主進(jìn)程。讓每次變更都變得可控,并且避免缺陷,同時(shí)最大程度地滿足功能性和靈活性的要求是這次架構(gòu)設(shè)計(jì)的目標(biāo)。

    解決方案是建設(shè)可拔插式插件化公共組件體系。定制標(biāo)準(zhǔn)的插件化規(guī)范,可便于拓展成對(duì)第三方開發(fā)者開發(fā)插件的體系。而 FC 公共組件是作為官方內(nèi)置插件的形式存在。插件體系有幾個(gè)比較關(guān)鍵的點(diǎn):第一是,第三方插件質(zhì)量會(huì)參差不齊,如何約束插件的運(yùn)行不會(huì)導(dǎo)致頁(yè)面的卡頓。第二點(diǎn)是,插件如何調(diào)用文檔SDK,也即使如何規(guī)范插件和主線程的通信問題。第三點(diǎn)是,插件安裝,卸載等后臺(tái)管理服務(wù)。

    2.1 如何安全的運(yùn)行插件?

    2.1.1 插件類型

    首先我們的插件體系分為兩類:純計(jì)算邏輯型插件 和 UI 交互式插件。純計(jì)算邏輯插件,比如一個(gè)自定義函數(shù),一個(gè)自定義任務(wù)等。這種插件可以通過使用 web worker 進(jìn)行多線程計(jì)算進(jìn)行隔離。UI 交互式插件,比如分享彈窗,權(quán)限側(cè)邊欄等,目前 FC 公共組件全部是這種類型。這種插件需要復(fù)雜的 UI 交互,我們可以通過 chrome 的 site-isolation 特性(參考第三方 web 應(yīng)用進(jìn)程隔離),用不同域的域名動(dòng)態(tài)創(chuàng)建 iframe,對(duì)應(yīng)的 iframe 內(nèi)容區(qū)域會(huì)和主進(jìn)程進(jìn)行隔離,從而保證品類的性能和安全性。

    2.2 插件如何與主進(jìn)程通信

    出于安全限制,插件不應(yīng)該直接訪問和寫入主進(jìn)程任何數(shù)據(jù)。需要建立一套 rpc 通信協(xié)議打通插件和主進(jìn)程的調(diào)用。

    2.2.1主進(jìn)程接口安全暴露

    excel 通過 di 依賴服務(wù)化后,各種依賴將會(huì)以服務(wù)化的形式對(duì)外提供。對(duì)外暴露 api 接口,提供給內(nèi)部和外部調(diào)用。

    2.2.2插件接口安全暴露

    基于安全性考慮,插件只能調(diào)用平臺(tái)方提供的安全接口,這些接口可以 api 服務(wù)化的形式對(duì)外暴露。在初始化的過程注入到一個(gè) API 服務(wù)工廠中返回給一個(gè)緩存對(duì)象,提供給插件使用。這些對(duì)象如何暴露給插件?這里我們參考 vscode 機(jī)制,可以攔截 require 接口,將緩存的插件api 注入到插件上下文。

    2.2.3 插件進(jìn)程 api 和 主進(jìn)程 api 通信

    定義標(biāo)準(zhǔn)的 worker/iframe 進(jìn)程與主進(jìn)程通信機(jī)制。參照 vscode 我們可以巧用 proxy 代理(IE 11 不兼容),在插件調(diào)用 api 時(shí)進(jìn)行攔截,統(tǒng)一轉(zhuǎn)換成 message send 調(diào)用,可以避免每次api 調(diào)用手動(dòng)觸發(fā) message 通信,簡(jiǎn)化調(diào)用流程。

    2.3 插件 UI 擴(kuò)展點(diǎn)

    騰訊文檔公共組件交互上只有兩種組成,分別是 dialog 彈窗和 slidebar 側(cè)邊欄,dialog 彈窗代表是添加文件夾面包、分享面板、vip 支付面板等。側(cè)邊欄有權(quán)限、通知列表等。這兩種類型組件,我們分別為插件 UI 展示提供統(tǒng)一的面板。插件編寫時(shí)需要配置指定類型,調(diào)用時(shí)在特定區(qū)域承載視圖。

    2.4 插件管理體系

    2.4.1 部署

    用戶開發(fā)的插件需要有管理平臺(tái),按照規(guī)范開發(fā)完后,發(fā)布到插件管理服務(wù)。管理服務(wù)具備生成插件描述信息,部署到靜態(tài)資源,為 UI 組件形態(tài)的插件動(dòng)態(tài)生成插件三級(jí)域名。

    2.4.鑒權(quán)、安裝

    用戶授權(quán)給插件,然后才能完成安裝。可訪問權(quán)限比如用戶基本信息,表格信息,確認(rèn)許可后,用戶信息下綁定應(yīng)對(duì)插件。

    2.5 調(diào)試

    內(nèi)部插件暫時(shí)可以直接代理 sheet 本地進(jìn)行開發(fā)。對(duì)外部插件需要提供一種標(biāo)準(zhǔn)便捷的調(diào)試方式。可選方案有兩種,第一種是通過騰訊文檔調(diào)試工具 Chrome 插件,支持用戶安裝臨時(shí)的本地插件,進(jìn)行開發(fā)。

    另外一種是用戶申請(qǐng)調(diào)試開發(fā)權(quán)限,文檔菜單選項(xiàng)內(nèi)增加插件導(dǎo)入,然后上傳到一個(gè)臨時(shí)的調(diào)試服務(wù)服務(wù) ,調(diào)試好后,再進(jìn)行發(fā)布。?

    2.5 如何兼容多品類

    公用組件插件化依賴品類有相同的服務(wù)化機(jī)制。但各個(gè)品類因?yàn)榇a并不統(tǒng)一,插件化如何兼容各個(gè)品類呢?

    有兩種主要方法,第一種是公共組件按照 Excel 服務(wù)化進(jìn)行插件化先行改造,內(nèi)部再暴露全局變量給其他未改造的品類按照原 FC 調(diào)用。

    另外一種是將插件化體系進(jìn)行單獨(dú)的 SDK 化,SDK 內(nèi)部做統(tǒng)一的插件化環(huán)境及初始化流程,在各個(gè)品類再進(jìn)行引入。

    結(jié)

    任何架構(gòu)設(shè)計(jì)都是歷史下的產(chǎn)物,脫離實(shí)際情況談最優(yōu)解都是不切實(shí)際的想法,如何在有限的人力資源和更優(yōu)的方案中取得平衡是一門學(xué)問。一個(gè)模式的提出必定面對(duì)解決一個(gè)問題,隨著時(shí)間的推移,需求不斷調(diào)整和迭代之下,原先的軟件設(shè)計(jì)必定會(huì)變得越來(lái)越脆弱,最終面臨自然崩塌,需要重構(gòu)。但就像一棟房子,工程師設(shè)計(jì)出結(jié)構(gòu)穩(wěn)定和考慮長(zhǎng)遠(yuǎn)的方案(架構(gòu)和可擴(kuò)展性),同時(shí)施工隊(duì)不偷工減料(代碼質(zhì)量),那么房子也會(huì)保值更久,也能更好的面對(duì)新工程的不斷改造。

    ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ----------? END? ----------

    推薦閱讀

    ??2020最新java學(xué)習(xí)路線圖!

    ??Java ?9 月程序員工資出爐,你拖后腿了嗎?

    ??CTO 寫的代碼為什么那么強(qiáng)!

    ?一個(gè)900行代碼得類,你累不累?

    如有收獲,點(diǎn)個(gè)在看,誠(chéng)摯感謝下次見(。・ω・。)ノ?

    總結(jié)

    以上是生活随笔為你收集整理的导入第三方组件_大型 web 应用公共组件架构是如何来的?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。