可擴展架構取捨

引言:「架構」是前端開發中一直以來都缺乏的。因爲近幾年Web應用日趨複雜,前端架構開始流行起來。成熟的工具使得開發人員能夠針對要解決的問題設計出可擴展的架構。
構建可擴展的軟件,能夠從不少角度來思考軟件架構。可是若是每一個角度都去考慮,根本不可能作出想要的軟件。這就是爲何須要從架構的角度對設計進行取捨:取咱們最須要的,舍次要的。
本文選自《大型JavaScript應用最佳實踐指南》。前端

肯定不可變內容

  在作出取捨以前有一點很重要:列出那些不能捨棄的需求——咱們的設計的哪些方面對實現可擴展是相當重要的、不能改變的。好比,被渲染頁面中的實體個數或者函數間接調用的最大深度就不能改變。雖然不可變的內容不會太多,可是它們確實存在。最好的辦法是縮小這些內容的做用範圍,減小它們的數量。若是有太多嚴格的設計原則不能被打破或改變以迎合需求,就不能更好地適應不斷變化的可擴展性影響因素。
  考慮到可擴展性影響因素的不可預測性,沒法改變的設計原則是否還有意義?答案是確定的,但只有在它們浮現出來,而且顯而易見時才成立。因此這可能不是前期的原則,雖然咱們常常要遵照至少一兩個前期原則。這些原則多是從早期代碼重構或後期軟件的成功中總結出來的。在任何狀況下,這些不可改變的內容必須明確下來,並和全部相關人員達成一致。性能優化

從開發的便捷性考慮性能

  性能上的瓶頸須要在一開始就被修復或避免。一些性能瓶頸是顯而易見的,會對用戶體驗形成明顯的影響,這些就須要當即修復。由於這些瓶頸意味着咱們的代碼因爲某些緣由沒法擴展,而且可能引出設計上更大的問題。
  其餘性能問題相對較小,一般是開發者爲了經過各類手段提升性能,對代碼進行基準測試時發現的。這些沒法很好地擴展,由於這些小的性能瓶頸沒法被用戶察覺,可是修復起來很是耗時。即便應用程序大小合理,又有很多開發人員,可是每一個開發人員都在修復這類小問題,就沒法繼續開發新的功能。
  一方面,這種細微的優化會引入對特殊狀況進行處理的代碼,而這類代碼對於其餘開發者來講就沒那麼容易理解了。另外一方面,若是不進行這種細微的優化,代碼就會相對簡潔,容易維護。在必要時,需捨棄性能優化來保證更好的代碼質量。這樣才能加強咱們在其餘方面提升可擴展性的能力。微信

性能的可配置性

  若是有幾乎每一個方面均可配置的通用組件天然是極好的。然而,設計通用組件的代價須要犧牲性能。這在一開始只有少許組件時是沒法察覺的,可是當軟件功能、組件數量、組件配置項開始增長時,問題就顯現出來了。隨着每一個組件尺寸(複雜度、可配置項的數量等)的增加,組件的性能就會呈指數遞減,以下圖所示。
【圖1】
  只要性能問題沒有影響到用戶,就能夠保留配置選項。不過須要注意的是,可能會在消除某個性能瓶頸時不得不刪除某些可配置項,不過可配置項不太可能成爲性能瓶頸的主要來源。在不斷擴大和增長功能的過程當中還容易過於投入,回顧起來你會發現,在設計時建立的自認爲有用的可配置項,最終並無什麼用,反而加大了開銷。因此,當配置項沒有帶來確鑿的好處時,爲了保證性能,應該果斷捨棄。架構

從可替換性考慮性能

  一個與可配置性相關的問題是可替換性。如今咱們的用戶界面運行良好,可是隨着用戶數量和功能的增長,咱們發現某些組件沒法輕易地被另外一個組件替換。這多是一個軟件成長問題:想設計一個新的組件用來替換已有組件,或者可能須要在運行時替換某些組件。
  替換組件的能力基本上由組件通訊模型來決定。若是新的組件能夠像已有組件那樣發送/接收消息/事件,那麼替換起來就至關簡單了。可是並非軟件的全部方面都須要能夠替換,爲了保障性能,可能根本沒有可替換的組件。
  但當擴展應用時,可能須要考慮將大組件重構爲較小的可替換組件。可是這樣作會引入新的間接層,從而影響性能。不過犧牲一點點性能換來可替換性,能夠幫助咱們在其餘方面得到架構的可擴展性。框架

