一次前端解構(gòu)的嘗試

前端開發(fā)由于單頁應(yīng)用的興起,前端是越來越工程化刻肄,代碼量越來越大瓤球。不可避免的需要將工程解構(gòu),然后分派給各個團(tuán)隊單獨(dú)開發(fā)敏弃。

我們希望能類似后端微服務(wù)的效果卦羡,獨(dú)立開發(fā),獨(dú)立部署麦到,而對用戶而言是無感知的绿饵。

First Split

于是我們基于頁面按照團(tuán)隊拆分,將不同的業(yè)務(wù)頁面按業(yè)務(wù)分成不同的業(yè)務(wù)線瓶颠,然后獨(dú)立開發(fā)拟赊,獨(dú)立部署。本質(zhì)上不同團(tuán)隊已經(jīng)在開發(fā)不同網(wǎng)站了粹淋,不過通過一層代理層將各個站點(diǎn)連接起來吸祟,讓終端用戶認(rèn)為他們?nèi)栽谑褂猛环N應(yīng)用。

獨(dú)立開發(fā)部署架構(gòu)圖.png

此拆分可以將業(yè)務(wù)部分拆分較細(xì)粒度桃移,允許團(tuán)隊獨(dú)立開發(fā)屋匕,最后僅僅需要測試人員根據(jù)業(yè)務(wù)要求驗(yàn)證各個業(yè)務(wù)集成時候是否符合需求即可。

對于大部分開發(fā)場景而言借杰,此方案就足夠了过吻。不過既然不同團(tuán)隊開發(fā)的站點(diǎn)其實(shí)是同一個應(yīng)用,頁面上可能有很多共同元素(比如常見的DashBoard應(yīng)用常常有用戶Profile元素蔗衡,以及切換業(yè)務(wù)用的Menu)纤虽。業(yè)務(wù)切換回導(dǎo)致頁面的Reload,共有元素必定會導(dǎo)致瀏覽器重新執(zhí)行绞惦,而且除此之外逼纸,單頁應(yīng)用框架現(xiàn)在都比較重,首屏加載中框架的啟動會占據(jù)大部分時間济蝉,從而每次業(yè)務(wù)切換Reload總會導(dǎo)致一部分JS引擎執(zhí)行時間花費(fèi)在這些公共部分的重新渲染上杰刽,造成用戶體驗(yàn)上感覺加載性能慢呻纹。

公共部分示意圖.jpg

Next Split

雖然上訴方案帶來了非常大的開發(fā)便利性,但是導(dǎo)致了的用戶體驗(yàn)的下降专缠。

我們希望能保持上訴方案中,既能保持各個團(tuán)隊獨(dú)立開發(fā)淑仆,獨(dú)立部署的好處涝婉,又能不犧牲頁面切換中,由單頁應(yīng)用拆分后帶來的應(yīng)用框架重復(fù)價值的性能損失蔗怠。

所以我們在前訴方案的基礎(chǔ)上嘗試了我們稱為Dynamic Route Loading的方案嘗試墩弯,確實(shí)提升了用戶體驗(yàn)的上升,但也帶來了很大的缺陷寞射,可供大家作為思路參考渔工。

本思路的核心為:當(dāng)前的單頁應(yīng)用均具有路由功能,并且均能夠提供Lazy Load Route的特性桥温。如果我們能夠通過某種手段欺騙單頁應(yīng)用的框架引矩,讓他能夠拿到拆分過的Lazy Load Route文件,進(jìn)而去加載對應(yīng)頁面侵浸,那么我們就可以做到無需應(yīng)用框架重啟旺韭,便可以加載不同業(yè)務(wù)。

那么我們可以通過Nginx的反向代理功能掏觉,讓應(yīng)用能夠順利拿到對應(yīng)路由的代碼区端,此方案的關(guān)鍵在于如何確保共有代碼絕對一致,從而保證框架能夠一直認(rèn)為其為一個完整的應(yīng)用澳腹。

