怎樣合理地使用 Ajax ?過度使用 Ajax 會有哪些弊端?

這些天看到一個同學很喜歡用 Ajax,做頁面的時候總是追求「不刷新」,導致 JS 代碼看得眼花繚亂的。所以想問問怎樣合理的使用 Ajax,過度使用是否會有什麼弊端。


時代變了。在 Single Page WebApp 滿地跑的年代,原最高票提到的經驗已經不適用。

1. 頁面上首次顯示的內容盡量不要用 Ajax,顯示更多(或換頁)的時候再用

該方案其實是對面向內容的傳統 Web 頁面的一種優化。對於強調沉浸體驗的 WebApp 而言,所有數據都可以使用相同的方式獲取並且渲染到頁面。

比如說 Google Docs http://docs.google.com 和 Dropbox Paper http://paper.dropbox.com 這樣的 WebApp,不需要也不應該去強求數據跟隨 HTML 一起載入。

2. 切換頁面的時候不用要 Ajax

對於現代 Web 頁面而言,切換頁面時是可以保持 URL 的語義化的(無論使用hashHistory 還是 browserHistory)。

即使是面向內容閱讀的網站,比如 http://Medium.com,無論是翻頁還是導航切換,都使用 Ajax 去非同步載入。

---

題主的問題可以重新解讀為:

  1. 什麼時候應該用 Ajax

  2. 如何應對使用 Ajax 技術導致的程序複雜性

什麼時候應該用 Ajax

先看看 Ajax 和傳統 Server Centri Web 架構的區別。

Ajax本質上是一種瀏覽器端技術,從圖中可以看出,傳統 Server Centri Web 架構的最大區別是將大量業務邏輯從伺服器端移到瀏覽器。

好處是當數據發生變更時,只需要重新渲染相關的 HTML,而不需要載入整個頁面。壞處是使用大量 Ajax 的項目與其說是B/S架構,不如說是C/S架構,自然也具備C/S架構的特點,在瀏覽器環境下,某些特點會成為缺陷。

比如說 Ajax 要求業務邏輯必須先於數據載入,瀏覽器必須載入完相關 js 文件後才能開始載入數據,因此第一次頁面 ready 的時間會晚於傳統 Web 頁面。不過這樣的問題也有很多解決方案,例如 Application Cache 可以將文件保存在瀏覽器里,避免反覆載入相同的腳本和資源文件。

所以結論是:是否應該使用 Ajax 取決於業務流程和技術棧

那怎麼判定一個業務流程是否適合 Ajax 呢,我舉個例子 。

假如你需要在微信里接入一個賣水果的活動,流程可以如下設計:

如何應對使用 Ajax 技術導致的程序複雜性

澄清一點:Ajax 本身並沒有加重程序複雜性。

程序變得複雜的原因是:由於 Ajax 要求業務邏輯被移動到瀏覽器端,因此瀏覽器端為了應對更多業務邏輯變得複雜。

既然是問題是程序複雜性,那麼解決方案當然來自軟體工程:

1. 重瀏覽器端的 WebApp 應用,和客戶端開發一樣,善用 MVC/MVV (https://zh.wikipedia.org/wiki/MVC)這樣的軟體設計模式,對複雜度的簡化,使程序結構更加直觀。

現代 Web Frameworks 都在執行這一理念。如果需要做一個 WebApp,從 React、Vue.js、Angular.js 等框架入手都是最好的選擇。

2. 使用 Ajax 優化傳統 Server Centri Web 的體驗

無非是結構化的程序設計方式,相信所有 CS 出身的開發者都能遊刃有餘。

再有就是合理使用第三方庫,例如使用 jQuery、underscore.js 這樣的工具性第三方庫可以降低對 DOM 操作的難度,並應對瀏覽器兼容性問題。


總結下自己的前端開發經驗吧:

  1. 頁面上首次顯示的內容盡量不要用 Ajax,顯示更多(或換頁)的時候再用

    比如說知乎首頁的第一頁 Timeline 上的問題是直接從伺服器讀取的,並寫入在當前的頁面源代碼裡面的,而隨後 「顯示更多」 得到的內容才是用 Ajax 讀取。
  2. 切換頁面的時候不用要 Ajax

    不要因為網頁的 header 或者 side 部分沒有變化而用 Ajax。

    因為這是不同的頁面,換句話說,是有完全不同的內容或者完全不同的頁面邏輯。他們的 URL 就應該不同。

    補充:使用了 HTML5 History API 例外,但是同時要考慮兼容早期版本的瀏覽器。
  3. 提交、修改、刪除的部分一般用 Ajax

    看看知乎 「添加答案」、「刪除答案」、「修改答案」,都是 Ajax。

    但是知乎的 「添加問題」 的提交並沒有採用 Ajax,因為添加問題是個多入口的操作(各個頁面都可以有),所以添加成功後,需要統一重定向到首頁。而其他的諸如 「添加答案」 只有在當前問題頁面才有,所以無需刷新,只需修改 DOM。
  4. 消息提醒的部分一般用 Ajax

    因為很有可能會用到 Comet 長連接來保證消息的實時推送,那麼除了 WebSocket 之外最好的選擇只有 Ajax。
  5. 編碼的時候模塊分工明確

    比如使用了 jQuery,那麼所有的 Ajax 請求都最好做一層包裝,然後再轉移給 $.post 或者 $.ajax 之類的方法。


代碼亂是設計模式的問題,跟ajax無關。是否使用ajax看需求,如果希望內容被爬蟲爬到,或某個頁面的內容能被用戶方便的保存那就需要單獨的url。舉個栗子,如果淘寶全部操作使用ajax實現,商品沒有自己的url,用戶就很難保存某個商品的頁面,這顯然是不科學的。但在打開了某個商品的頁面後,商品具體信息使用ajax載入就沒什麼問題了。企業內部辦公用的web應用全程ajax問題就不大,還會有更好的體驗。


顯然web worker+websocket是更好的選擇,至少可以節約伺服器端負載


除了 SEO 的考慮,暫時沒有想到用 ajax 有什麼弊端。


1. 希望首屏立即出來的內容,不要用ajax。

2. SEO相關的內容,不要用ajax。

3. 首屏內容,但是不需要馬上出來的,可以用可以不用。

4. 剩下的都用ajax,注意合併請求。


有一本書叫做Single web application.

看看先?


我不知道怎麼算合理使用,因為我不是一個前端工程師。但是我知道,過渡使用,尤其是過度使用還不能良好的處理內存的利用的話,後果就是造成瀏覽器負擔加重甚至卡死。甚至再一些比較老的操作系統和機器裡面這樣的卡死會造成整機的假死狀態。


推薦閱讀:

XML在數據傳輸哪些方面會比JSON有優勢,在哪些領域更加適合?
如何解决 Ajax 跨域请求不到的问题?
訪問localhost和127.0.0.1是否完全一樣?

TAG:Web開發 | 前端開發 | JavaScript | Ajax |