Flutter爲何使用Dart?

老孟導讀:關於Flutter爲何使用Dart?這個話題,就像PHP是世界上最好的語言同樣,爭論歷來沒有中止過,有不少說法,好比:node

  • Google是爲了推廣Dart,Dart是親兒子。
  • Flutter團隊和Dart團隊相鄰,溝通起來更方便。

或許存在這樣的考慮,但即便是親兒子,爛泥也要能扶上牆才行啊,難道你真的以爲如此重大的決定是靠這些主觀色彩決定的?不可能的,因此Dart必定是有其很是大的優點。git

前言

在Flutter成立之初,Flutter團隊評估了10多種語言,Flutter團隊從四個主要維度進行評估,並考慮了框架做者,開發人員和最終用戶的需求。最終Dart在全部評估維度上得分都很高,而且符合全部要求和標準。程序員

Dart在如下主要標準上贏得了高分:github

  • 開發人員的生產力。Flutter的主要價值主張之一是,它可讓開發人員使用相同的代碼庫爲iOS和Android建立應用程序,從而節省了工程資源。使用高效的語言能夠進一步加速開發人員,並使Flutter更具吸引力。這對咱們的框架團隊和開發人員都很是重要。Flutter的大多數語言都是用與咱們提供給用戶的語言相同的語言構建的,所以咱們須要在不犧牲開發人員的框架和小部件的可訪問性或可讀性的狀況下,保持100k的代碼行的生產力。
  • 面向對象。對於Flutter,咱們須要一種適合Flutter問題領域的語言:建立視覺用戶體驗。該行業擁有數十年使用面嚮對象語言構建用戶界面框架的經驗。儘管咱們可使用非面向對象的語言,但這將意味着從新發明輪子來解決一些難題。另外,絕大多數開發人員都有面向對象開發的經驗,這使得學習Flutter開發方法變得更加容易。
  • 可預測的高性能。藉助Flutter,咱們但願使開發人員可以建立快速,流暢的用戶體驗。爲了實現這一點,咱們須要可以在每一個動畫幀中運行大量的最終開發人員代碼。這意味着咱們須要一種既能提供高性能又能提供可預測的性能的語言,而又不會致使幀丟失的按期暫停。
  • 快速分配。Flutter框架使用一種功能樣式的流程,該流程在很大程度上依賴於基礎內存分配器,能夠有效地處理短暫的短時間分配。此樣式是使用具備此屬性的語言開發的,在缺乏此功能的語言中沒法有效工做。

Dart

如下是Dart功能的列表,這些功能對於Flutter來講是必不可少:web

  • Dart是AOT(Ahead Of Time)編譯的,編譯成快速,可預測的本機代碼,幾乎全部Flutter均可以用Dart編寫。這不只使Flutter更快,並且幾乎全部內容(包括全部小部件)均可以自定義。
  • Dart還能夠經過JIT(Just In Time)進行編譯,以實現異常快速的開發週期和改變遊戲規則的工做流(包括Flutter亞秒級有狀態熱重裝)。
  • Dart使建立以60fps運行的平滑動畫和過渡更加容易。Dart能夠在沒有鎖的狀況下進行對象分配和垃圾回收。與JavaScript同樣,Dart避免了搶先式調度和共享內存(從而避免了鎖定)。由於Flutter應用程序已編譯爲本機代碼,因此它們不須要在領域之間創建緩慢的橋樑(例如,JavaScript與本機之間)。它們的啓動速度也快得多。
  • Dart容許Flutter避免使用像JSX或XML這樣的聲明式佈局語言,也不須要單獨的可視化界面構建器,由於Dart的聲明式程序化佈局易於閱讀和可視化。並且,因爲全部佈局都以一種語言和一種位置顯示,所以Flutter能夠輕鬆地提供使佈局變得輕鬆的高級工具。
  • 開發人員發現Dart特別易於學習,由於它具備靜態和動態語言用戶都熟悉的功能。

