大前端時代,淺談JavaScript開發重型跨平臺應用以及架構

大前端時代以及即將到來的5G時代,3D可視化,音視頻直播技術,IM即時通信場景應用我以爲都是大有可爲的。前段時間爆款換臉應用出現,到近段時間頭像加🚩的火爆,這是好事。前端

不知不覺,九月就要過去,因爲這個月工做上,被C++折磨得很難受,並且其餘時間都在學習,因此沒有時間寫文章,好在技術提高很大。今天準備好好談一談重型應用的架構以及技術選型,爲接下來個人正式架構設計作個鋪墊。react

爲何寫重型應用的架構和技術選型

  1. 傳統的web前端,只能發個ajax請求,畫畫頁面。了不起寫個webApp
  2. 想讓後端的同窗們,瞭解下目前大前端的世界,如今的前端跟之前不同了,特別如今市場很缺高級前端,可是術業有專攻,這點我認可
  3. 大前端的定義,太普遍,在我看來,必須深刻前端某個方向,以及能獨立設計不那麼複雜場景下的後端架構。
  4. 在極客時間上提問了winter老師,我自我感受已經良好,可是迷茫了。他回懟了我:想想你用你的技術作出了什麼nb的東西把。
  5. 是人都想作出點什麼事情,我想引發你們的共鳴去使用某些技術,或者朝着這個方向去發展,共同提高 社區的技術總體層次

什麼是重型應用

例如微信,QQ,Telegram, 以及一些工具類的應用linux

說到這些你們確定以爲,爲何不說是遊戲? 固然遊戲也算,但是我相信作出1000萬人天天都在用的產品是你們的夢想,起碼能吹一生吧git

工具類的東西實際上是最難作的,好比vsCodeExcelPhotoShop這些。這也是爲何這麼多年出現成功的工具類產品這麼少。這裏不得不提到vsCode,它其實就是用ELectron開發,基於TypeScript。固然確定使用了很多C++插件,說到這裏,留下傷心的眼淚,最近也是被折磨得很難受程序員

成功開發一個重型應用的好處

  1. 出去面試基本上很容易成功,特別是專業性強的崗位,例如你在QQ開發了十幾年,你根本不用出去找工做,固然你應該也不會跑
  2. 技術全面,複雜場景你都能hold
  3. 有能吹的地方,能夠跟誰說:我開發的東西,多少萬人在用,老了還能吹。 程序員嘛,一半時間都在吹水,還有接近一半時間在划水,只有一丁點時間在寫代碼
  4. 更容易財務自由,生活自由,例如如今不少有過成功的重型應用開發者已經不單純靠代碼產出維持生活。他們作技術顧問,賣課程,出書,辦培訓都甚至比單純寫業務代碼賺得多不少

正式開始

  • 目前跨平臺框架,移動端比較成熟的是React-native,可是你們有所瞭解的都應該知道,這個框架雖然生態比較成熟,可是在面對衆多手機的適配難度,以及性能方面存在的缺陷,若是用它製做重型應用我以爲是不合適的,若是要作重型應用,移動端應該使用原生。
  • 庫克說過,中國的移動端開發確實很強,美國人要作一個應用,首先考慮的是PC桌面端,而國內首先考慮的是移動端。

國內移動端開發人員,在我看來已經人目前已經夠多了,若是說你如今不會React-nativeFlutter,我也不建議你去深刻學習,特別是Flutter.github

爲何要這麼說?web

React-native剛出來的時候,坑多吧。如今Flutter也是,但是當你從RN最初的版本踩坑踩到如今,以前踩的坑大都沒有意義(說這些話想過被噴,可是...此處省略一萬字,建議去了解下原理和基本使用,不要耗費太多時間)面試

一個技術你去使用,並非它多流行,只要它足夠流行。 ---來自某位國內大佬ajax

技術的學習,應該多往底層鑽研,若是你走錯了路,鑽錯了方向,浪費了時間得不償失,我以前有說過,前端最核心的幾個基礎知識點,應用層的東西曆來不會很難。前提你的基礎足夠紮實數據庫

前端20個真正靈魂拷問,吃透這些你就是中級前端工程師 【上篇】

前端20個靈魂拷問 完全搞明白你就是中級前端工程師 【中篇】

前端20個靈魂拷問 完全搞明白你就是中級前端工程師 【下篇】

這些文章不少同窗應該都看過,爭議也很大,在我如今看也寫得很爛,可是它裏面的知識點是夠的。固然你必需要去結合起來,而後深刻學習每一個知識點。

