<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          你聽說過微前端框架 Satum 嗎?

          共 4602字,需瀏覽 10分鐘

           ·

          2022-06-07 14:49

          ?緣起

          hello,大家好,我是 RISC_V 生態(tài)業(yè)務(wù)團(tuán)隊(duì)的前端架構(gòu)師 谷童,本文是我 5.28 參加早早聊分享之后沉淀的一篇文章,文字版講解 Satum 的性能優(yōu)化策略,可能會(huì)更合一部分同學(xué)的口味。聲明一下,本文不是對(duì)分享的照搬,略有刪減。如果喜歡視頻版,請(qǐng)查閱早早聊 C43 大會(huì)錄播。

          什么是 Satum?

          考慮到部分小伙伴對(duì) Satum 不是很熟悉,我先簡單介紹一下這個(gè)框架。相比于市面上已經(jīng)開源的微前端框架,Satum 最重要的特點(diǎn)是面向多實(shí)例集成的場景,且諸如沙箱、緩存等功能是可插拔的。展開來說,該框架類似 express/koa 等框架,是微內(nèi)核化的,支持中間件和插件機(jī)制。所以可以基于該內(nèi)核,定制出適合自己團(tuán)隊(duì)的微前端體系。其他特性如集成能力強(qiáng)、共享機(jī)制靈活、無縫支持 Vite,如果想進(jìn)一步了解,請(qǐng)?jiān)L問官網(wǎng)地址。再看個(gè)簡單的示例吧,該示例也有線上版本,感興趣的話可以去編輯下。

          import?{
          ??MidwareName,
          ??HistoryType,
          ??register,
          ??start,
          ??use,
          ??corsRuleLabel,
          }?from?'@satumjs/core';
          import?{?simpleSandboxMidware?}?from?'@satumjs/simple-midwares';
          import?midwareSingleSpa?from?'@satumjs/midware-single-spa';

          register({
          ??name:?'vue-todomvc',
          ??entry:?'https://todomvc.com/examples/vue/',
          ??history:?HistoryType.HASH,
          ??rules:?{
          ????rule:?'/',
          ????container:?'#mountNode',
          ??},
          });

          use((system,?_,?next)?=>?{
          ??//?設(shè)置跨域服務(wù),使用中間件節(jié)點(diǎn)?MidwareName.urlOption
          ??//?該節(jié)點(diǎn)設(shè)置類型請(qǐng)參考?https://satumjs.github.io/website/guide/midware/flow-nodes.html#%E6%8C%89%E6%94%AF%E6%8C%81%E3%80%8E%E5%8D%95%E4%B8%AA-%E5%A4%9A%E4%B8%AA%E3%80%8F%E5%88%92%E5%88%86
          ??system.set(MidwareName.urlOption,?{
          ????corsRule:?`https://vklife.fun/proxy?target=${corsRuleLabel}`,
          ??});
          ??next();
          });

          //?使用簡單的沙箱
          use(simpleSandboxMidware);

          //?使用?single-spa?中間件處理微應(yīng)用的加載/卸載
          use(midwareSingleSpa);

          start({?hostHistoryType:?HistoryType.HASH?});

          不用糾結(jié)里面的代碼,簡單看下即可。use方法就是對(duì)中間件的調(diào)用。這樣幾十行代碼,執(zhí)行后就能看的@尤大 寫的 vue-todo 被集成到微應(yīng)用里了。

          從傳統(tǒng)優(yōu)化策略中借鑒

          傳統(tǒng)優(yōu)化策略,比較熟悉的莫過于“雅虎N條軍規(guī)”了。我梳理一下它的內(nèi)容,發(fā)現(xiàn)它包含以下 7 大板塊。其中很多“軍規(guī)”已經(jīng)融入開發(fā)中了,比如服務(wù)器端的那幾條。

          梳理后,發(fā)現(xiàn)可以借鑒的有以下幾條:

          • ?? ?減少 HTTP 請(qǐng)求數(shù)
          • ?? ?保持單個(gè)內(nèi)容小于 25K (偏移動(dòng)端)
          • ? ?緩存 Ajax 請(qǐng)求
          • ? ?預(yù)加載 / 延遲加載
          • ? ?盡早刷新輸出緩沖

          其中前兩條分別需要在業(yè)務(wù)中優(yōu)化,著重看后三條。緩存 Ajax 請(qǐng)求是后面的重頭戲,這里先略過。

          預(yù)加載 / 延遲加載

          Satum 已經(jīng)實(shí)現(xiàn)了預(yù)加載,當(dāng)頁面第一次進(jìn)入時(shí),框架會(huì)通過 requestIdleCallback 在空閑時(shí)間拉取非激活的微應(yīng)用相關(guān)的 html 和靜態(tài)資源,并放置在緩存中備用。可以在 start 函數(shù)執(zhí)行時(shí),傳遞配置項(xiàng) prefetch是 true,就能根據(jù)不同終端,預(yù)拉取該端所有微應(yīng)用的資源。延遲加載還沒實(shí)現(xiàn),不過已經(jīng)有一個(gè)理論可行的實(shí)施思路。后面實(shí)現(xiàn)了之后,再在社區(qū)同步。

          盡早刷新輸出緩沖

          這條建議軍規(guī)中是相對(duì)于服務(wù)端說的,大概意思就是盡快把 html 內(nèi)容發(fā)送到瀏覽器去呈現(xiàn)。可以借鑒其中的思想,把 html 模板和靜態(tài)資源內(nèi)容緩存到瀏覽器,渲染時(shí)優(yōu)先使用這些資源,并同時(shí)拉取遠(yuǎn)程的內(nèi)容,當(dāng)內(nèi)容不一致時(shí)再局部刷新。這個(gè)也是目前的設(shè)想,Satum 還沒實(shí)現(xiàn)。后面實(shí)現(xiàn)了之后,會(huì)在社區(qū)同步。

          先有度量再有優(yōu)化

          針對(duì)微前端中的微應(yīng)用優(yōu)化又能做些什么?談到性能優(yōu)化,先決條件肯定是度量出運(yùn)行數(shù)據(jù),分析數(shù)據(jù)才能對(duì)癥下藥。先梳理下微應(yīng)用的生命周期,來確定度量的埋點(diǎn)。

          Satum 把微應(yīng)用分為三類:新應(yīng)用、重新激活的應(yīng)用、沙箱復(fù)用的應(yīng)用。不同類型的應(yīng)用,生命周期略有不同。

          先看新激活的應(yīng)用,當(dāng)調(diào)度周期開始后,進(jìn)入資源拉取,拉取完成后進(jìn)入腳本在沙箱中執(zhí)行,執(zhí)行完成后當(dāng)掛載點(diǎn) ready 了就插入掛載點(diǎn)進(jìn)而渲染到頁面上。重新激活的應(yīng)用直接省去了資源遠(yuǎn)程拉取,而沙箱復(fù)用的應(yīng)用 因?yàn)樯诚涞臓顟B(tài)還在內(nèi)存中,只需要分配給它路徑 展現(xiàn)特定內(nèi)容的即可。

          這里稍微科普下 Satum 對(duì)微應(yīng)用的處理,一則便于理解所謂沙箱復(fù)用的應(yīng)用,二則便于理解后面沙箱層面上的優(yōu)化。Satum 是面向多實(shí)例集成,但也支持一個(gè)微應(yīng)用同一時(shí)間多處渲染。所以微應(yīng)用的承載有 MIcroApp 類和 Actor 類。而一個(gè) microApp 實(shí)例關(guān)聯(lián)多個(gè) actor 實(shí)例(簡單來說,就是 microApp 和 actor 是一對(duì)多的關(guān)系),每個(gè) actor 都有完整的沙箱但共用一個(gè) microApp 的配置。當(dāng)新的調(diào)度周期開始時(shí),舊的 actor 被卸載,但其相關(guān)的 microApp 可能還是處于激活狀態(tài)的,沙箱就可以被復(fù)用,讓新的 actor 使用。

          梳理完微應(yīng)用的生命周期,來確定下度量指標(biāo)包括:資源拉取耗時(shí)腳本執(zhí)行耗時(shí)渲染耗時(shí)卸載耗時(shí)。通過這些耗時(shí),就能直觀分析微應(yīng)用實(shí)際的運(yùn)行狀況,靈活的配置報(bào)警策略。

          而這些耗時(shí)數(shù)據(jù)的收集,是依賴 Satum 對(duì)每個(gè)階段做了性能埋點(diǎn):

          第一個(gè) scheduleSystemStart 是頁面初始化時(shí),調(diào)用 start 方法時(shí)觸發(fā)。

          scheduleCycleStart 是頁面初始化、每次 URL 變化時(shí),內(nèi)置的調(diào)度開始時(shí)觸發(fā)。在使用時(shí)可以當(dāng)成參考時(shí)間。

          后面這幾個(gè)都是成對(duì)出現(xiàn)的,和上面分析的生命周期對(duì)應(yīng),分別是資源拉取、腳本執(zhí)行、渲染階段的起始時(shí)間。

          通過對(duì)耗時(shí)數(shù)據(jù)的收集和分析,就能制定優(yōu)化和報(bào)警策略,進(jìn)而讓微應(yīng)用健康運(yùn)行。也能讓優(yōu)化的工作可以用數(shù)據(jù)量化,直觀展示價(jià)值。

          沙箱層面上的優(yōu)化

          使用微前端時(shí),可以很精細(xì)地控制每個(gè)微應(yīng)用的調(diào)度。可以調(diào)度微應(yīng)用腳本的執(zhí)行時(shí)機(jī),提升沙箱的復(fù)用性,內(nèi)容真正載入頁面的時(shí)機(jī)。下面可以從這三方面來闡述優(yōu)化點(diǎn)。

          腳本執(zhí)行時(shí)機(jī)

          Satum 因?yàn)橛泻莒`活的共享機(jī)制,包括三方庫的共享。所以當(dāng)一個(gè)微應(yīng)用依賴共享的三方庫時(shí),其腳本執(zhí)行時(shí)機(jī)和其他不依賴此的微應(yīng)用是不一樣的。如何設(shè)置三方庫的依賴呢?可以看下圖:

          可以看到上面的例子,main-app 是提供共享三方庫的微應(yīng)用,而 community-app 是依賴了三方庫的。只需要在配置文件里配置 externals聲明依賴哪些三方庫即可。

          Satum 不但支持共享三方庫,還支持運(yùn)行時(shí)的數(shù)據(jù)共享和靜態(tài)數(shù)據(jù),當(dāng)某個(gè)三方庫由其他微應(yīng)用共享時(shí),通過嵌套關(guān)系形成的依賴鏈,其子級(jí)微應(yīng)用也就能獲取到。

          如果不依賴三方庫,就不用等待,可以和其他微應(yīng)用并行執(zhí)行腳本;而依賴三方庫的,就只能等到三方庫 ready 時(shí)再執(zhí)行。對(duì)于三方庫的獲取,我使用了鏈表結(jié)構(gòu)的數(shù)據(jù)類型,可以很快查詢到。

          沙箱的復(fù)用性

          因?yàn)樯诚鋵?shí)例的創(chuàng)建和銷毀是有很大代價(jià)的,可以基于共同的 microApp 做到復(fù)用。實(shí)例化 actor 時(shí),我把 actor 分為六種類型,其中兩種是復(fù)用沙箱的。比如業(yè)務(wù)中 main 應(yīng)用提供了 layout、公共組件等,它自身又有一些業(yè)務(wù)比如首頁渲染、登錄注冊(cè)等。當(dāng)切換到它自身的路由時(shí) actor 是普通類型,當(dāng)切換到應(yīng)用商城時(shí),actor 又變成了 layout 類型。這期間牽涉到新舊 actor 的更替,但沙箱可以復(fù)用。

          內(nèi)容真正載入頁面時(shí)機(jī)

          這里利用了 MutationObserver 來實(shí)時(shí)監(jiān)聽 DOM 變化,盡快獲取到以便快速載入微應(yīng)用的 template 和 css 結(jié)束白屏。后面規(guī)劃對(duì)微應(yīng)用設(shè)置渲染優(yōu)先級(jí),可以更精細(xì)地控制某個(gè)板塊渲染。

          三級(jí)緩存方案實(shí)現(xiàn)頁面“秒開”

          什么是三級(jí)緩存呢?主要包含以下分類,它們分別存儲(chǔ)不同的內(nèi)容。這也和 CPU 的運(yùn)算單元有異曲同工之處。

          • 內(nèi)存緩存: 存儲(chǔ)激活過的微應(yīng)用 html/json 內(nèi)容
          • 軟緩存: 即會(huì)話緩存。存儲(chǔ)當(dāng)前 session 所有激活過的微應(yīng)用靜態(tài)資源
          • 硬緩存: 設(shè)置開啟后,存儲(chǔ)微應(yīng)用靜態(tài)資源,會(huì)比較類似文件進(jìn)行更新或刪除

          不同緩存的實(shí)現(xiàn),是由 @satumjs/midware-cachecode 提供支持,也可自行實(shí)現(xiàn)緩存機(jī)制。這里我有一個(gè)算是獨(dú)創(chuàng)的思路,即利用瀏覽器的數(shù)據(jù)庫 indexedDB,偽裝會(huì)話緩存,即軟緩存。實(shí)現(xiàn)思路是這樣的:

          當(dāng)調(diào)度系統(tǒng)調(diào)用緩存中間件時(shí),會(huì)先判斷是否禁用了軟硬緩存,如果都禁用了所有內(nèi)容緩存到內(nèi)存中;未被禁用的話,會(huì)判斷目前是 html/json 文件內(nèi)容,又沒有設(shè)置白名單強(qiáng)制走軟硬緩存,則會(huì)由內(nèi)存緩存處理。非 html/json 的文件繼續(xù)走下面的邏輯,判斷是否啟用硬緩存,如果是則直接由硬緩存邏輯處理。否的話則判斷 sessionStorage 里是否有標(biāo)志位,這意味著這個(gè)頁面是第一次進(jìn)入還是刷新,大家都知道 sessionStorage 是會(huì)話結(jié)束清除緩存,刷新不會(huì)清除。如果是第一次進(jìn)入,則先刪除已有的緩存,再寫入新的緩存。這樣做是防止老的緩存干擾。

          其實(shí)這塊先前的實(shí)現(xiàn),我使用的是 sessionStorage,方便是很方便不過有很多問題:容量僅有 5M,微應(yīng)用多了之后很容易用盡,而影響業(yè)務(wù)邏輯中使用 sessionStorage。而我看到瀏覽器的數(shù)據(jù)庫 indexedDB 是很理想的緩存載體,理論上講有無限的容量。但如何把它偽裝成會(huì)話緩存呢?于是想到使用一個(gè)標(biāo)志位來控制刪除緩存的時(shí)機(jī),讓它盡可能達(dá)到會(huì)話緩存的效果。

          最后

          以上就是分享的所有內(nèi)容。現(xiàn)在搞成文字版,方便查閱。上面談到大部分的優(yōu)化,都在 Satum 微前端內(nèi)核或中間件中有實(shí)現(xiàn)。歡迎加入微信群和釘釘群,關(guān)注和試用該框架,甚至基于內(nèi)核定制適合自己團(tuán)隊(duì)的微前端體系來。

          PS. 如果微信群的二維碼失效,請(qǐng)?zhí)砑游业奈⑿?valleykiddy 拉小伙伴入群哈~



          請(qǐng)你喝杯?? 記得三連哦~

          1.閱讀完記得給?? 醬點(diǎn)個(gè)贊哦,有?? 有動(dòng)力

          2.關(guān)注公眾號(hào)前端那些趣事,陪你聊聊前端的趣事

          3.文章收錄在Github?frontendThings?感謝Star?


          瀏覽 122
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  好操逼在线视频 | 好爽毛片一区二区三区色好美 | 日韩欧美黄 | 无码一区二区三区三 | 国产精品第一页在线观看 |