並不是全部這些功能都是Dart獨有的,可是它們的結合達到了一個甜蜜點,這使得Dart在實施Flutter方面具備獨特的功能。如此之多,很難想象Flutter會像沒有Dart同樣強大。數據庫

編譯與執行

若是您已經瞭解靜態和動態語言,AOT和JIT編譯以及虛擬機等主題,則能夠跳過本節。編程

從歷史上看,計算機語言已分爲兩類:靜態語言(例如,Fortran或C,其中在編譯時靜態鍵入變量)和動態語言(例如,Smalltalk或JavaScript,其中,變量的類型能夠在運行時更改)時間)。一般會編譯靜態語言,以生成目標計算機的本機代碼(或彙編代碼)程序,這些程序在運行時由硬件直接執行。動態語言由解釋器執行,而不會產生機器語言代碼。設計模式

固然,後來事情變得更加複雜。虛擬機(VM)的概念變得很流行,它實際上只是一種模仿軟件中的硬件機器的高級解釋器。虛擬機能夠更輕鬆地將語言移植到新的硬件平臺。在這種狀況下,VM的輸入語言一般是中間語言。例如,一種編程語言(例如Java)被編譯成一種中間語言(字節碼),而後在VM(JVM)上執行。瀏覽器

另外,如今有即時(JIT)編譯器。JIT編譯器會在程序執行期間運行,並進行即時編譯。在程序建立期間(運行時以前)執行的原始編譯器如今稱爲提早(AOT)編譯器。安全

一般,只有靜態語言才適合將AOT編譯爲本機機器代碼,由於機器語言一般須要知道數據的類型,而在動態語言中,類型不是預先固定的。所以,一般會解釋動態語言或編譯JIT。

在開發過程當中 AOT 編譯,開發週期(從更改程序到可以執行程序以查看更改結果的時間)老是很慢。可是 AOT 編譯產生的程序能夠更可預測地執行,而且運行時不須要停下來分析和編譯。AOT 編譯的程序也更快地開始執行(由於它們已經被編譯)。

相反,JIT編譯可提供更快的開發週期,但會致使執行速度較慢或更加不穩定。特別是,JIT編譯器的啓動時間較慢,由於在程序開始運行時,JIT編譯器必須在執行代碼以前進行分析和編譯。研究代表,若是開始執行須要花費幾秒鐘的時間,那麼不少人就會放棄該應用程序。

以上就是 AOT 和 JIT 相關知識,將 AOT 和 JIT 編譯的優勢結合起來不是很棒嗎?而Dart就是經過支持AOT 和 JIT 兩種類型的編譯而帶來顯著的優點。

編譯並執行Dart

在研究Dart以前,Dart團隊的成員已經在高級編譯器和虛擬機上進行了開創性的工做,既針對動態語言(如JavaScript 的V8引擎,針對Smalltalk的Strongtalk)又針對靜態語言(如Java 的Hotspot編譯器)。他們利用這種經驗使Dart在如何進行編譯和執行方面異常靈活。

Dart是極少數適合於同時編譯AOT和JIT的語言之一。支持這兩種編譯爲Dart和(尤爲是Flutter)提供了明顯的優點。

在開發過程當中使用JIT編譯,使用的編譯器特別快。而後,當應用程序準備發佈時,將對其進行AOT編譯。所以,藉助先進的工具和編譯器的幫助下,提供一箭雙鵰的方案:極快的開發週期,並快速執行和啓動時間。

Dart在編譯和執行方面的靈活性不止於此。例如,Dart能夠編譯爲JavaScript以便瀏覽器能夠執行。這容許在移動應用程序和Web應用程序之間重複使用代碼。開發人員報告說,他們的移動和Web應用程序之間的代碼複用率高達70%。經過將Dart編譯成本機代碼,或編譯成JavaScript並將其與node.js結合使用,也能夠在服務器上使用Dart 。