既然說了移動端沒有合適的重型跨平臺應用開發框架,那麼只有PC端了。還有多少小夥伴在PC端開發呢?

Electron開發,來了

我不止一次提到過這個框架,我以爲它真是一個很是棒的框架,爲何這麼說呢?

  1. 我跟不少朋友說過,若是想開發APP,不會寫原生,那麼你確定達不到某種境界。由於你始終有不少不少的黑盒過程,但是Electron就會大大下降這個機率。
  2. 基本上沒有適配和差別性,linuxMac以及Windows三者均可以運行,除了Mac上某些特殊場景須要本身設計下菜單快捷鍵之類,以及一些文件IOMAC默認行爲
  3. 最新的Node版本、運行的V8環境以及最新的谷歌瀏覽器一塊兒被打包,最新的技術和API均可以用,無需適配擔憂兼容性,真正放飛自我,能夠隨時隨刻用Node.js實現功能,甚至調用大量C++插件,著名的VSCode就是這樣而來

你甚至能夠當作Electronweb網頁套上一層殼,你能夠在主進程寫你的Node.js去實現功能,渲染進程你怎麼寫怎麼寫,還能夠呼叫封裝好的原生接口。遇到特別複雜的需求,用C++插件去實現吧

最終打包出來的安裝包跟正常的桌面應用是同樣的,正常安裝卸載等,都已經封裝好。

目前GitHub上已經有77.2Kstar

應用層面的東西,大都不會太難,Electron的文檔已經很是全面,基於它出現了不少複雜,並且成功的工具類重型應用。我相信它

whatsApp也是基於它,國外還有一些很NB的應用也是。這裏不作過多闡述,能夠肯定它是一個成熟並且成功的框架

可能不少人看到這裏又要說標題黨了,別急,下面來乾貨。

重型應用架構注重的核心問題

  1. 項目自己的最重要功能是什麼
  2. 項目自己出發點是爲客戶提供什麼方便
  3. 項目的核心競爭力是什麼

一個好的開發,它必定能懂一些產品,甚至測試,固然他也應該會炒河粉,35歲之後好維持生活

咱們今天舉一個例子,IM,即時通信,Telegram,20萬人超級羣端到端加密的核心賣點產品

電報Telegram

如今回答上面三個問題:

項目自己的最重要功能是什麼

答案:即時通信,信息的收發

項目自己出發點是爲客戶提供什麼方便

使用產品進行消息傳遞

項目的核心競爭力是什麼

20萬人的超級羣,端到端加密,隱私足夠安全

核心競爭力,每每表明了這個應用產物的技術最難點,由於誰都能作,那麼就不是核心競爭力了

因此咱們其餘的都忽略,關注第三點,開始進行技術選型,架構。

單線程的Node.jsJavaScript重型應用架構設計

要想寫好這個架構,我以爲你首先在自身的擅長領域不能有太多的黑盒過程。例如框架源碼,庫原理實現,瀏覽器和Node.js的事件EventLopp以及他們的缺陷,你要熟知在心。由於像這種應用,一個小方向可能就會掏空你的技術棧,耗盡你的精力,例如音視頻、圖片處理等。

單線程的Node.js以及js主解析引擎,讓咱們又愛又恨。

這款應用的核心競爭力,是20萬人超級羣,那麼數據量很大,大批量渲染壓力和頻繁加解密計算耗時、頻繁數據庫寫入壓力都是不可避免的,那麼咱們的Node.js擅長異步非阻塞,以及前端渲染進程的異步就顯得尤其重要

前端架構總體的核心除了技術選型以及大致框架外,就是任務調度。

這裏的任務調度分兩種:

1.渲染任務調度

2.非渲染任務調度

單個渲染任務調度

1.React框架中,屢次傳入對象,setState會自動合併到一次執行,其實就是一種節流思想

2.ReactFiber架構思想,把若干個任務分割成多個小任務執行,中間根據你的任務優先級安排去選擇時機執行

3.淘寶的分片渲染方案,跟上面第二條有一些相似

我以前說過,應用層的東西都不難,只要你基礎足夠紮實,能手寫出簡單的框架,以及庫。你絕對能很是輕鬆應對前端百分80以上的性能問題和需求,技術最終都是類似的

上面只是說了別人的一些比較簡單的優化方案,下面纔是開始咱們本身的渲染任務調度:

回到咱們的Telegram架構設計方案:

渲染任務架構過程須要着重考慮的幾個問題:

1.渲染數據量特別大

2.更新特別頻繁

