iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 28
7
Modern Web

重新認識 JavaScript系列 第 28

重新認識 JavaScript: Day 28 從 Page 到 Application,談談前端框架與工具庫 (中)

本系列文章已重新編修,並在加入部分 ES6 新篇章後集結成書,有興趣的朋友可至天瓏書局選購,感謝大家支持。

購書連結 https://www.tenlong.com.tw/products/9789864344130

讓我們再次重新認識 JavaScript!


現在人們談論到 SPA (Single Page Application, 單頁式應用) 可能都會認為是在 2007 年 iPhone 推出之後,Mobile Web 日漸增長之後才開始蓬勃發展的。

事實上,SPA 的崛起可能比起你我的想像還要早得許多。

從 Page 到 Application

最早期的網頁幾乎都是以靜態網頁為主,所有資料直接從 Server 端輸出,幾乎不需要做運算,就是單純的 HTML。就算有後端語言,最多也就是負責表單的處理。 後來過了幾年,有了「動態網頁程式」的語言 (如 PHP、ASP 等) 開始由後端程式語言負責處理頁面邏輯,加上資料庫系統的成熟,使得原本無法紀錄狀態的網頁,可以利用資料庫來記錄狀態及資料。 人們這才開始意會到,原來網頁是可以用來開發「應用程式」的。

上面講的是後端程式的部分,同一時間另一個戰場在使用者端。

除了日漸成熟的後端技術外,在當時網頁標準還沒有底定的同時,各家廠商為了搶佔市場,也紛紛推出各種增強或擴充瀏覽器的應用程式,像是早期的 Java Applet、微軟主打的 ActiveX,都可以算是後來 Rich Internet Application (RIA) 的始源。

時間來到 2004 年。 幾乎所有在介紹 Ajax 的文章都會提到這個產品。
沒錯,就是由 Google 所推出的 Gmail。

https://timedotcom.files.wordpress.com/2014/03/image37.jpg?quality=100

其實 Ajax 光看名字就知道,「Asynchorous Javascript And XML」在當時並不是什麼特別新的技術,而是把好幾項本來就有的東西組合起來,但這項技術確實為後來 SPA 的發展奠定重要基礎。

除了 Ajax 以外,當時想要在網頁上製作應用程式還有另外一派,那就是由 Macromedia 所開發的 Flash (後來被 Adobe 買下) 以及微軟的 Sliverlight。

然而,不管是透過外掛在瀏覽器的 RIA 應用,或者是只採用 CSS、HTML、Javascript 來控制 HTML DOM 的 Dynamic HTML (Ajax) ,我們都可以從中發現共通點,網頁的應用實際上已經開始漸漸由「後端」轉移到「前端」(更精準一點應該稱 Client 端) 了。

從多頁到單頁

https://i-msdn.sec.s-msft.com/dynimg/IC690875.png
圖片來源:ASP.NET - Single-Page Applications: Build Modern, Responsive Web Apps with ASP.NET

傳統多頁式的網站與單頁式網站最大的差別就是省下了換頁的成本,不需要重新載入網頁,操作的回饋更即時。 取而代之的是透過 Ajax 取得需要被更新的資料,然後透過 JavaScript 將網頁的內容替換。 但同時也遇到了新的挑戰,首先面臨的問題就是使用者的習慣、狀態的管理,以及 SEO 的考量。

先前提過,長久以來使用者「被教育」操作網頁建置的系統時,要回到前一個步驟,一定會去按「上一頁」,但網頁是用 Ajax 更新的資料,哪裡來的上一頁與下一頁可以給使用者切換。

當然早期前輩們也想過這個問題,想要動 URL 又不能換頁,只好改 URL Hash。

window.location.hash = "#main_page";

window.location.hash = "#content_page";

window.location.hash = "#list_page";

然後搭配 hashchange 事件,去監聽 URL Hash 的狀態來決定目前顯示的內容。

這種方式算是最早的前端路由解決方案。

還好後來 HTML5 之後,新的規範提供了 History API,可以透過 pushState()replaceState() 的方式更新 URL,以及 history.go();history.back(); 來切換頁面的上下頁路徑,同時也提供了 state 物件來讓開發者存取每一頁的狀態。

而這種搭配 pushState 的方式,甚至有人把它與 Ajax 合併,合稱為「Pjax」。

另一個需要面臨的問題是 SEO,雖然 Google 曾宣稱可以看懂 Javascript 渲染的結果,但是...

https://ithelp.ithome.com.tw/upload/images/20171231/20065504zFj3Cjus1u.png

...有些事情還是聽聽就好。 況且搜尋引擎也不止 Google 一家。

在處理這類問題最大的挑戰是,前後端需要各自實作路由來處理 url 變化,前後端分別維護各自的 view 及 routing,且要能互相對應,換言之就是後端要處理 API 的資料,同時也要負責在使用者 landing 的時候提供畫面的渲染。 而前端負責的是,當後端將第一頁畫面渲染之後,就得接手使用者的後續操作。

這樣的解決方式就算是機器人來爬也絕對沒有問題,但等於開發人員需要做兩份工,專案複雜度也是倍數上升。