最後,Dart還提供了一個獨立的VM,該VM使用Dart語言自己做爲其中間語言(本質上像解釋器同樣工做)。

Dart能夠有效地編譯AOT或JIT,解釋或轉換爲其餘語言。Dart的編譯和執行不只異常靈活,並且速度特別

有狀態熱重載

Flutter最受歡迎的功能之一是其極快的熱重載。在開發期間,Flutter使用JIT編譯器,該編譯器一般能夠在一秒鐘內從新加載並繼續執行代碼。只要有可能,應用狀態就會在每次從新加載時保持不變,所以該應用能夠從中斷處繼續運行。

除非您親自體驗過,不然很難理解真正快速(可靠)的熱重載在開發過程當中有多重要。Flutter的熱加載功能使嘗試新想法或嘗試替代方法變得容易得多,極大地促進了創造力。

如下是一位移動應用程序開發人員對Flutter 熱重載的評價:

我想測試熱重載,因此我改變了顏色,保存修改,結果……就喜歡上它了❤!

這個功能真的很棒。我曾認爲 Visual Studio 中編輯和繼續(Edit & Continue)很好用,但這簡直使人驚歎。有了這個功能,我認爲移動開發者的生產力能夠提升兩倍。

這對我來講真的是翻天覆地的變化。當我部署代碼並花費很長時間時,我分心了,作了其餘事情,當我回到模擬器 / 設備時,我就忘了想測試的內容。有什麼比花 5 分鐘將控件移動 2px 更使人沮喪?有了 Flutter,這再也不存在。

避免卡頓

一個快速的應用程序是偉大的,但流暢的應用程序,甚至更好。即便是超級快的動畫,若是看起來很生澀,也會看起來很糟糕。可是,防止卡頓可能很困難,由於因素太多。Dart 有許多功能能夠避免許多常見的致使卡頓的因素。

固然,(像任何語言同樣)仍然能夠在Flutter中編寫一個簡陋的應用程序。Dart更具可預測性,可幫助開發人員更好地控制其應用的平滑度,從而更輕鬆地提供最佳的用戶體驗,無所不能。

Flutter建立的用戶界面以60 fps的速度運行,其性能遠優於其餘跨平臺開發框架建立的用戶界面。

不只比跨平臺應用程序更好,並且與最佳本機應用程序同樣好:

用戶界面很是流暢……我從未見過如此流暢的Android應用。

AOT彙編和「橋樑」

咱們討論過一個有助於保持順暢的特性,那就是 Dart 能 AOT 編譯爲本地機器碼。預編譯的 AOT 代碼比 JIT 更具可預測性,由於在運行時不須要暫停執行 JIT 分析或編譯。

可是,AOT編譯代碼有一個更大的優點,那就是避免了「 JavaScript橋樑」。當動態語言(例如JavaScript)須要與平臺上的本機代碼進行互操做時,它們必須經過網橋進行通訊,這會致使上下文切換必須保存大量的狀態(可能保存到輔助存儲)。這些上下文切換是雙重打擊,由於它們不只使速度變慢,並且可能致使嚴重的問題。

注意:即便編譯的代碼也可能須要與平臺代碼進行對話的接口,這也能夠稱爲橋接,可是一般比動態語言所需的橋接要快幾個數量級。此外,因爲Dart容許將小部件之類的內容移入應用程序,所以減小了跨過橋樑的須要。

搶先式調度,時間分片和共享資源

大多數支持多個併發執行線程的計算機語言(包括Java,Kotlin,Objective-C和Swift)都使用搶佔線程之間進行切換。每一個線程都分配了一個「執行時間」,若是超過了分配的時間,則使用上下文切換來搶佔該線程。可是,若是在更新線程(例如內存)之間共享的資源時發生了搶佔,則這會致使爭用條件。