Dynamic Router Loading 架構(gòu)示例圖.png

自然可以得出织盼,我們必須保證開發(fā)中加入一些限制條件,才能保證本方案能夠被順利執(zhí)行酱塔。

  1. 每個工程必須擁有所有業(yè)務(wù)的全量路由表:因?yàn)榧热辉跒g覽器上需要保證為一個單頁應(yīng)用的形式沥邻,那么應(yīng)用必須知道所有應(yīng)用的路由,才能正確地加載應(yīng)用延旧。
  2. 公同依賴(包含各個業(yè)務(wù)開發(fā)中沒有抽離到初始化代碼中谋国,但是都會使用的依賴,比如lodash)需要一致:應(yīng)用需要能被正確執(zhí)行迁沫,那么就必須保證頁面切換中芦瘾,頁面中所有部分的代碼都是基于同一套基礎(chǔ)依賴的,不然就無法保證應(yīng)用能夠被正確執(zhí)行集畅,比如A近弟,B站需要互相無刷新頁面切換,A站使用React開發(fā)挺智,B站使用Angular開發(fā)祷愉,兩天路由加載的邏輯根本的不同,你無法使用React的路由去加載Angular的路由代碼,反之亦然二鳄。當(dāng)然在實(shí)踐執(zhí)行中赴涵,你即便使用的同一套框架,很多細(xì)節(jié)的代碼也必須保持一致才能保持整個大應(yīng)用能準(zhǔn)確無誤的被執(zhí)行订讼。

凡事必有代價髓窜,這個方案在我們實(shí)踐中也帶來了不少問題。

你別看上面兩項限制看起來簡單欺殿,但是因?yàn)槲覀兊幕舅悸肥腔谀硞€現(xiàn)有的前端框架寄纵,然后將不同站點(diǎn)通過Nginx等代理軟件,偽裝成同一個單頁應(yīng)用的一部分來提示用戶體驗(yàn)脖苏。不同業(yè)務(wù)必須要保證其均能夠運(yùn)行在同一套代碼上下文下程拭,這本身就是本末倒置,之前方案一的出發(fā)點(diǎn)就是為了解耦應(yīng)用棍潘,讓業(yè)務(wù)開發(fā)者不需要了解其他團(tuán)隊怎么開發(fā)恃鞋,只需要保證符合業(yè)務(wù)需求即可。但是此方案導(dǎo)致:

  1. 開發(fā)者必須使用同樣的開發(fā)框架亦歉,本身就和微服務(wù)的開發(fā)框架選項無關(guān)性背道而馳山宾。
  2. 因?yàn)閼?yīng)用運(yùn)行在同一套框架執(zhí)行上下文上,而開發(fā)者團(tuán)隊又是在獨(dú)立開發(fā)和部署的開發(fā)模式下鳍徽。必然導(dǎo)致線上線下環(huán)境的割裂资锰,很多聯(lián)調(diào)的問題只會在上線部署配置完成后,一些執(zhí)行上下文的細(xì)微區(qū)別的影響才有可能會被暴露出來阶祭,輕則業(yè)務(wù)切換B后應(yīng)用行為和單獨(dú)訪問B的時候不一致绷杜,重則加載B站會導(dǎo)致應(yīng)用崩潰。

這個方案下濒募,由于環(huán)境的割裂鞭盟,業(yè)務(wù)開發(fā)者又不可能去了解整個應(yīng)用的開發(fā)進(jìn)展,必然導(dǎo)致很多錯誤會被推出到上線瑰剃,而排錯又需要了解整個運(yùn)行原理和所有團(tuán)隊的開發(fā)進(jìn)展齿诉,導(dǎo)致排錯困難。錯誤又難以在上線前排查出來晌姚。

