一. Pjax 是啥?
Pjax = history.pushState + Ajax
= history.pushState + Async JS + XML(xhr?)
BOM 物件 history 被增強了一波,主要是對歷史棧的操作,以前只有 replace, go 之類的,都會跳轉並刷新整個頁面,現在有了 pushState, replaceState 等等單純操作歷史棧的方法,只是單純修改歷史棧裡的內容,沒有副作用(頁面不會跳轉刷新)
關於 history 物件的更多資訊請查看 MDN History
二. Pjax 有什麼用?
1. 最初的單頁面應用(SPA)
頁面刷新不僅浪費資源(很多同級頁面上大部分內容都是相同的,沒必要重新載入這些重複內容),還影響使用者體驗(loadingloadingloading...)。局部刷新能夠避免 loading 影響使用者體驗,從 Ajax 概念一出來就有人開始這麼做了,把整站做成單頁面應用(Single Page App,簡稱 SPA),Ajax 請求 JSON,再局部刷新呈現數據,最初的 SPA 存在很多缺點:
- 最大的問題:頁面內容與 URL 不對應
這是致命的缺點,使用者看到的內容與網址列 URL 不對應,意味著內容無法分享傳播(分享傳播太重要了),瀏覽器前進/後退按鈕也無法按照使用者預期工作
- 其次:破壞 SEO
純 Ajax 實現的 SPA 對 SEO 有極大的消極影響,由於頁面上很多內容都是 Ajax 請求之後 JS 控制呈現的,蜘蛛看不到這些內容,也就根本不會被索引/收錄
2. pretty AJAX URL
為了解決 SEO 問題,Google 提出了一種很醜(雖然名字叫 pretty AJAX URL。。)的方法:#!
據說 Twitter 用過一個月,後來使用者回饋說太醜了,再後來就不用了。這種很醜的 URL 確實能解決上述的第 2 個問題,但是需要搜尋引擎配合,Google 認可這種方式,Google 的蜘蛛會把 mydomain.com/index.html#!article1 和 mydomain.com/index.html#!article2 當作兩個不同的頁面對待,服務給這種特殊 URL 的請求回傳對應的頁面即可, SEO 問題沒了。
但第一個問題還在,頁面內容與 URL 仍然不對應,於是有了下面要說的 Pjax
3. Pjax
W3C 提出了新的 API,增強了 history 對歷史棧的控制能力,能夠直接修改網址列 URL,直到這時頁面內容與 URL 才終於能夠對應了
每次局部刷新成功之後都呼叫 history.pushState 同步更新網址列的 URL(維護歷史棧),這些 URL 都對應可以直接存取的頁面,每個局部刷新動作都是由 a 標籤觸發的,JS 攔截預設跳轉,再 Ajax 請求數據呈現數據,使用者看到的是局部刷新和流暢的體驗,蜘蛛看到的是普通的 a 標籤頁面跳轉,頁面展示的內容始終與直接存取 URL 得到的內容一致,致命缺點也不存在了
如果各個瀏覽器支援性良好的話,Pjax 能夠完美支援單頁面應用,如果瀏覽器不支援新 API 就把它當蜘蛛好了(目前好像沒有好用的相容方案,jq 外掛程式也無能為力),至於 CSS/JS 衝突、記憶體洩漏等等都是 SPA 本身的問題,成熟的 SPA 方案應該可以避免這些問題
三. Pjax 怎麼用?
核心是 2 個方法和 1 個事件:
-
history.pushState(state, title, url); -
history.replaceState(state, title, url); -
popstate
其中 state 參數是自定義物件,可以透過 history.state 拿到,title 參數沒什麼用,瀏覽器都不認。push 和 replace 的區別是前者把指定 URL 入棧,後者換掉棧頂元素。瀏覽器的前進/後退會觸發 popstate,可以在裡面根據 history.state 數據作出相應處理
前輩有一個比較簡潔的 DEMO:ajax 與 HTML5 history pushState/replaceState 實例
此外,也有相應的開源函式庫可以使用:
-
jQuery 的 pjax:最近(2015-9-22)還在更新
-
history.js:2 年前停止更新了,據說很好用
-
welefen/pjax:主流 JS 函式庫的 Pjax 用法
四. 為什麼要用 Pjax?
在不影響 SEO 的前提下,局部刷新 + 本地快取能夠帶來前所未有的快速體驗,這是 Pjax 的絕對優勢
Pjax 適用於非純行動端的單頁面應用,能夠實現流暢的使用者體驗,而且封裝好的 Pjax 元件支援一些額外的功能,比如快取、在地儲存、動畫等等,使用起來也很方便
行動頁面一般不存在頻繁地大篇幅頁面內容更新,而且行動頁面很少需要考慮 SEO,直接用 Ajax 即可
五. Pjax 案例
- 全站 Pjax 部落格:porridge
暫無評論,快來發表你的看法吧