用戶:恆溫/單頁應用 (1)
單頁應用 (SPA)是一種 網頁應用程式 或 網站 ,適合於單個 網頁, 目的是提供一個和桌面應用程式相似的用戶體驗。 在SPA中,無論是所需要的代碼是HTML、 JavaScript還是CSS都在一次頁面加載中獲取,[1] 或者通常根據用戶動作動態加載有關的資源並按需要加入到網頁中。 儘管 位置的哈希 或 HTML5 歷史API 可用於在應用中提供獨立邏輯頁的感性和導航,網頁在這個過程中不會重新加載,也不控制跳轉到另一個網頁。[2] 和單頁面應用交互通常會涉及到和網絡伺服器動態通信。
歷史
雖然早在2003年就被討論過了,但是單頁面應用的起源還是不太清楚.[3] Stuart (stunix) Morris於2002年4月寫了具有同樣的目標和功能的獨立網站slashdotslash.com。[4] 同年晚些時候Lucas Birdeau, Kevin Hakman, Michael Peachey和Evan Yeh在美國專利8,136,109中描述了單頁面應用的實現。 [5]
JavaScript可以用於在網絡瀏覽器中顯示用戶界面 (UI),運行應用邏輯,以及和網絡伺服器進行通信。有成熟的開源庫可以用來建立一個SPA,這樣可以減少開發人員不得不編寫的JavaScript代碼量。
技術實現
即使應用需要和伺服器進行通信,還是有各種技術可用於讓瀏覽器保持單頁面。
JavaScript框架
諸如 AngularJS Ember.js, Meteor.js,ExtJS 和 React 這些網絡瀏覽器JavaScript框架都已經採納了SPA原則。
- AngularJS 是一個純粹的客戶端框架。 AngularJS的模板是基於雙向 UI數據綁定的。 數據綁定是一種讓模型變化時更新視圖,和在視圖變化時更新模型的自動實現的方式。 HTML模板在瀏覽器中被編譯。 編譯的階段創建純粹的HTML代碼,然後瀏覽把這段HTML代碼重新渲染到即時視圖中去。這個步驟在後面的頁面展現中重複進行。 在傳統的伺服器端HTML編程的中,如控制器和模型這樣的概念和伺服器進程進行交互來生成新的HMTL視圖。 在AngularJS框架中,控制器和模型狀態在客戶端瀏覽器中被維護。 因此,新網頁都能夠在不和伺服器交互的情況下產生。
- Ember.js 是一個基於模型-視圖-控制器(MVC)軟件架構模式的客戶端JavaScript網絡應用框架。 它把常用語言的優點和最佳實踐融入到一個提供豐富的對象模型,陳述式雙向數據綁定,計算屬性,由Handlebars.js提供支持自動更新的模板和管理應用狀態的路由等特性的框架中,讓開發者能夠創建可擴展的單頁應用。
- Meteor.js 是專為SPAs設計的全棧(客戶端-伺服器)JavaScript框架。 它的特點在於相對Angular,Ember or ReactJS,引用錯誤:
<ref>
標籤中未填內容的參照必須填寫name屬性 有更簡單的數據綁定,使用 Distributed Data Protocol引用錯誤:<ref>
標籤中未填內容的參照必須填寫name屬性 和發佈/訂閱模式 實時自動傳播數據變化到客戶端,同時還不需要開發人員來編寫任何同步代碼。 全棧反應堆確保所有層面,從數據庫到模板都能自動按需更新。 Ecosystem包,例如 伺服器端渲染引用錯誤:<ref>
標籤中未填內容的參照必須填寫name屬性 處理了搜尋引擎優化的問題。 - Aurelia 是一個JavaScript客戶框架,用於流動裝置、桌面和網絡。 它是類似於AngularJS,但是更新,符合更多標準,並使用了模塊化辦法。 Aurelia是用下一代 ECMScript寫的。
Ajax
目前正在使用的最重要的技術是Ajax。引用錯誤:<ref>
標籤中未填內容的參照必須填寫name屬性 主要使用JavaScript的 XMLHttpRequest/ActiveXObject(被棄用的)對象,其他Ajax包括使用IFRAME或者腳本HTML元素。受歡迎的庫像jQuery 規範化了Ajax在來自不同製造商的瀏覽器上的行為,進一步推廣Ajax的技術。
WebSockets
WebSockets 是HTML5的規範的一部分,是一個雙向有狀態的實時的客戶端-伺服器通信技術,從性能[6]和簡潔性上看是Ajax的上級。
伺服器推送事件
伺服器發送事件 (SSEs)是一個技術,用於伺服器將初始數據傳輸的瀏覽器客戶端。 一旦初始化連接建立,一個事件流保持開放狀態直到客戶端關閉連接。 SSEs通過傳統的HTTP發送並且具有多種WebSockets缺乏的功能,諸如自動重新連、事件標識,以及能夠發送任意的事件。引用錯誤:<ref>
標籤中未填內容的參照必須填寫name屬性
瀏覽器插件
雖然這種方法已經過時,異步調用伺服器也可以使用瀏覽器插技術,例如 Silverlight, Flash,或 Java applets。
數據傳輸(XML,JSON和Ajax)
發送到伺服器的請求通常導致伺服器返回原始數據(例如, XML 或 JSON),或者新的HTML。 在該情況下,HTML由伺服器返回,JavaScript在客戶更新DOM(文件的對象模型)的部分區域。引用錯誤:<ref>
標籤中未填內容的參照必須填寫name屬性 當原始數據被返回時,往往是一個客戶端JavaScript XML /(XSL)進程(例如返回JSON時一個模板)用於翻譯原始數據為HTML,然後用其更新DOM的一部分區域。
伺服器架構
輕型伺服器架構
一個SPA把邏輯從服務端移動到客戶端。 這導致伺服器的角色演變成一個純粹的數據API或網絡服務。 這個結構轉變,在某些圈子被稱作"輕型伺服器架構"來強調複雜性已經從伺服器端移向客戶端,並帶來了這最終降低了整個系統的複雜性的爭論。
重型有狀態伺服器架構
伺服器在內存中保存必要的客戶端所在頁面的狀態。 在這種方式下,當任何請求到達伺服器(通常用戶的行為),伺服器發送適當HTML和/或帶結構變化的JavaScript讓客戶端進入想要的新狀態(常常增加/刪除/更新的一部分客戶端DOM)。 在同一時間,伺服器上的狀態也更新。 大多數的邏輯在伺服器上執行,並HTML通常也在伺服器上渲染。 在某些方面,伺服器模擬網絡瀏覽器,接受事件並在伺服器狀態上執行delta changes,並自動傳播到客戶端。
這種方法需要更多的伺服器存儲和伺服器處理,但其優點是簡化的開發模式,因為a)應用通常是完全在伺服器編碼,並b)伺服器上的數據和UI共享在同一個存儲空間,無需特定的C/S通信橋樑。
重型無狀態伺服器架構
這是一個有狀態伺服器方法的變形。 客戶端頁面通常是通過Ajax請求發送表示其目前狀態的數據到伺服器。通過這個數據,伺服器能夠重建需要修改的頁面部分的客戶端狀態,並能生成必要的數據或代碼(例如,JSON或JavaScript),返回的數據或代碼會把客戶端帶到一個新的狀態,通常是根據發起請求的客戶端行為來修改頁面的DOM樹。
這種方法需要發送到服務端更多的數據,並且為了在服務端重建客戶端頁面狀態,每個請求都可能需要更多的計算資源。 同時,這種做法更易於擴展,因為沒有在服務端保存每個單獨客戶端頁面數據,因此,Ajax請求能被分派給不同的伺服器節點,不需要會話數據共享或伺服器關聯性。
本地運行
一些SPAs可以從一個使用的 文件URI結構本地文件執行。 這使用戶能夠從一個伺服器下載SPA,然後從一個本地存儲設備運行該文件,而不依賴於伺服器的連通性。 如果這樣一個SPA要存儲和更新數據,它必須使用基於瀏覽器的 網絡存儲。 這些應用從HTML5的進步中受益。[7]
單頁應用模型的挑戰
因為SPA是由瀏覽器最初設計的無狀態頁面重繪模型進化出來的,一些新的挑戰已經浮現。 每個這些問題都有有效的解決方案[8] :
搜尋引擎優化
因為主流的網絡搜尋引擎[13] 爬蟲缺乏JavaScript的執行,SEO(優化搜尋引擎)是希望在網站上採用SPA模型的公眾面臨一個歷史難題,。[14]
從2009年至2015年, 谷歌網站管理員中 提出並建議一個"Ajax爬蟲規範"[15][16] ,為有狀態的 AJAX 頁面在片段標識符首字母使用的一個感嘆號(#!
)。在SPA站點中必須實現特殊的行為以便搜尋引擎提取相關元數據。 對不支持這種URL哈希結構的搜尋引擎,SPA站點上的哈希網址保持不可見狀態。 這些"散列爆炸"URIs被包括W3C的Jeni Tennison在內的一些作家認為是有問題的,因為它們使頁面在那些瀏覽器沒有開啟JavaScript的人無法訪問。他們還破壞 HTTP referer 頭,因為瀏覽器是不允許在Referer頭髮送片段標識。[17] 在2015年,谷歌棄他們的散列的爆炸的AJAX爬取提案。[18]
或者,應用可能呈現的第一頁伺服器的負載和隨後的網頁的更新客戶。 這個傳統上是困難的,因為呈現代碼,可能需要寫在一個不同的語言或框架的伺服器和客戶。 使用邏輯較少的模板,截編寫從一種語文到另一個,或使用相同的語言在伺服器和客戶可能有助於增加量的代碼,可以共享。
因為搜尋引擎優化的兼容性並不是微不足道的SPA,這是值得注意的水療中心通常不使用的情況下,搜尋引擎編制索引是一種要求,或可取的。 使用情況包括應用程式面的私人數據的背後隱藏着一個 身份認證 系統。 在該情況下,這些應用消費品,往往是一個經典的網頁重新繪的模型用於將應用程式的着陸頁和營銷網站,其提供足夠的元數據的應用程式出現的一擊一個搜尋引擎查詢。 博客,支持論壇和其他傳統的網頁重新繪製文物往往圍坐在溫泉,可以種搜尋引擎的有關條款。
另一個方法中使用的伺服器中心網框架,如基於Java ItsNat 是呈現的任何超文本的伺服器使用相同的語言和模板的技術。 在這種方法,伺服器就知道精確的DOM國家在客戶的任何或大或小的頁面更新的要求產生的伺服器,以及運輸由阿賈克斯,的確切JavaScript code帶來的客戶網頁的新的國家執行DOM方法。 開發人員可以決定哪些網頁的國家必須通過可搜索蜘蛛網的搜尋引擎優化的和能夠產生所需的國家在裝載時間產生純HTML而不是JavaScript。 在這種情況下的ItsNat框架,這是自動的,因為ItsNat保持的客戶DOM樹在伺服器作為一個Java W3C DOM樹;渲染這DOM樹在伺服器生成純HTML在裝載時間和JavaScript DOM行動,阿賈克斯的請求。 這種雙重性是非常重要的搜尋引擎優化,因為開發者可以建立,同Java的代碼和純粹基於HTML模板所需DOM國家在伺服器;在頁面負載時,常規HTML是由ItsNat使這DOM狀態的搜尋引擎優化兼容。 為1.3版本的,[19] ItsNat提供了一個新的無國籍模式中,以及客戶DOM不是在伺服器上保留因為與無國籍模式中客戶多國家是部分或完全重建的時伺服器上處理任何Ajax請求基於需要的數據由客戶發送通知伺服器的流DOM狀態;無國籍模式中還可以搜尋引擎優化兼容的,因為搜尋引擎優化的兼容性發生在裝載時最初的頁面不受影響狀態或無國籍的模式。
有一對夫婦的解決方法,使它看起來就像網站的可搜索的。 兩者都涉及創建獨立HTML網頁鏡的內容。 伺服器可以創建一個基於HTML版網站,並提供,以爬蟲,或者它可以使用一個無頭的瀏覽器,如PhantomJS運行JavaScript應用程式及輸出的所得HTML。
這些都需要相當多的努力,並可以最終放棄維護頭痛的大型複雜的網站。 也有潛在的SEO的陷阱。 如果伺服器生成HTML被認為是太不同的SPA內容,那麼該網站將被處罰。 運行PhantomJS輸出HTML可以減緩的反應速度的網頁,其中一些是為其搜尋引擎–谷歌,特別是降級排名。[20]
客戶端/服務端代碼分離
一種方法來增加量的代碼,可以共用伺服器和客戶之間是使用一種邏輯-小模板語言喜歡 鬍子 或 把手的。 這種模板可以呈現不同的主語言,例如 紅寶石 在伺服器和 JavaScript 在的客戶。 然而,僅僅共享模板通常需要工作重複的 業務邏輯 使用的選擇正確的模板,並填入數據。 呈現的模板可能有負面業績的影響時,才更新一小部分的頁面,如價值的文本輸入內的一個大型的模板。 更換整個模板也可能會干擾用戶的選擇或標位置,此處僅更新的改變價值可能不會。 為了避免這些問題,應用程式可以使用 UI數據綁定 或顆粒狀 DOM 操縱,只有在更新相應的部件的網頁,而不是重新呈現整個模板。
瀏覽器歷史
有一個SPA是,通過的定義,'一個單頁的',該模型休息瀏覽器是設計為一頁歷史上航行使用向前/後的按鈕。 這提出了一個可用性障礙時,一種用戶按下按鈕回,希望前面的屏幕國家內的溫泉,而是應用程式的單頁卸載和以前的頁面的瀏覽器的歷史記錄。
傳統的解決方案用於水療中心已經改變瀏覽網址的散列 段標識符 合當前的屏幕狀態。 這是可以實現的JavaScript,並使網址的記錄事件,以建立內的瀏覽器。 只要溫泉能夠重建相同的屏幕狀態從中包含的信息URL散,預期後按鈕行為是保留。
進一步解決這一問題,5說明已采 pushState 和 replaceState 提供程序訪問,實際的網址和瀏覽器的歷史。
分析
分析工具,例如 谷歌分析 依賴整個新網頁載在瀏覽器,發起一個新的頁面負荷。 溫泉不以這種方式工作。
之後的第一頁載,隨後的所有網頁和內容的改變都是內部處理的應用,這應該只是一個叫功能以更新的分析包。 沒有電話所述的功能,瀏覽器永遠不會觸發一個新網頁載,沒有得到增加的瀏覽器的歷史和分析軟件包已經沒有知道誰是做什麼的網站上。
為單頁面應用添加頁面加載
通過使用HTML5歷史API可以給SPA添加頁面加載事件;這將有助於集成分析。 困難在於管理這個並確保這一切都被精確跟蹤,這涉及檢查缺失的報告和雙入口。 一些框架為主要分析供應商中的大多數提供開源的分析集成。 開發者可以將它們集成到應用,並確保一切正常,但是沒有需要從頭開始做的所有的事情。
初始化加載的速度
單頁應用較於基於伺服器的應用都有一個較慢的首頁加載。 這是因為初始化加載必須在把需要的視圖在瀏覽器中渲染成HTML之前,把框架和應用代碼拉取下來。一個基於伺服器的應用程式,只需要把必要HTML推送給瀏覽器,減少了延遲和下載時間。
加快頁加載
有一些方法可以加速SPA的首次加載,例如一種重方法是用緩存和按需懶加載模塊。 但不可能避免這個事實,它需要下載的框架,至少是一些應用代碼,並極可能將在瀏覽器展示東西前調用API獲取數據。 這是一個『要麼現在付錢給我,要麼以後付給我'的折衷場景。 性能和等待時間這個問題的仍然是一個開發人員必須做的決定。
網頁生命周期
一個SPA在初始頁面加載中完全載入,接着按需從伺服器加載新頁面片段替換或者更新頁面區域。為避免過多的下載未使用的功能,SPA通常會逐步在需要時下載更多的功能,或是小的頁面片段,或是完整的畫面模塊。
這樣在SPA中的"狀態"和傳統網站"網頁"存在一種類比。 因為同一頁面的"狀態導航"和頁面導航類似,在理論上,任何基於頁面的網站都可以轉化為單頁面,通過比較非SPA連續頁面中變化的部分得到結果,在同一頁面替換掉即可。
網絡上的SPA做法類似於流行在原生桌面應用程式的單一的文件接口 (SDI)表現技術。
參考
- ^ Flanagan, David, "JavaScript - The Definitive Guide", 5th ed., O'Reilly, Sebastopol, CA, 2006, p.497
- ^ Fixing the Back Button: SPA Behavior using Location Hash. [2016-01-18] (美國英語).
- ^ Inner-Browsing: Extending Web Browsing the Navigation Paradigm. [2011-02-03].
- ^ Slashdotslash.com: A self contained website using DHTML. [2012-07-06].
- ^ US patent 8,136,109. [2002-04-12].
- ^ Real-Time Monitoring using AJAX and WebSockets. [2016-06-01].
- ^ Unhosted web apps.
- ^ The Single Page Interface Manifesto. [2014-04-25].
- ^ Derby. [2011-12-11].
- ^ Sails.js. [2013-02-20].
- ^ Tutorial: Single Page Interface Web Site With ItsNat. [2011-01-13].
- ^ HTML5
- ^ What the user sees, what the crawler sees. [January 6, 2014].
the browser can execute JavaScript and produce content on the fly - the crawler cannot
- ^ Making Ajax Applications Crawlable. [January 6, 2014].
Historically, Ajax applications have been difficult for search engines to process because Ajax content is produced
- ^ Proposal for making AJAX crawlable. Google. October 7, 2009 [July 13, 2011].
- ^ (Specifications) Making AJAX Applications Crawlable. Google. [March 4, 2013].
- ^ Hash URIs. W3C Blog. May 12, 2011 [July 13, 2011].
- ^ Deprecating our AJAX crawling scheme. Official Google Webmaster Central Blog. [2017-02-23] (美國英語).
|work=
和|newspaper=
只需其一 (幫助) - ^ ItsNat v1.3 release Notes. [2013-06-09].
- ^ Holmes, Simone (2015).
外部連結
- 多頁面網絡應用到單頁Ajax接口的遷移(代爾夫特技術大學): http://arxiv.org/abs/cs/0610094
- 單頁宣言界面
[[Category:网络应用程序]]