3.儘量手動回收垃圾,避免消息量過大,v8垃圾回收的時間不肯定性致使內存被白白佔用,引發卡頓

4.考慮大批量數據到達渲染進程的用戶應用體驗,肯定用戶交互屬於高優先級任務,其餘的哪些是低優先級-但必須執行的任務,哪些是中優先級任務,這裏說的任務,都是渲染任務。

今天在學習一篇小冊,裏面有一句話引發了個人共鳴,在計算機的世界,若是有解決不了的問題,那就加一箇中間層,若是還不行,那就加兩個。 -後面這句是我加的

這個是我本身編寫的Reactmini-react源碼地址

PReact源碼中,是將須要更新的組件放入隊列中,而後一次清空,僞代碼:

if (setStateQueue.length === 0) {
    //清空隊列的辦法是異步執行 
    defer(flush);
  }
     setStateQueue.push({
    stateChange,
    component
  });

    function defer(fn) {
      //requestIdleCallback的兼容性很差,對於用戶交互頻繁屢次合併更新來講,requestAnimation更有及時性高優先級,requestIdleCallback則適合處理能夠延遲渲染的任務~
      //   if (window.requestIdleCallback) {
      //     console.log('requestIdleCallback');
      //     return requestIdleCallback(fn);
      //   }
      //高優先級任務
      return requestAnimationFrame(fn);
    }


  while ((component = renderQueue.shift())) {
    renderComponent(component);
  }



複製代碼

上面這段代碼其實很重要,核心思想就是:

每當進入這個函數,若是發現隊列隊列裏沒有任務就去執行defer函數

defer函數執行是異步,此時defer下面的setStateQueue已經被push了進去數據,這樣達到一幀完成一次渲染任務調度

固然上面僅僅一個小的任務調度,這個必需要了解,才能往下看


requestAnimationFramerequestIdleCallback使用:

你須要深刻了解React框架的Fiber架構,這塊尤爲重要,是性能優化,任務調度的基礎,上面有提到,React在每次diff對比階段,將任務分割成若干個小任務,此時若是有RAFRID的任務,就要考慮去執行了

RAF的任務會每次在下一次小任務前執行

RID的任務只有在下一次小人物前,有空餘時間纔會執行,因此它不必定會執行。(特別高頻必須執行的任務)

Fiber架構配合單個任務分割已經介紹完畢,下面出思惟導圖出總體的任務調度


總體渲染任務調度

核心的兩點:

1.釋放主線程的佔用,讓用戶的操做最快獲得響應

2.合理調度任務,分高、中、低三種優先級別任務

理清思路:

1.數據經過IPC通訊到達渲染進程

2.所有交給子線程去進行計算,組裝數據,經過異步的postMessage事件通訊,拿到渲染數據

3.調度渲染任務,用戶操做交互

4.釋放主線程

這裏特別提示,爲何我一直強調不要使用定時器,一旦應用變得很複雜,若是任務調度不合理,定時器裏的代碼是要好久好久才能執行的。固然,只有重型應用會這樣

渲染任務調度這塊,主要是微任務,RAF,RID分片渲染以及同步代碼,隊列調度等手段。

主進程,接入層任務調度

核心思想跟渲染進程大概一致:

1.儘可能釋放主進程,保持空閒,讓用戶的操做即時獲得反饋,由於不少操做會調用主進程的接口

2.異步調度任務,寫入數據庫異步,解密計算可使用nextTick等方式去調度添加隊列

這裏提到,任務調度的核心一點就是,頻繁觸發的任務必須加入隊列,異步清空,不然像解密這種同步計算耗時,一旦被頻繁觸發就會引發阻塞。即便交給了其餘進程,也要作隊列

總體架構以及技術選型注意點

1.技術選型時,儘可能選擇本身熟悉它原理的庫,以及能用Demo測試模擬場景的技術,測試經過再選用,不一樣技術之間解決問題出發點不同,可能會有衝突

2.隊列和多進程、多線程的開啓,並非必定須要的,你能夠本身設定一套規則,當一段時間的任務到達多少次被觸發時候選擇開啓多線程,多進程。不然就是浪費

3.重型應用架構遠不止這些,因此標題是淺談,等下個月技術做者再度飛速提高一波,再來談這些。

這裏推薦關注做者的微信公衆號:前端巔峯

發送加羣,我會將你拉進 前端交流羣,不少小姐姐哦~

技術氛圍槓槓滴~ 關鍵漂亮的小姐姐也在裏面哦~

若是以爲寫的不錯,必定要點個贊再走,必定哦~

相關文章
相關標籤/搜索