Loading AI tools
来自维基百科,自由的百科全书
單頁式應用程式(英語:single-page application,縮寫SPA)是一種網路應用程式或網站的模型,它透過動態重寫當前頁面來與使用者互動,而非傳統的從伺服器重新載入整個新頁面。這種方法避免了頁面之間切換打斷使用者體驗,使應用程式更像一個桌面應用程式。在單頁式應用程式中,所有必要的代碼(HTML、JavaScript和CSS)都透過單個頁面的載入而檢索[1],或者依需(通常是為回應使用者操作)動態載入適當的資源並添加到頁面。儘管可以用位置雜湊或HTML5歷史API來提供應用程式中單獨邏輯頁面的感知和導覽能力,但頁面在過程中的任何時間點都不會重新載入,也不會將控制轉移到其他頁面。[2]與單頁式應用程式的互動通常涉及到與網頁伺服器後端的動態通訊。
![]() | 此條目翻譯自其他語言維基百科,需要相關領域的編者協助校對翻譯。 |
此條目需要補充更多來源。 (2018年2月25日) |
儘管早在2003年就討論過這個概念,但單頁式應用程式(single-page application)一詞的起源並不明晰。[3]Stuart (stunix) Morris在2002年4月編寫的自主網站slashdotslash.com有著相同的目標和功能[4];同年稍晚,Lucas Birdeau、Kevin Hakman、Michael Peachey和Evan Yeh在美國專利8,136,109中描述了一個單頁式應用程式的實作概念。[5]
在網頁瀏覽器中可以使用JavaScript顯示使用者介面(UI)、執行應用程式邏輯,以及與Web伺服器通訊。成熟的開源程式庫支援構建一個單頁式應用程式,從而減少開發人員要編寫的JavaScript代碼量。
現今已有各種技術可以使網頁瀏覽器停留在單個頁面,並同時支援應用程式與伺服器通訊。
諸如AngularJS、Ember.js、Meteor.js、ExtJS和React等網頁瀏覽器端的JavaScript框架採納了單頁式應用程式(SPA)原則。
目前最常採用Ajax技術。主要從JavaScript使用XMLHttpRequest/ActiveX對象(已不建議使用),其他Ajax方法包括使用IFRAME或script HTML元素。jQuery等流行的程式庫可以為不同廠商的瀏覽器的Ajax行為標準化,進一步推廣了Ajax技術。
WebSocket是HTML5規範中的一個雙向有狀態即時客戶端與伺服器通訊技術,在效能和簡單性方面優於Ajax[11]。
伺服器傳送事件(SSE)是一種伺服器向瀏覽器客戶端發起資料傳輸的技術。一旦建立了初始連接,事件流將保持打開狀態,直到客戶端關閉。該技術透過傳統的HTTP傳送,並具有WebSockets缺乏的各種功能,例如自動重新連接、事件ID以及傳送任意事件的能力。[12]
可以使用瀏覽器外掛程式技術(如Silverlight、Flash或Java applet)實現對伺服器的非同步呼叫。此種方法在業界已經過時。
對伺服器的請求通常會帶來原始資料(如XML或JSON)或傳回新的HTML。在伺服器傳回HTML時,客戶端上的JavaScript將更新DOM的部分割區域。[13]在傳回原始資料時,客戶端側的JavaScript通常將其轉換為HTML,然後用它來更新DOM的部分區域。
SPA技術將邏輯從伺服器轉移到了客戶端。這導致Web伺服器發展為一個純資料API或Web服務。這種架構的轉變在一些圈子中被稱為「瘦伺服器架構」,以強調複雜性已從伺服器端轉移到客戶端,並認為這最終降低了系統的整體複雜性。
這種設計是伺服器在主記憶體中儲存必要的客戶端所處狀態。這種模式下,當任何請求到達伺服器(通常因使用者操作)時,伺服器傳送適當的HTML和/或JavaScript,以及具體的更改,以使客戶端達到新的期望狀態(如添加、刪除或更新部分客戶端的DOM)。與此同時更新伺服器中的狀態。這種設計下的大部分邏輯都在伺服器上執行,HTML通常也在伺服器上呈現。在某些方面,伺服器是類比Web瀏覽器,接收事件並執行伺服器狀態下的增量更改,將這些更改自動傳播到客戶端。
這種方法需要更多的伺服器主記憶體和處理能力,但優點是簡化的開發模型,因為:1、應用程式通常完全在伺服器中編寫;2、伺服器中的資料和UI狀態在相同的主記憶體空間中共享,不需要自訂客戶端/伺服器通訊隧道。
這是有狀態伺服器方法的變體。客戶端頁面通常透過Ajax請求將表示其當前狀態的資料傳送到伺服器。伺服器使用這些資料能夠重新構建需要修改的頁面部分,並生成必要的資料或代碼(如作為JSON或JavaScript),將其傳回給客戶端使其它達到新的狀態。
此方法需要將更多資料傳送給伺服器,並可能需要更多計算資源才能部分或完全重建在伺服器中的客戶端頁面狀態。不過,這種方法更容易擴充,因為伺服器中不存在每個客戶端的頁面資料,因此可以將Ajax請求分派到不同的伺服器節點,而無需對談資料共享或伺服器關聯。
部分單頁式應用程式可以使用file URI方案依賴本地檔案執行。這使使用者可以從伺服器上下載單頁式應用程式並在本地裝置中執行,而不需要依賴與伺服器的網路連接。這類單頁式應用程式如果想要儲存或更新資料,則必須使用基於瀏覽器的網頁儲存。這些應用受益於HTML5提供的進階功能。[14]
由於單頁式應用程式偏離了最初為瀏覽器設計的無狀態頁面重繪模型,所以帶來了一些新挑戰。每個問題都有一個或一些有效的解決方案[15]:
由於一些流行的網路搜尋引擎的爬蟲缺乏JavaScript執行能力[20],搜尋引擎最佳化(SEO)已成為面向公眾的網站採用單頁式應用程式模型必須面對的一個問題。[21]
在2009至2015年間,Google網站管理員提出並推薦了一個「AJAX爬取方案」[22][23],其中使用起始為驚嘆號的片段識別碼(#!
)來標識有狀態的AJAX頁面。單頁式應用程式網站必須實作特殊行為才能允許搜尋引擎的爬取工具提取相關的中繼資料。對於不支援此URL雜湊方案的搜尋引擎,單頁式應用程式的雜湊網址會被視而不見。包括Jeni Tennison在內的許多作者認為這些「hash-bang」URI在W3C中被認為是存在問題的,因為它們使那些沒有在瀏覽器中啟用JavaScript的人無法訪問頁面。這也影響HTTP參照位址標頭,因為瀏覽器不允許在Referer標頭中傳送片段識別碼。[24]2015年,Google不再建議使用雜湊AJAX爬取方案。[25]
還有一些周邊方法可以使網站表現為可抓取,它們都涉及建立反應單頁式應用程式內容的獨立HTML頁面。伺服器可以建立基於HTML的網站版本並將此提供給爬取工具,也可以使用PhantomJS等無頭(headless)瀏覽器執行JavaScript應用程式並輸出生成的HTML。
這種方法需要付出不小的努力,最終可能給大型、複雜的網站帶來很大的維護成本,並且也有潛在風險。如果伺服器生成的HTML被認為與單頁式應用程式存在較大差異,則網站排名將受到處罰。執行PhantomJS來輸出HTML可能會降低頁面的回應速度,一些搜尋引擎(尤其是Google)可能因此對排名降級。[26]
增加伺服器與客戶端之間所共享代碼量的一種方法是使用如Mustache、Handlebars等無邏輯模板語言。這種模板可以用不同的代管語言來呈現,如伺服器上的Ruby和客戶端的JavaScript。但是,單純共享模板通常需要重複使用業務邏輯來選擇正確的模板,並使用資料填充它們。僅更新頁面的一小部分(諸如大型模板中的一個文字的值)時,從模板呈現可能會產生負面的效能影響。替換整個模板也可能會干擾使用者的選擇或游標位置,只更新變更的值則可能不會。為避免這些問題,應用程式可以使用UI資料繫結或粒度DOM操作來更新頁面的相應部分,而不是重新呈現整個模板。
根據單頁式應用程式(SPA)模型的定義,它只有「單個頁面」,因此這打破了瀏覽器為頁面歷史記錄導覽所設計的「上一頁、下一頁」功能。當使用者按下上一頁按鈕時,可能會遇到可用性障礙,頁面可能返回真正的上一個頁面,而非使用者所期望的上一個頁面。
傳統的解決方案是不斷更改瀏覽器網址(URL)的雜湊片段識別碼以保持與當前的螢幕狀態一致。這種方案可以透過JavaScript實現,並在瀏覽器中建立起網址歷史事件。只要單頁式應用程式能根據網址雜湊所包含的資訊重新生成相同的螢幕狀態,就能實現預期的上一頁按鈕行為。
而為進一步解決此問題,HTML5規範引入了pushState (頁面存檔備份,存於網際網路檔案館)和replaceState (頁面存檔備份,存於網際網路檔案館)來提供程式碼對實際網址和瀏覽器歷史的訪問。
諸如Google分析等分析工具高度依賴在瀏覽器中載入全新的頁面,而單頁式應用程式的工作方式不同於此。
單頁式應用程式的第一頁載入會比基於伺服器的應用程式慢。這是因為首次載入必須先拿到框架和應用程式的代碼,再在瀏覽器中呈現所需的視圖。基於伺服器的應用程式只需將所需的HTML推播到瀏覽器,從而減少了延遲和下載用時。
有一些方法可以加快單頁式應用程式的初次載入速度,比如採用多項快取措施、需要時再載入某些模組(延遲載入)。但這依舊不可能擺脫需要下載框架的事實,某些部分必須在呈現前下載。這是一個「現在支付,或者稍後支付」的問題。效能與等待時間的權衡是開發者必須作出的權衡。
單頁式應用程式在初始頁面載入時被完全載入,然後頁面區域被替換或更新為按需從伺服器載入的新頁面片段。為避免過度下載未使用的功能,單頁式應用程式通常會逐漸下載更多內容,如所需要的功能、頁面的一小塊,或者完整的一頁。
單頁式應用程式(SPA)舉措與原生桌面應用程式所使用的多檔案介面(MDI)呈現技術類似。
Seamless Wikipedia browsing. On steroids.
Every time you click a link to Wikipedia, Wiktionary or Wikiquote in your browser's search results, it will show the modern Wikiwand interface.
Wikiwand extension is a five stars, simple, with minimum permission required to keep your browsing private, safe and transparent.