可尋址性的開發便捷性

  爲應用程序中的資源分配可尋址的URI 必然會增長功能實現的難度。真的須要爲應用暴露的每一個資源分配URI 嗎?也許不須要。從保持一致的角度看,爲每一個資源分配URI是合理的。可是若是針對某些資源,沒有路由以及統1、易於遵循的URI 生成方案,那麼更傾向於不爲這種資源分配URI。
  爲應用中的每一個資源分配URI 帶來的負擔是值得的,由於不支持可尋址資源更糟糕。URI 讓咱們的應用和用戶熟悉的其餘頁面表現一致。也許URI 的生成和路由在應用中是不可改變的、不可捨棄的,因此幾乎老是犧牲開發的便捷性來換取可尋址性。相較於URI,開發的便捷性能夠隨着軟件的成熟更深刻地解決。函數

性能的可維護性

  功能開發的難易程度最終取決於開發團隊和可擴展性的影響因素。例如,可能出於預算的壓力不得不招聘初級開發人員。這樣是否能適應後期要求,則取決於代碼。當須要考慮代碼性能時,極可能會引入一些對於缺少經驗的開發者難以理解的代碼。很顯然,這會阻礙新功能的開發。若是新功能開發難度比較大,那就會花費更長的時間,這顯然不能適應用戶的需求變化。
  開發人員並非總須要費力理解這些用來解決特定領域性能瓶頸的晦澀代碼。固然能夠經過編寫高質量、易於理解的代碼,甚至編寫文檔來緩解這個問題。但這一切都是有代價的,隨着團隊的壯大,須要短時間內完成對開發者的培訓、指導,這些都是在生產效率方面須要付出的代價。
  在關鍵代碼上常常是優先考慮性能而不是開發的便捷性。不能老是逃避代碼性能帶來的代碼醜陋,可是若是這些醜陋的代碼能很好的被隱藏,就能夠獲得更易理解和自解釋的代碼。好比,底層JavaScript 庫性能良好,API 緊湊易用,可是若是你看一下底層的源碼,就會發現並非那麼優美。這就是咱們的收穫——讓別人維護出於性能緣由而看起來醜陋的代碼。
【圖2】工具

減小功能以提升可維護性

  當全部其餘手段都失敗時,須要退後一步,全面審視應用中的全部功能。架構是否可以支持全部的這些功能?把投入了大量時間來開發的架構廢棄掉是毫無道理的,但也確實會發生。大多數時候,會被要求實現一組頗具挑戰的與咱們結構相悖的功能。
  這種狀況發生時,其實是在打亂現有的穩定功能,或者在應用中加入一些低質量的東西。兩種狀況皆無益處,但值得投入時間,花費精力,與投資人溝通以決定哪些必須被刪除,儘管這個過程並不愉快。
  若是已經作出折中的選擇而且花時間理清了咱們的架構,那麼應該有一個合理的理由來解釋爲何咱們的軟件不能支持上百個功能。
【圖3】性能

利用框架

  框架的存在是爲了經過採用一套緊密聚合的模式,幫助咱們實現架構。框架具備極大的多樣性,選擇哪一個框架是由我的偏好以及與設計的契合度來決定的。例如,一個JavaScript應用框架能夠實現更多創造性,而另外一個框架擁有更多功能,但其中大部分功能是咱們不須要的。
  JavaScript 應用框架有不一樣的大小和成熟度。有些內置了不少套件,有些則傾向於機制而非政策。沒有一個框架是專爲咱們的應用設計的,對於每一個框架所聲稱的功能要持有存疑態度。框架標榜的功能只適用於簡單的通常狀況,而在咱們架構中的應用則徹底是另一回事。
  儘管如此,固然能夠用一個本身喜歡的框架做爲設計過程的輸入。若是咱們真的喜歡這個工具,團隊也有使用經驗,可讓它來影響決策者。只要咱們明白,框架不會自動地響應擴展影響因素,由於這個部分是由咱們來負責的。
  本文選自《大型JavaScript應用最佳實踐指南》,點此連接可在博文視點官網查看此書。
                     圖片描述
  想及時得到更多精彩文章,可在微信中搜索「博文視點」或者掃描下方二維碼並關注。
                       圖片描述測試

相關文章
相關標籤/搜索