競爭情況是雙重打擊,由於它們可能致使嚴重的錯誤,包括使應用程序崩潰並致使數據丟失,並且因爲依賴於獨立線程的相對時間,所以特別難以查找和修復它們。在調試器中運行應用程序時,競爭條件會中止表現出來,這很常見。

解決爭用條件的典型方法是使用防止其餘線程執行的鎖來保護共享資源,可是鎖自己可能會致使棘手甚至更嚴重的問題(包括死鎖飢餓)。

Dart 採起了不一樣的方法來解決這個問題。Dart 中的線程稱爲 isolate,不共享內存,從而避免了大多數鎖。isolate 經過在通道上傳遞消息來通訊,這與 Erlang 中的 actor 或 JavaScript 中的 Web Worker 類似。

Dart和JavaScript同樣,都是單線程的,這意味着它根本不容許搶佔。相反,線程顯式地產生(使用async / await,FuturesStreams)。這使開發人員能夠更好地控制執行。單線程可幫助開發人員確保關鍵功能(包括動畫和過渡)在沒有搶佔的狀況下得以執行。這不只對用戶界面,並且對於其餘客戶端-服務器代碼,一般都是一個很大的優點。

固然,若是開發人員忘記放棄控制,這可能會延遲其餘代碼的執行。可是,咱們發現,忘記屈服一般比忘記鎖定容易得多(由於很難找到競爭條件)。

對象分配和垃圾回收

形成垃圾的另外一個嚴重緣由是垃圾收集。確實,這只是訪問共享資源(內存)的一種特殊狀況,在許多語言中,這都須要使用鎖。可是在收集可用內存時,鎖可能會阻止整個應用程序運行。可是,Dart幾乎能夠在沒有鎖的狀況下幾乎始終執行垃圾回收。

Dart 使用先進的分代垃圾回收和對象分配方案,該方案對於分配許多短時間對象(對於Flutter 這樣的反應式用戶界面來講很是完美,Flutter 爲每幀重建不可變視圖樹)而言很是快。Dart 能夠用一個指針凹凸分配一個對象(無需鎖定)。這將致使平滑的滾動和動畫效果,而不會產生現卡頓。

統一佈局

Dart的另外一個好處是Flutter不會在您的程序和其餘模板化或佈局語言(例如JSX或XML)之間拆分佈局,也不須要單獨的可視化佈局工具。這是用Dart編寫的簡單Flutter視圖:

Center(child:
  Column(children: [
    Text('Hello, World!'),
    Icon(Icons.star, color: Colors.green),
  ])
)複製代碼

可是,我知道您可能在想什麼- 缺乏專門的佈局語言如何被稱爲優點?但它確實是顛覆性的。這是開發人員在題爲「 爲何本機應用程序開發人員應認真看待Flutter 」 的文章中寫的。

在 Flutter 裏,界面佈局直接經過 Dart 編碼來定義,不須要使用 XML 或模板語言,也不須要使用可視化設計器之類的工具。

個人預感是,聽到這個消息後,大家中的一些人甚至會畏縮一點。表面看來,這也是個人反應。使用視覺工具進行佈局難道不是一件容易的事。用代碼編寫各類約束邏輯會不會使事情變得過於複雜?

結果否則。天啊,它簡直讓我大開眼界。

答案的第一部分是上面提到的熱重載。

這比 Android 的 Instant Run 和任何相似解決方案不知道要領先多少年。對於大型的應用一樣適用。如此快的速度,正是 Dart 的優點所在。

實際上,可視化編輯器就變得多餘了。我一點都不懷戀 XCode 的自動重佈局。

Dart 建立的佈局簡潔且易於理解,而「超快」的熱重載可當即看到結果。這包括佈局的非靜態部分。

