官术网_书友最值得收藏!

3.4 單頁面架構

3.4.1 單頁面應用的定義

單頁Web應用(single page web application,SPA)就是只有單個Web頁面的應用,廣泛應用了AJAX技術,通過頁面局部刷新,而不是通過從遠程服務器渲染頁面使全部頁面重寫。當前主流JS框架都將SPA作為主要開發模式。與SPA相對的是多頁面應用(MPA),典型代表是早期以JSP為模板的傳統應用結構。

在SPA中,第一次加載時要加載絕大多數的靜態資源,包括HTML、CSS、JS、Image等。頁面加載完成后,SPA不會因為用戶的操作而進行頁面的重新加載或跳轉。取而代之的是通過異步獲取JSON數據局部刷新頁面,利用JS動態地變換HTML的內容。SPA是前端面向接口(或面向API)編程的一個具體實現方式。

3.4.2 SPA的優缺點

(1)SPA的優點

■ 良好的交互體驗,在SPA中用戶不需要刷新頁面,頁面切換流暢,更加類似于本地應用,更具響應性。

■ 后端與前端解耦,后端不再負責頁面渲染,后端吞吐能力提高。后端面向接口編程,一套后端可以面向不同終端。

(2)SPA的缺點

■ SEO難度較高,由于內容都在一個頁面中動態替換顯示,很多搜索引擎不能通過JS獲取動態頁面,SPA模式在SEO上有著天然的弱勢。

■ 初次加載耗時多,SPA在初始加載頁面時需要將大量JavaScript、CSS統一加載,會導致第一次訪問時速度較慢。

■ 前進、后退功能缺失,由于AJAX請求不需要整頁面的刷新動作,不會導致瀏覽器的URL地址變化,因此頁面的變化無法記錄到瀏覽器的歷史記錄堆棧中,從而使得用戶無法通過瀏覽器的前進/后退按鈕在不同狀態頁面間進行切換。

3.4.3 服務端渲染

為了解決SPA應用的SEO問題,單獨提供一套靜態頁面是最好的解決辦法,可以使用服務端渲染技術(Server Side Rendering,SSR),即由后端服務器將數據與模板結合,返回HTML的過程。服務端渲染包括非同構渲染和同構渲染。

(1)非同構渲染模式下前后端不是同一種技術棧,如后端采用經典的Spring MVC渲染輸出。此種模式的主要問題是編寫兩套代碼導致工作量較大。

(2)同構渲染是指前后端采用相同的技術棧進行渲染輸出。當前各大前端框架基本都提供自身相對應的同構的服務端渲染技術。如在Vue的官網上有Vue SSR指南,見https://ssr.vuejs.org/zh/。其他主要的SSR技術包括PrerenderJS,NRect服務器渲染框架Next.js,Vue服務器渲染框架Nuxt.js。

采用PrerenderJS進行渲染,首先通過反向代理或者Prerender應用程序中間件判斷訪問端是否來自爬蟲,針對爬蟲程序會先使用Google-Chrome加載網站資源,并返回靜態HTML給爬蟲程序,若非爬蟲程序可以直接回溯到源站。PrerenderJS不區分前端開發語言,能統一做預加載。對爬蟲進行判斷時,PrerenderJS提供在應用層判斷或代理層判斷等多種模式,但在應用層判斷會加重應用層負擔,推薦在代理層進行判斷。

3.4.4 初始頁面優化

為了解決SPA初始頁面加載慢的問題,要盡可能地減少初始頁面文件的大小,主要方法如下:

(1)懶加載,例如,結合webpack的代碼分割功能,配合使用Vue的路由與組件懶加載辦法。

(2)在業務上優先顯示功能按鈕,延時顯示可見區域外內容。

(3)不阻塞預加載,使用<link rel="preload">屬性進行預加載,將加載和執行分離開,不阻塞渲染和document的onload事件。

(4)內容壓縮,啟用gzip功能,在服務端壓縮資源,瀏覽器解壓縮。

(5)使用正確的圖片文件格式,小圖片使用Base64傳輸。

(6)精簡JS與CSS代碼。

(7)減少get請求數,合并文件。

(8)使用CDN加速。

3.4.5 地址堆棧管理

一般情況下缺失瀏覽器前進后退功能對用戶影響不大,在業務上也可以通過“面包屑”進行替代。有特殊要求的,解決辦法是用JS修改location.hash值(URL中“#”符號后的字符串),另外也可在頁面中嵌入隱藏Iframe,瀏覽器可以對Iframe節點的src屬性建立堆棧,通過建立頁面狀態與URL hash或Iframe的對應關系解決問題。

主站蜘蛛池模板: 广水市| 麻栗坡县| 克拉玛依市| 公安县| 长泰县| 正宁县| 铁力市| 湖北省| 福鼎市| 文安县| 弥渡县| 巴青县| 潮州市| 茌平县| 崇州市| 黔西县| 乌兰浩特市| 湖南省| 桓仁| 武安市| 武乡县| 曲周县| 抚松县| 修武县| 电白县| 潮安县| 凌云县| 固镇县| 望谟县| 西峡县| 望都县| 新绛县| 大余县| 九龙坡区| 得荣县| 崇州市| 惠来县| 奉节县| 泗水县| 开平市| 抚远县|