你對SPA單頁面的理解,它的優缺點分別是什麼?

語言: CN / TW / HK

一、什麼是SPA

SPA(single-page application),翻譯過來就是單頁應用SPA是一種網路應用程式或網站的模型,它通過動態重寫當前頁面來與使用者互動,這種方法避免了頁面之間切換打斷使用者體驗在單頁應用中,所有必要的程式碼(HTMLJavaScriptCSS)都通過單個頁面的載入而檢索,或者根據需要(通常是為響應使用者操作)動態裝載適當的資源並新增到頁面頁面在任何時間點都不會重新載入,也不會將控制轉移到其他頁面舉個例子來講就是一個杯子,早上裝的牛奶,中午裝的是開水,晚上裝的是茶,我們發現,變的始終是杯子裡的內容,而杯子始終是那個杯子結構如下圖

我們熟知的JS框架如react,vue,angular,ember都屬於SPA

二、SPA和MPA的區別

上面大家已經對單頁面有所瞭解了,下面來講講多頁應用MPA(MultiPage-page application),翻譯過來就是多頁應用在MPA中,每個頁面都是一個主頁面,都是獨立的當我們在訪問另一個頁面的時候,都需要重新載入htmlcssjs檔案,公共檔案則根據需求按需載入如下圖

單頁應用與多頁應用的區別

| | 單頁面應用(SPA) | 多頁面應用(MPA) | | --------- | -------------- | ---------------------------- | | 組成 | 一個主頁面和多個頁面片段 | 多個主頁面 | | 重新整理方式 | 區域性重新整理 | 整頁重新整理 | | url模式 | 雜湊模式 | 歷史模式 | | SEO搜尋引擎優化 | 難實現,可使用SSR方式改善 | 容易實現 | | 資料傳遞 | 容易 | 通過url、cookie、localStorage等傳遞 | | 頁面切換 | 速度快,使用者體驗良好 | 切換載入資源,速度慢,使用者體驗差 | | 維護成本 | 相對容易 | 相對複雜 |

單頁應用優缺點

優點:

  • 具有桌面應用的即時性、網站的可移植性和可訪問性
  • 使用者體驗好、快,內容的改變不需要重新載入整個頁面
  • 良好的前後端分離,分工更明確

缺點:

  • 不利於搜尋引擎的抓取
  • 首次渲染速度相對較慢

三、實現一個SPA

原理

  1. 監聽位址列中hash變化驅動介面變化
  2. pushsate記錄瀏覽器的歷史,驅動介面傳送變化

實現

hash 模式

核心通過監聽url中的hash來進行路由跳轉

``` // 定義 Router
class Router {
constructor () {
this.routes = {}; // 存放路由path及callback
this.currentUrl = '';

    // 監聽路由change呼叫相對應的路由回撥  
    window.addEventListener('load', this.refresh, false);  
    window.addEventListener('hashchange', this.refresh, false);  
}

route(path, callback){  
    this.routes[path] = callback;  
}

push(path) {  
    this.routes[path] && this.routes[path]()  
}

}

// 使用 router
window.miniRouter = new Router();
miniRouter.route('/', () => console.log('page1'))
miniRouter.route('/page2', () => console.log('page2'))

miniRouter.push('/') // page1
miniRouter.push('/page2') // page2
```

history模式

history 模式核心借用 HTML5 history apiapi 提供了豐富的 router 相關屬性先了解一個幾個相關的api

  • history.pushState 瀏覽器歷史紀錄新增記錄
  • history.replaceState修改瀏覽器歷史紀錄中當前紀錄
  • history.popState 當 history 發生變化時觸發

``` // 定義 Router
class Router {
constructor () {
this.routes = {};
this.listerPopState()
}

init(path) {  
    history.replaceState({path: path}, null, path);  
    this.routes[path] && this.routes[path]();  
}

route(path, callback){  
    this.routes[path] = callback;  
}

push(path) {  
    history.pushState({path: path}, null, path);  
    this.routes[path] && this.routes[path]();  
}

listerPopState () {  
    window.addEventListener('popstate' , e => {  
        const path = e.state && e.state.path;  
        this.routers[path] && this.routers[path]()  
    })  
}

}

// 使用 Router

window.miniRouter = new Router();
miniRouter.route('/', ()=> console.log('page1'))
miniRouter.route('/page2', ()=> console.log('page2'))

// 跳轉
miniRouter.push('/page2') // page2
```

四、題外話:如何給SPA做SEO

下面給出基於VueSPA如何實現SEO的三種方式

  1. SSR服務端渲染

將元件或頁面通過伺服器生成html,再返回給瀏覽器,如nuxt.js

  1. 靜態化

目前主流的靜態化主要有兩種:(1)一種是通過程式將動態頁面抓取並儲存為靜態頁面,這樣的頁面的實際存在於伺服器的硬碟中(2)另外一種是通過WEB伺服器的 URL Rewrite的方式,它的原理是通過web伺服器內部模組按一定規則將外部的URL請求轉化為內部的檔案地址,一句話來說就是把外部請求的靜態地址轉化為實際的動態頁面地址,而靜態頁面實際是不存在的。這兩種方法都達到了實現URL靜態化的效果

  1. 使用Phantomjs針對爬蟲處理

原理是通過Nginx配置,判斷訪問來源是否為爬蟲,如果是則搜尋引擎的爬蟲請求會轉發到一個node server,再通過PhantomJS來解析完整的HTML,返回給爬蟲。下面是大致流程圖