結果,在 Flutter 中進行佈局要比在 Android/XCode 中快得多。一旦你掌握了它(我花了幾個星期),因爲不多發生上下文切換,所以會節省大量的開銷。沒必要切換到設計模式,選擇鼠標並開始點擊,而後想是否有些東西必須經過編程來完成,如何實現等等。由於一切都是程序化的。並且這些 API 設計得很是好。它很直觀,而且比自動佈局 XML 更強大。

例如,下面是一個簡單的列表佈局,該列表佈局以編程方式定義的全部其餘項目之間添加了分隔線(水平線):

return new ListView.builder(itemBuilder: (context, i) {
  if (i.isOdd) return new Divider(); 
  // rest of function
});複製代碼

在 Flutter 中,不管是靜態佈局仍是編程佈局,全部佈局都存在於同一個位置。新的Dart 工具,包括Flutter Inspector 和大綱視圖(利用全部的佈局定義都在代碼裏)使複雜而美觀的佈局更加容易。

Dart是專有語言嗎?

不,Dart(如 Flutter)是徹底開源的,具有清楚的許可證,同時也是 ECMA 標準的。Dart 在 Google 內外很受歡迎。在谷歌內部,它是增加最快的語言之一,並被 Adwords、Flutter、 Fuchsia 和其餘產品使用;在谷歌外部,Dart 代碼庫有超過 100 個外部提交者。

Dart開放性的更好指標是Google之外社區的發展。例如,咱們看到來自第三方的Dart文章和視頻源源不斷(包括Flutter和AngularDart),我在本文中引用了其中的一些。

除了Dart自己的外部提交者以外,公共Dart軟件包存儲庫中還有3000多個軟件包,包括Firebase,Redux,RxDart,國際化,加密,數據庫,路由,集合等的庫。

Dart程序員會容易找到嗎?

若是沒有不少程序員知道Dart,找到合格的程序員會更困難嗎?固然不是,Dart使它更容易找到程序員,由於它是一種很是快速且易於學習的語言。Java,JavaScript,Kotlin,C#或Swift等語言的程序員幾乎能夠當即在Dart中開始編程。最重要的是,熱重載鼓勵用戶玩Dart並嘗試新事物,這使得學習Dart更快,更愉快。

這是一個程序員在題爲「 爲何Flutter將在2018年騰飛 」的文章中所說的:

Dart是用於開發Flutter應用程序的語言,學習起來很容易。Google擁有建立簡單,記錄良好的語言(例如Go)的經驗。到目前爲止,對我而言,Dart使我想起了Ruby,這是一種學習的樂趣。它不只適用於移動設備,也適用於Web 開發

另外一篇關於Flutter和Dart的文章,標題爲「 爲何要Flutter?而不是框架X?甚至更好,爲何我要盡心盡力。

Flutter使用由Google建立的Dart語言,說實話,我不喜歡C#或JAVA之類的強類型語言,但我不知道Dart編寫代碼的方式爲何看起來有所不一樣。我寫起來很舒服。也許是由於它很是簡單易學。

經過普遍的UX研究和測試,Dart專門設計爲熟悉且易於學習。例如,在2017年上半年,Flutter團隊與八名開發人員進行了UX研究。咱們向他們簡要介紹了Flutter,而後將它們鬆散了一個小時左右,以建立一個簡單的視圖。全部參與者都可以當即開始編程,即便他們之前從未使用過Dart。他們專一於編寫響應式視圖,而不是語言。Dart 直接就能上手用了。

最後,一位參與者(在任務中取得了特別大的進步)沒有說起該語言,所以咱們詢問他們是否意識到本身使用的是哪一種語言。他們不知道。語言不要緊 ; 他們在幾分鐘內就能夠在Dart中編程。

學習新系統的難點一般不是學習語言,而是學習全部編寫好的代碼的庫,框架,工具,模式和最佳實踐。並且Dart庫和工具都很是出色,而且文檔齊全。一篇文章宣稱:「做爲獎勵,他們還很是注意本身的代碼庫,而且擁有我見過的最好的文檔。」 學習Dart只需花不多的精力就能夠經過節省學習其他時間的時間來彌補。