是不是有必要做到這樣其實見仁見智,規劃專案的時候,有時候除了「潮」也要考慮到開發的成本與未來的維護性。

從桌面應用到行動裝置

另一個使 SPA 快速發展的原因,則是我們一開始提到的行動裝置的快速成長。
在現在這個幾乎人手一機的時代,有些人家裡可能沒有電腦,但幾乎不會沒有手機或是平板。

在過去頻寬不像現在有 4G 這麼快速的年代,比起傳統的換頁式網站,行動版的網頁採用 Ajax 取得 JSON 來更新資料除了節省頻寬的好處外,畫面的更新回饋也更加即時。

但需要注意的是,SPA 並不是單純把一堆頁面全部往同一頁塞就好。

大約六、七年前,有個前端框架叫 PhoneGap (現更名為 Cordova),它最大的賣點就是讓開發人員得以使用 HTML5、JavaScript、CSS 等 web 標準技術來開發原生程式,其實說穿了就是將 Web 包裝成 App,透過 SDK 提供的 Bridge 可以使網頁應用去呼叫裝置的功能。

但由於這樣方式開發出來的 App 通常都還有「網頁」的思維,也常聽到開發者送審時被 Apple 打槍的結果。

所以說除了技術面以外,開發 SPA 的另一個重點則是開發者的思維,否則技術再先進,做出來的東西依然是網頁,那個樣子怎麼看都不會是應用程式。

其實現代主流的前端框架,早一點的像 Backbone、AngularJS,到後來的 React、Vue 也有提供 SPA 相關的解決方案。 然而了解哪些場景該用傳統後端,哪些該用 SPA 來開發,則是 Web 開發人員的未來需要面對的另一個課題。


MV* 框架的出現與開發思維的轉變

網頁開發的思維從早期的「義大利麵式程式碼」(Spaghetti code) 把所有的東西通通往 HTML 頁面塞,到了後來有人提倡「關注點分離」,將 HTML、CSS 及 JavaScript 拆開來,這是表現層級上的關注點分離。

https://ithelp.ithome.com.tw/upload/images/20171231/200655043WR8znahnn.png

然而,當專案的架構越來越大,人們開始把「關注點」從表現層移到了架構層面。 於是,分成了「資料層」、「表現層」以及「邏輯層」,也就是所謂的 MVC 概念。

https://ithelp.ithome.com.tw/upload/images/20171231/20065504gPGQJLFA10.png

當瀏覽器開啟 View 的時候,View 會向 Controller 提出請求。 Controller 處理完商業邏輯的部分之後,要求 Model 端改變狀態,然後 Model 再將資料反映到 View 上。

以 Backbone 來說,使用者可以透過 DOM 事件對 View 發送指令,再由 View 要求 Model 改變狀態。 但同時使用者也可以透過操作 URL 來對 Controller 做操作,再由 Controller 去改變 View。

這個時候你會發現前端 MVC 與後端 MVC 有著一個很大的差異: 前端的 MVC 著重在事件流程,而後端的重點在於資料流。

後端 MVC 的 View 就相當於是前端的全部了:

https://ithelp.ithome.com.tw/upload/images/20171231/200655049gO5tuxY1m.jpg
來源:http://slides.com/evenchange4/2014-ntuim-prepconf#/2/3

當前後端分離後,後端幾乎不需要去處理 View 的部分。相對地,後端的 V 變成前端的 M,那些原本放在後端處理畫面、邏輯的部分,其實很大程度地往前端移動。

於是前端框架慢慢發展成 MVVM 模式。

像比較早期的 Ember、Angular 採用資料的雙向綁定作法,當 View 操作 (DOM event) 變動,透過 ViewModel 去操作 Model (JavaScript Object),反過來也是。

https://ithelp.ithome.com.tw/upload/images/20171231/20065504s77Ol1vqrS.png

後來的 React、Vue 也都延續採用 Single Source of Truth (SSOT) 的準則,使得資料流更容易被追蹤,架構也更好維護。

一般來說,後端的 Controller 是指 URL 與 Http Method 的部分,而前端可以透過 URL 操作 (hashtag / pushState) 以及 DOM Event 去對 View 做操作。 所以通常前端框架不會直接稱自己是 MVC 框架,而是被稱作 MV* (MVC/MVP/MVVM...) 的框架。


今天講了滿多與 SPA 相關的東西,也是藉此與各位聊聊網頁應用的架構,是如何從傳統的後端為主逐漸發展至 SPA (但目前也未必是主流),以及它所延伸出的問題。

那麼下回我們就延伸這個話題,繼續與大家聊聊,在 MV* 框架出現後, Web Component 為什麼漸漸變成主流,以及前端開發生態圈的發展。


上一篇
重新認識 JavaScript: Day 27 從 Page 到 Application,談談前端框架與工具庫 (上)
下一篇
重新認識 JavaScript: Day 29 從 Page 到 Application,談談前端框架與工具庫 (下)
系列文
重新認識 JavaScript37

1 則留言

0
wuyuxin321000
iT邦新手 5 級 ‧ 2020-08-19 14:20:23

前端架构大家都挂在嘴边,vue、react大家都在用,但是好像又都不懂。
kuro大大有机会开一个前端架构的主题嘛?

我要留言

立即登入留言