關於大型網站技術演進的思考(十六)--網站靜態化處理—前後端分離—下(8)

夏天的森林發表於2015-03-07

  我第一次聽說nodejs技術大概是在2009年年末,不過我真正認真在網路上進一步瞭解nodejs還是在2010年年中,當時對nodejs的認識和我現在對nodejs的認識有著天壤的區別,開始想了解nodejs我只是為了感慨谷歌公司開發的V8引擎居然如此強大,它不僅僅可以作為chrome瀏覽器的javascript核心執行平臺,居然還能為服務端使用javascript語言作為平臺,通過對nodejs的瞭解讓我認識到chrome瀏覽器是如此的優秀,但是如此相對的是我並不認為javascript作為服務端語言真的會有市場。

  為什麼我當時會認為javascript作為服務端語言的前景堪憂呢?我當時有如下的思考,這些思考放到時下nodejs已經非常火爆的背景下,我相信對很多朋友任然有參考意義,下面是我當時的思考,具體如下:

  質疑nodejs思考一:2010年之前我還不是敢自稱自己是一名專業web前端的工程師,因此對於javascript的認識和掌握程度也不能和現在相比,但是對於javascript的難學,難深入卻是有著切膚之痛,因此我想javascript作為服務端語言就是讓會其他服務端語言的工程師更加深入的學習常被服務端工程師詬病的javascript,這麼做的結果無異於逼迫服務端工程師轉向成web前端工程師嘛,這個想想就讓人覺得不現實。

  質疑nodejs思考二:我對web應用開發的技術選型認識比較膚淺。技術的選型是個很寬泛的問題,回到我對nodejs的質疑思考主要是體現在web應用服務端語言選擇上,在中國用作web服務端開發的語言非常多,但是主流的無非就是java、php、C#以及C語言系列,當然web服務端技術發展到現在Python、ruby也是有一定市場,作為一名具體幹活的軟體工程師對於專案選擇何種技術是沒啥發言權的,因此我常常覺得技術選型就是專案經理或者是技術經理以及架構師的問題,而大多時候我們去詢問為什麼用這個服務端語言得到的答案都是非技術性的回答,例如:公司主要是使用php啊,java比較流行人好找啊,C#開發快啊能很快的完成工作,很少有人會這麼告訴你我們的專案是個什麼樣的專案,這個專案使用A語言比使用其他的B語言、X語言有何種好處和優勢,其實中國很多軟體企業做專案在技術選型這塊都很粗,說的難聽點其實就是很多能控制專案的人技術水平很難被恭維,當然大部分專案其實使用什麼技術實現並不是太重要的問題,但是這個到了技術架構異常複雜的大型網站技術選型問題就顯得尤為重要,這個認識主要是來自於我閱讀《淘寶技術這十年》所感受到的,淘寶網站的技術選型隨著業務的發展變化的如此之大,顛覆性如此之高,這個在我待過的很多專案組都是難以令人想象的。

  Web應用發展這麼多年,那些佔據了天時、地利和人和的現有技術基本都是處於一個壟斷的地位,新的同型別語言想突破重圍必然有著自己獨有的技術優勢,這就好比在中國做網際網路如果有家新型網際網路公司可以突破BAT的圍追堵截,那麼這家公司一定是有著自己得天獨厚的優勢,所以nodejs一定是獲得一種得天獨厚的優勢,那麼nodejs優勢在哪裡了?不過在講述nodejs的優勢之前我們先來講講上篇文章裡遺留下來的問題。

  其實上篇裡我講到前端MVC,文章裡只是著重講到了V層即檢視層和M層即模型層的問題,而唯獨沒有專門講解C層即控制層的問題。在前後端分離文章第一篇裡,我談到如果把MVC框架裡的C層以作為連線web前端和web服務端的角度來理解,C層主要承擔了三個方面的工作,它們分別是:路由、報文格式轉化和頁面渲染的工作。前端MVC在處理報文格式轉化和頁面渲染這兩個方面還是比較容易做到,但是在做路由這塊存在一定問題,前端MVC框架對於獲取服務端資料這塊以及非同步請求處理方面其實和傳統MVC框架的處理的手段本質上是類似,只是實現載體有所不同而已,但是控制層還有一個路由功能,其中用於頁面切換的路由存在一定的問題,不過這個切換也要限定一下範圍,頁面通過ajax技術讓頁面部分重新整理,假如這種部分重新整理讓頁面展示效果發生很大變化,對於使用者而言也是頁面發生了切換,但是這種切換是不會讓位址列的url產生任何改變,這就是問題的根本所在了,我在上篇裡已經討論過這些問題,通過這些問題我們發現如果頁面轉化時候位址列的地址隨之也發生改變是會給使用者體驗、網站的友好度以及SEO優化帶來好處的,如是乎我提供了一種手段,那就是使用錨連結來幫助我們實現url的變化,因為錨連結只是作用於瀏覽器,因此這種手段是對前端MVC的C層實現頁面路由功能的一種很好的支援,但是因為這種方式需要在javascript裡完成,那麼對於SEO優化就產生了問題,最後我提出了頁面切換我們最好使用同步請求的方式。

  這個時候問題來了,如果要使用同步請求,那麼這個同步操作自然是要讓服務端來控制,這麼做的結果就是讓服務端再去回收部分控制層的功能,這樣下來一個使用前端MVC架構的網站就有點不太純粹了,具體點就不是一個單頁面的網站,這裡我們的討論又迴歸到了單頁面的問題了,前文講前端MVC框架很多熱心網友對我的論述發表了有價值的評論,但是我發現我的想法有些朋友可能沒有真正理解(這也許是我的表述的問題吧),我前端MVC講述的一個思路是以批判前端MVC的角度進行的,我早些時候和一些網友探討過前端MVC的設計問題,有些朋友在沒有做具體web前端MVC架構前總是想實現純粹的前端MVC框架,延著這些朋友的思路我們就會把所有的C層和M層的東西都移到web前端,我常想如果真的這麼實現了,結果自然就是單頁面網站了,或者就是在前端引入了複雜的模型層設計,不過探討畢竟是探討真的實現時候很多朋友就會知道了難度所在了,所以說理想和現實是有差距的,這話又一次靈驗了。

  這種理想和現實的差距,其實就告訴我們一定有個地方出問題了,那麼問題在哪裡了?下面我將我對這個問題的思考,總結如下:

  問題思考一:讓前端承擔大部分MVC的工作,那麼前端本身的技術能力是否能達到所有的要求嗎?這個回答似乎是肯定的,例如單頁面的出現就代表了這種可能性,javascript也是擁有強大的物件導向的程式設計能力,因此再寫複雜的業務模型層也是沒問題,但是前端這麼做了以後其實並不能滿足所有人的需求,例如:SEO的要求,SEO很多技術都是以同步網站請求技術為根基,這個和前端MVC框架以ajax技術為根基產生了衝突,這就讓前端技術產生了侷限性。使用javascript物件導向技術來實現業務模型,這個也是有問題,javascript的物件導向的學習成本和精通難度超出了傳統的物件導向的語言例如像java這樣的語言,而且javascript要設計和寫出更加容易維護的程式碼是非常不容易的,這麼做不符合我在儲存系列裡講到的要用最簡單的方式實現的原則,這其實也是說明前端技術能力不足的問題。

  問題思考二:其實不管什麼形式的前後端分離方案它最根本的思想就是讓前後端進行解耦,讓不同技術語言體系下的人能做到工作的隔離,最後協同起來各自發揮出自己的最大價值,但是如果我們只是按前端,後端的角度來做分離,是不是有點粒度過粗,考慮是不是過於片面了?特別是這個片面的問題,web應用的問題並不是一個純技術問題,而是一個技術和業務結合的問題,因此任何應用於生產的技術方案都會受到業務的影響,例如上面當我們要考慮SEO的問題,考慮開發難度的問題,那麼純粹的前端MVC的框架就會顯示出自己的侷限性。前端技術無法改變瀏覽器位址列的url,這個從很多角度思考是個合理的設計,但是到了前端MVC裡對C層的設計而言則變成了一種技術手段的侷限性了。因為這種侷限性就讓我們不得不回到問題的原點狀態,例如頁面的同步請求,而同步請求最合理的控制地點就是服務端了。

  問題思考三:本思考是一個延生性的思考,我從事這麼多年的web開發,我其實一直困惑於web應用開發和MVC的關係,為什麼我們做web應用開發時候都要那麼強調和重視MVC設計思想呢?難道web應用開發的世界沒有MVC就不能活了嗎?回首下web應用發展的歷史,在web應用開發的忙慌年代,的確是看不到MVC的影子,那個時代的確很自由,自由到許多web應用混亂不堪,質量和健壯性差的不能再差了,這個時候一個英雄出現了那就是MVC,MVC代表了一種次序,一種基本的法則,這就好比人類社會建立的根本原則一樣,這些原則讓人類和野獸有了區別,人類也因為這些原則而成為萬物之靈長,相比之下MVC就是web開發世界裡的遊戲規則和行為準則,因此只有當我們從MVC角度思考web應用的建設,才會讓web應用更加的優秀,這也就是在講述前後端分離技術時候我都是以MVC思想作為準則進行思考的。思考回到具體的場景,MVC思想的運用就是讓我們把web應用開發裡可以歸為一類的場景聚集在一個範疇之下,不同範疇使用一種雙發都可以接受的統一準則進行溝通,這麼一來我們就把需要解決的問題簡單化了,各個獨立的範疇因為減少許多不必要的干擾,因此能讓它們發揮出更大的潛力,更重要的MVC還讓web應用伸縮性,健壯性,可維護性大大增強。例如在很多傳統web應用開發裡在控制層這塊前後端的矛盾就是屬於MVC規則使用不完善所致。

  單頁面的應用存在很多問題,因此需要同步請求的介入,這就導致了服務端再度回收了失去的控制層的功能,這麼做也無可厚非,但是我很擔心這個改進的引入會不會導致傳統MVC框架裡控制層的混亂問題,根據我的經驗,這種混亂的程度已經降低了很多很多,基本我們可以忽視原來C層的問題了。

  不過很多有追求的web前端工程師對於這種不純粹的前端MVC的異議還是很多的,大部分異議還是源自瀏覽器能力的侷限性,當服務端很多方面被弱化後,也許可以解決我們以前在前端被服務端束縛的很多問題,但是同時又產生了新的問題,這些新問題我總結如下:

  新問題一:在傳統的網站動靜劃分裡,我們常把瀏覽器端的技術html、css和javascript歸結於靜態技術的範疇,如果網站使用Web前端MVC那麼前端就會接過很多動態網站的功能,這個時候傳統的靜態技術就被人為的演變為動態技術。回顧網站的發展歷程,基本是從靜態到動態的轉變,這個結論用在時下其實已經有點不太對了,隨著網站越來越龐大越來越複雜,網站技術發展逐漸開始逆向進行了,網站從動態化向靜態化轉變的需求變得越來越強烈了,這也是時下前沿的前端技術正在解決的問題,例如本系列的主題網站靜態化技術就是順應這個發展趨勢而來的,所以前端MVC框架在這點上有點逆歷史潮流的問題了。

  新問題二:前端MVC讓web前端的技術難度和架構難度成指數級上升,而javascript語言天生有著自己設計的缺陷,這個缺陷在寫大規模複雜應用時候就顯得尤為突出,例如:javascript沒有模組化管理,javascript物件導向的實現難度,所以前端MVC的應用可能會變相的提升企業的技術成本和開發成本,當然很多新的技術手段能解決javascript固有的缺陷,對這些新技術有個更大的問題就是“你會嗎“,不會的話首先要解決會的問題,這也是個成本問題。

  新問題三:當前端真的越來越獨立於服務端後,這會導致服務端一些可以優化web前端的重要技術就很難實現了,例如網站靜態化系列裡講到了快取運用,CDN的運用就很難達到預期效果,或者根本沒法使用,因為這些技術的根基都是認為網站動態性是由服務端發生的,而客戶端霸佔了動態性,那麼這些技術的作用就被限制住了。

  由此我可以下個結論:如果前後端分離方案是以瀏覽器和伺服器角度來劃分並不是最好的前端分離方案,那麼前後端分離方案還有沒有新的解決思路了?這個真的有,那就是nodejs參入的前後端分離方案。

  其實前後端分離的驅動永遠都是前端強於服務端,而前後端分離的重要目的也是要給web前端創造一個更加乾淨的開發環境,那麼寫的程式碼是否是在瀏覽器上跑還是在服務端上跑這個並不是太重要,所以引入nodejs,就是讓服務端也能跑javascript程式碼並不會是讓人無法接受的事情,回到前後端分離方案裡以服務端驅動的前後端分離方案,我曾說過這個方案能獲得服務端開發人員更多的掌聲,我相信這個掌聲不會是服務端為前端的喝彩,而是服務端終於從web前端解脫出來了,這樣服務端運用更加高階的SOA技術就成為了可能,那麼我們把web前端的控制層使用nodejs替代,這麼一來我們既可以繼承所有傳統MVC框架的優點,同時也達到以前後端分離的根本的問題就是為web前端創造一個很乾淨的開發環境問題,那麼我們在前端MVC框架使用時候遇到的問題都會很好的被解決。

  Nodejs的運用讓動態網站的動態性再度停留在了服務端,那麼我前面講的那麼多網站靜態化技術就可以和前後端分離方案很好的融合了,因此本篇先不具體討論nodejs做前後端分離的實現手段了,在下篇講從網站靜態化角度重新審視前後端分離方案時候一起講解,這麼做會更加符合本系列的主題。

  現在我們可以解答為什麼nodejs技術可以突破傳統服務端技術的包圍,因為nodejs可以讓前後端達到更高程度的分離,從而讓前後端各自發揮自己的優勢,很有意思的是,雖然nodejs技術屬於服務端範疇,但是它卻是前端工程師驅動來普及的,這絕對是web前端逆襲啊。

  相關文件:

  關於大型網站技術演進的思考(一)--儲存的瓶頸(1)
  關於大型網站技術演進的思考(二)--儲存的瓶頸(2)
  關於大型網站技術演進的思考(三)--儲存的瓶頸(3)
  關於大型網站技術演進的思考(四)--儲存的瓶頸(4)
  關於大型網站技術演進的思考(五)--儲存的瓶頸(5)
  關於大型網站技術演進的思考(六)--儲存的瓶頸(6)
  關於大型網站技術演進的思考(七)--儲存的瓶頸(7)
  關於大型網站技術演進的思考(八)--儲存的瓶頸終篇(8)
  關於大型網站技術演進的思考(九)--網站靜態化處理--總述(1)
  關於大型網站技術演進的思考(十)--網站靜態化處理—動靜整合方案(2)
  關於大型網站技術演進的思考(十一)--網站靜態化處理—動靜分離策略(3)
  關於大型網站技術演進的思考(十二)--網站靜態化處理—快取(4)
  關於大型網站技術演進的思考(十三)--網站靜態化處理—CSI(5)
  關於大型網站技術演進的思考(十四)--網站靜態化處理—前後端分離—上(6)
  關於大型網站技術演進的思考(十五)--網站靜態化處理—前後端分離—中(7)
  關於大型網站技術演進的思考(十六)--網站靜態化處理—前後端分離—下(8)
  關於大型網站技術演進的思考(十七)--網站靜態化處理—滿足靜態化的前後端分離(9)
  關於大型網站技術演進的思考(十八)--網站靜態化處理—反向代理(10)
  關於大型網站技術演進的思考(十九)--網站靜態化處理—web前端優化—上(11)
  關於大型網站技術演進的思考(二十)--網站靜態化處理—web前端優化—中(12)
  關於大型網站技術演進的思考(二十一)--網站靜態化處理—web前端優化—下【終篇】(13)

相關文章