做爲直接的證據,Google內部的一個大型項目但願將其移動應用程序移植到iOS。他們打算僱用一些iOS程序員,但決定嘗試Flutter。他們監控了使開發人員快速掌握Flutter所花費的時間。他們的結果代表,程序員能夠在三週內學習Dart Flutter並提升工做效率。相比之下,他們以前觀察到的五個星期可使程序員僅在Android上就能夠上手(更不用說他們必須僱用和培訓iOS的開發人員)。

最後,文章「 咱們爲何選擇Flutter以及它如何使咱們的公司變得更好 」來自一家將大型企業應用程序遷移到全部三個平臺(iOS,Android和Web)上的Dart的公司。他們的結論:

招人變得容易多了。不管他們是來自 Web、iOS 仍是 Android,咱們如今都但願接受最佳人選。

如今咱們擁有 3 倍的工做效率,由於咱們全部的團隊都集中在一個代碼庫上。

知識共享達到史無前例的高度。

經過使用Dart和Flutter,他們可以將生產力提升三倍。鑑於他們以前所作的事情,這不足爲奇。與許多公司同樣,他們正在使用獨立的語言,工具和程序員爲每一個平臺(Web,iOS和Android)構建獨立的應用程序。改用Dart意味着他們再也不須要僱用三種不一樣的程序員。對於他們來講,將現有的程序員轉移到Dart上很容易。

他們和其餘人發現,一旦程序員開始使用Flutter,他們一般會愛上Dart。他們喜歡語言的簡潔性和缺少儀式感。他們喜歡語言功能,例如級聯,命名參數,異步/等待和流。最重要的是,他們喜歡Dart所提供的Flutter功能(例如熱重載),而Dart幫助他們構建的漂亮,高性能的應用程序。

祕訣就是專一

Dart 2中的改進集中在優化客戶端開發上。可是Dart仍然是構建服務器端,臺式機,嵌入式系統或其餘程序的絕佳語言。

專一是一件好事。專一於幾乎可使全部持久的流行語言受益。例如:

  • C是用於編寫操做系統和編譯器的系統編程語言。它變得更多了。
  • Java是爲嵌入式系統設計的語言。
  • JavaScript是Web瀏覽器的腳本語言(!)。
  • 甚至備受反對的PHP也成功了,由於它專一於編寫「我的主頁」(並以此爲名)。

另外一方面,許多語言已經明確嘗試(但失敗)成爲徹底通用的語言,例如PL / 1和Ada等。最多見的問題是,沒有集中注意力,這些語言就成了衆所周知的廚房水槽。

使Dart成爲出色的客戶端語言的許多功能也使它成爲服務器端使用的更好語言。例如,Dart避免了搶先式多任務這一事實使它具備與服務器上的Node相同的優點,但打字效果更好,更安全。

爲嵌入式系統編寫軟件也是如此。Dart可靠地處理多個併發輸入的能力是關鍵。

最後,Dart在客戶端上的成功將不可避免地引發更多在服務器上使用它的興趣-就像JavaScript和Node發生的狀況同樣。爲何要強迫人們使用兩種不一樣的語言來構建客戶端服務器軟件?

結論

這對於 Dart 來講是一個激動人心的時刻。使用 Dart 的人喜歡它,而 Dart 2 中的新特性使其成爲你工具庫中更有價值的補充。若是您沒有使用Dart,但願本文爲您提供有關Dart的新功能或不一樣之處的有價值的信息,而且您能夠嘗試使用它和Flutter。

查看英文原文: https://hackernoon.com/why-flutter-uses-dart-dd635a054ebf

交流

老孟Flutter博客地址(近200個控件用法):laomengit.com

歡迎加入Flutter交流羣(微信:laomengit)、關注公衆號【老孟Flutter】:

相關文章
相關標籤/搜索