什么是單頁應(yīng)用呢?單頁應(yīng)用的全稱是 single-page application,簡稱 SPA,它是一種網(wǎng)站應(yīng)用的模型,它可以動態(tài)重寫當(dāng)前的頁面來與用戶交互,而不需要重新加載整個頁面。單頁應(yīng)用的流暢性讓 Web 應(yīng)用更像桌面端或 Native 應(yīng)用了。相對于傳統(tǒng)的 Web 應(yīng)用,單頁應(yīng)用做到了前后端分離,后端只負(fù)責(zé)處理數(shù)據(jù)提供接口,頁面邏輯和頁面渲染都交給了前端。前端發(fā)展到現(xiàn)在,單頁應(yīng)用的使用已經(jīng)很廣泛,目前時興的 react、vue、Angular 等前端框架均采用了 SPA 原則。單頁應(yīng)用意味著前端掌握了主動權(quán),也讓前端代碼更復(fù)雜和龐大,模塊化、組件化以及架構(gòu)設(shè)計都變得越來越重要。
2、工作原理
SPA 的一個重要實現(xiàn)就是改變路由時,頁面不刷新。實現(xiàn)這個功能,通常有兩種方式:使用 window.history 對象或 location.hash。
3、history 對象
window.history 包含了瀏覽器的歷史信息,它有以下幾種常用方法:
history.back():與在瀏覽器點擊后退按鈕相同;
history.forward():與在瀏覽器中點擊按鈕向前相同;
history.go(n):接受一個整數(shù)作為參數(shù),移動到該整數(shù)指定的頁面,比如 go(1) 相當(dāng)于 forward(),go(-1) 相當(dāng)于 back(),go(0) 相當(dāng)于刷新當(dāng)前頁面。
html5 對 history 對象新增了 pushState() 和 replaceState() 方法,這兩個方法可以往歷史棧中添加數(shù)據(jù),給用戶的感覺就是瀏覽器的 url 改變了,但是頁面并沒有重新加載。pushState() 是在瀏覽記錄中添加一個新記錄,replaceState() 則是修改當(dāng)前的瀏覽器記錄,這是二者的細(xì)微差別,使用時參數(shù)的字段和含義都是一樣的。
window.history.pushState(state, title, url)
state 是狀態(tài)對象,可以用 history.state 讀??;title 表示新頁面的標(biāo)題,但是現(xiàn)在的所有瀏覽器都會忽略這個字段,所以可以傳 null;url 是新頁面的地址,必須是和當(dāng)前頁面在同一個域。當(dāng)用戶點擊瀏覽器上的前進(jìn)和后退按鈕時,或者調(diào)用上述 window.history 的 back、forward 和 go 方法,就會觸發(fā) popstate 事件。該事件只針對同一個文檔,如果瀏覽歷史的切換導(dǎo)致加載了不同的文檔,popstate 事件將不會被觸發(fā)。popstate 事件回調(diào)函數(shù)的參數(shù)中的 state 屬性指向 pushState() 和 replaceState() 方法為當(dāng)前頁面提供的狀態(tài),也就是 pushState() 和 replaceState() 方法使用時傳的第一個參數(shù) state。
4、hash
hash 是 location 對象的屬性,它指的是當(dāng)前 url 的錨,也就是從 # 號開始的部分。修改 location.hash 并監(jiān)聽 window 的 hashchange 事件,也能達(dá)到同樣的目的。
5、優(yōu)缺點
SPA 可圈可點,現(xiàn)在已被大家廣泛使用,也得到了主流框架的支持,但是它也有局限性,我們將它的優(yōu)缺點總結(jié)如下。
優(yōu)點:
無刷新體驗,用戶在切換頁面過程中不會頻繁被“打斷”,因為界面框架都在本地,對用戶的響應(yīng)非常及時,因此提升了用戶體驗;
分離前后端關(guān)注點,前端負(fù)責(zé)界面顯示,后端負(fù)責(zé)數(shù)據(jù)存儲和計算,各司其職,不會把前后端的邏輯混雜在一起;
減輕服務(wù)器壓力,服務(wù)器只用出數(shù)據(jù)就可以,不用管展示邏輯和頁面合成,吞吐能力會提高幾倍;
API 共享,同一套后端程序代碼,不用修改就可以用于Web界面、手機、平板等多種客戶端;
完全的前端組件化,前端開發(fā)不再以頁面為單位,更多地采用組件化的思想,代碼結(jié)構(gòu)和組織方式更加規(guī)范化,便于修改和調(diào)整。
缺點:
對 seo 不友好,盡管可以通過 Prerender 預(yù)渲染優(yōu)化等技術(shù)解決一部分,但是相對還是不容易索引到它;易出錯,需要使用程序管理前進(jìn)、后退、地址欄等信息;
缺失URL地址,搜索引擎程序無法正確或完整索引整站或頁面完整內(nèi)容。無法分享轉(zhuǎn)發(fā)內(nèi)容對應(yīng)URL地址等;
6、對比分析
|
單頁面應(yīng)用(SinglePage Web Application,SPA) | 多頁面應(yīng)用(MultiPage Application,MPA) |
---|---|---|
組成 | 一個外殼頁面和多個頁面片段組成 | 多個完整頁面構(gòu)成 |
資源共用(css,js) | 共用,只需在外殼部分加載 | 不共用,每個頁面都需要加載 |
刷新方式 | 頁面局部刷新或更改 | 整頁刷新 |
url 模式 |
a.com/#/pageone a.com/#/pagetwo |
a.com/pageone.html a.com/pagetwo.html |
用戶體驗 | 頁面片段間的切換快,用戶體驗良好 | 頁面切換加載緩慢,流暢度不夠,用戶體驗比較差 |
轉(zhuǎn)場動畫 | 容易實現(xiàn) | 無法實現(xiàn) |
數(shù)據(jù)傳遞 | 容易 | 依賴 url傳參、或者cookie 、localStorage等 |
搜索引擎優(yōu)化(SEO) | 需要單獨方案、實現(xiàn)較為困難、不利于SEO檢索 可利用服務(wù)器端渲染()優(yōu)化 | 實現(xiàn)方法簡易 |
試用范圍 | 高要求的體驗度、追求界面流暢的應(yīng)用 | 適用于追求高度支持搜索引擎的應(yīng)用 |
開發(fā)成本 | 較高,常需借助專業(yè)的框架 | 較低 ,但頁面重復(fù)代碼多 |
維護(hù)成本 | 相對容易 | 相對復(fù)雜 |