這個方案而言粤剧,我們又進(jìn)一步做了一些優(yōu)化方案,其中比較好的方案是將公共依賴盡可能的抽出成為CDN挥唠,并且我們保證CDN上的版本總是最新的版本抵恋,這樣很多依賴版本導(dǎo)致的問題可以結(jié)合一些開發(fā)部署策略盡可能避免,這樣基本能夠被應(yīng)用起來宝磨,但不得不說弧关,離真正的前端微服務(wù)而言盅安,還有很長的路。

Other Solution Idea

還有其他的一些解決思路世囊,可以參考下這篇文章Building Microfrontends别瞭,其中最有希望的是Web Component方案,不過這個方案基于瀏覽器標(biāo)準(zhǔn)的實(shí)現(xiàn)株憾,而且每個組件部分其實(shí)完整的應(yīng)用畜隶,可能會引入一定的代碼冗余,但是是能滿足我們在獨(dú)立部署下不刷新切換頁面愿景的号胚,而且解耦的粒度更下,是頁面上的組件級別浸遗,是相對有潛力的一個方案猫胁。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市跛锌,隨后出現(xiàn)的幾起案子弃秆,更是在濱河造成了極大的恐慌,老刑警劉巖髓帽,帶你破解...
    沈念sama閱讀 207,248評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件菠赚,死亡現(xiàn)場離奇詭異,居然都是意外死亡郑藏,警方通過查閱死者的電腦和手機(jī)衡查,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評論 2 381
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來必盖,“玉大人拌牲,你說我怎么就攤上這事「柚啵” “怎么了塌忽?”我有些...
    開封第一講書人閱讀 153,443評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長失驶。 經(jīng)常有香客問我土居,道長,這世上最難降的妖魔是什么嬉探? 我笑而不...
    開封第一講書人閱讀 55,475評論 1 279
  • 正文 為了忘掉前任擦耀,我火速辦了婚禮,結(jié)果婚禮上涩堤,老公的妹妹穿的比我還像新娘埂奈。我一直安慰自己,他們只是感情好定躏,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評論 5 374
  • 文/花漫 我一把揭開白布账磺。 她就那樣靜靜地躺著芹敌,像睡著了一般。 火紅的嫁衣襯著肌膚如雪垮抗。 梳的紋絲不亂的頭發(fā)上氏捞,一...
    開封第一講書人閱讀 49,185評論 1 284
  • 那天,我揣著相機(jī)與錄音冒版,去河邊找鬼液茎。 笑死,一個胖子當(dāng)著我的面吹牛辞嗡,可吹牛的內(nèi)容都是我干的捆等。 我是一名探鬼主播,決...
    沈念sama閱讀 38,451評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼续室,長吁一口氣:“原來是場噩夢啊……” “哼栋烤!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起挺狰,我...
    開封第一講書人閱讀 37,112評論 0 261
  • 序言:老撾萬榮一對情侶失蹤明郭,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后丰泊,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體薯定,經(jīng)...
    沈念sama閱讀 43,609評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評論 2 325
  • 正文 我和宋清朗相戀三年瞳购,在試婚紗的時候發(fā)現(xiàn)自己被綠了话侄。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,163評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡学赛,死狀恐怖满葛,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情罢屈,我是刑警寧澤嘀韧,帶...
    沈念sama閱讀 33,803評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站缠捌,受9級特大地震影響锄贷,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜曼月,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評論 3 307
  • 文/蒙蒙 一谊却、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧哑芹,春花似錦炎辨、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽乙嘀。三九已至,卻和暖如春破喻,著一層夾襖步出監(jiān)牢的瞬間虎谢,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評論 1 261
  • 我被黑心中介騙來泰國打工曹质, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留婴噩,地道東北人。 一個月前我還...
    沈念sama閱讀 45,636評論 2 355
  • 正文 我出身青樓羽德,卻偏偏與公主長得像几莽,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子宅静,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評論 2 344

推薦閱讀更多精彩內(nèi)容