客戶端JavaScript的5個弊端
譯注:原來的標題是:“我們?yōu)樯恫挥肁ngularJS:…”,后來作者覺得不妥就改掉了,因為AngularJS是通常適用于單頁面程序框架(SPA) 很多人理解為對AngularJS的抨擊,但這并不是他的本意。
幾個月前,當我們打開Sourcegraph網(wǎng)站的時候,它是一個富AngularJS應用,服務器只要把原始HTML和JSON endpoints返回,剩下的就交給Angular來搞定了。我們就這樣懵懵懂懂地做出了最初版本的Sourcegraph。
但是單頁(single-page) JavaScript框架并不適用于每一個站點。Sourcegraph就是一個內(nèi)容為主的站點,我們漸漸發(fā)現(xiàn)這個富js應用的開發(fā)還是弊大于利;下面是我們在探知這條路上遇到的溝溝坎坎,希望對有雷同遭遇的開發(fā)人員一些幫助。
下周,我們來討論更多地關于我們是如何從AngularJS遷移server-side GO templates
客戶端JS框架的5個弊端
我們早就知道這會有很多的困難,但是不知道到底有多難
1. 搜索排名和Twitter/Facebook預覽
搜索引擎爬蟲和社交網(wǎng)站的預覽抓取器不能加載純Javascript站點,而如果提供替換版本又慢又復雜
有兩種方法可以允許爬蟲閱讀你得站點。你可以在服務器端運行一個瀏覽器實例用以執(zhí)行你的應用里的Javascript,然后返回HTML結果(PlantomJS或者WebLoop)。 或者你可以為你的站點專門建立一個HTML版本為爬蟲服務
***個方法需要你為每一次頁面加載建立一個headless瀏覽器(或者tab),比起直接產(chǎn)出HTML,這樣會花費很多的時間和系統(tǒng)資源?;谀阌玫目蚣埽瑫ㄙM很多的工作來決定什么時候已經(jīng)準備好的頁面將被渲染。 你可以緩存頁面,但是如果頁面經(jīng)常改變,不但優(yōu)化甚微而且會增大復雜度。
這樣做還會降低你的頁面加載速度好幾秒,對搜索引擎排名也不利。(PlantomJS需要Xvfb和WebKit)
第二個方法(做一個服務器端站點)對簡單地站點有效,但是如果頁面很多,那用這個方法就形同噩夢。
如果Google認為你的服務器版本站點跟你的主站版本有很大的不同,那他就會狠狠的懲罰你,到時候你連怎么死的都不知道
2. 不可靠的統(tǒng)計和監(jiān)控
很多分析工具需要易于出錯,人工集成來使用HTML5 history API(pushState)用于導航。因為他們很難自動檢測到你的應用使用pushState導航到了新的頁面。即使可以做到,他們?nèi)匀恍枰却銘美锏男盘杹硎占马撁娴男畔?/p>
如何解決這個問題呢?取決于你的客戶端用什么導航和你想集成什么分析工具。用Google分析+Backbone.js?嘗試一下backbone.analytics。用Heap(順便說一下,太酷了)和UI-Router?設置你自己的$stateChangeSuccess并調(diào)用heap.track
還沒完事呢!你想追蹤起始頁面加載?也許你在雙向跟蹤他?你會跟蹤失敗的頁面記載嗎?如果你使用replaceState代替pushState呢?如果你錯誤的配置了分析掛鉤或者屬于檢查導致依賴升級搞壞了事情。當你發(fā)現(xiàn)的售后,很難去恢復你錯過的分析數(shù)據(jù)(或者消除重復數(shù)據(jù))
3. 又慢又復雜的構建工具
前-后端JavaScript構建工具,比如Grunt,需要復雜的配置而且很慢。還好我們有像ng-boilerplate這樣的project來幫我們做配置,但是如果你想添加一個自定義的步驟還是逃不出又慢有復雜的怪圈(我為什么說Grunt復雜,看看這個配置文件就知道了)
一旦你配置好了你的應用,你仍然要忍受漫長的JavaScript構建時間。你可以把dev和production構建通道分開來提高開發(fā)速度,但是始終免不了走這么一遭,用AngularJS尤其如此,他需要在丑陋的代碼前使用ngmin(如果你用了這個功能)。其實,Sourcegraph因為這些丑陋的JavaScript表現(xiàn)代碼幾度被毀
還好,Gulp已經(jīng)有了極大的提高
4. 慢,不可靠的測試
測試JavaScript-only的站點需要使用基于瀏覽器的測試框架,比如Selenium,PhantomJS,或者WebLoop。安裝這些(除了PhantomJS)通常意味著安裝WebKit和Java依賴,配置Xvfb(機關新的PhantomJS移除了這些先決條件),或者運行一個本地的VNC客戶端和服務器來測試。***,你還需要在持續(xù)集成的服務器上設定所有東東
相反,測試服務器端產(chǎn)生的頁面通常只需要類庫來或者URLs并解析HTML,安裝和配置起來簡單許多
一旦你開始寫瀏覽器測試,你必須處理異步加載。你不能在頁面還沒有加載的時候就測試頁面上的元素,但是如果在一個特定時間端里沒有加載,你的測試就會失敗。瀏覽器測試類庫提供了很好地功能來處理這種情況,他們只能在負載的頁面里使用這些功能
如果你想聯(lián)合重量級瀏覽器來進行(Selenium,加上Firefox或者Webkit)很復雜的測試(因為瀏覽器的異步特質(zhì))?你的測試需要很多配置,很長的時間來執(zhí)行,而且很不可靠
5. 慢,可以緩解,但沒有解決
在富JavaScript應用中,頁面轉化幾乎是瞬間發(fā)生,然后所有的特定元素異步加載。在server-side應用中,完全相反:頁面在服務器端加載完成前不會發(fā)送到客戶端
聽起來似乎是client-side應用勝利了,但是也許會是個坑也不一定
當用戶點擊一個鏈接,client-side應用會立刻加載頁面并呈現(xiàn)。如果用戶用sidebar導航到一個需要5秒鐘才可以加載的頁面。***次感覺很快,但是如果一個用戶需要的信息在sidebar里,對用戶來說就感覺很難受。即使你需要的特定內(nèi)容立即呈現(xiàn),你仍需要忍受加載指示器和頁面填充后的抖動
我們來考慮如果開發(fā)人員想在那個頁面添加新功能。是很難讓她的功能必須快速加載的-因為都是異步的,所以誰會在意頁面底部過了幾秒才加載呢?如此反復幾次,整個站點讓人感覺滯后很抖動
在server-side 應用中,如果一個API調(diào)用很慢,整個頁面就會停滯直到徹底完成。這個不容忽視的server-side慢節(jié)奏很容易被測量并會公平地影響每一個人。但是在client-side應用中很容易被忽略
你可以說,一個好的開發(fā)團隊應該避免這些錯誤,并且client-side JS 框架不是罪魁禍首。是的,client-side JS框架提高了速度。這一點改變鼓勵了任何開發(fā)團隊
下一步?
上面說得都不是大問題。我們已經(jīng)做了很多來減輕上述情況。
總而言之,上述種種以為這client-side JS 框架加大了我們開發(fā)的負擔。
而且要記住,每一個站點都是不同的。Sourcegraph是一個內(nèi)容站點,他得頁面在加載后不會有太多的變化(相較于富JS應用),我們依然愛著浙西技術,但是他們不一定是構建主站點的正確工具。
原文鏈接: Sourcegraph 翻譯: 伯樂在線 - 蔡蔡