考虑使用 Pjax 加速你的网站

在通常的网站中,如果需要链接到其它的页面(不是数据),只能刷新整个网站 做一次链接的跳转.

<body>
    <header>Header</header>
    <main>Content</main>
    <footer>Footer</footer>
</body>

其实 headerfooter 页已经不需要重新加载了 如果只去加载主要的数据页面 (Content) 会不会更快一点?

你想到的 jquery 已经想到了,在 jquery api 中,提供了这样一个方法:

load(url, [data], [callback]) 

发起 ajax 请求去拿数据页面,获取到页面之后进行选定节点到标签渲染(修改),最终执行完毕 callback.

如果你使用了 load 方法完成了整站的编写,那我想告诉你的是 这是一个悲伤的事情,因为你的网站没有后退功能!!!

使用 load 方法确实能获取一部分页面进行渲染,增加用户的交互性,但是浏览器的地址永远不会改变!,这是因为你并没有跳转页面,你只是一直在发送 ajax 请求而已。

终于切入主题了 今天给大家介绍的 PJAX


什么是PJAX?

PJAX 并不是什么新的技术 , 只是在HTML5推出之后 提供了一个 pushState 的方法 可以让你改变浏览器的 url 地址 和 title

而 PJAX 就是 对 ajax + pushState 的封装 , 同时支持了缓存和本地存储 , 并且支持动画展现渲染的标签(支持自定义动画)

项目主页: http://pjax.herokuapp.com

PJAX 开源项目地址: https://github.com/defunkt/jquery-pjax

有哪些公司在使用?

大名顶顶的 Github

新浪微博 Weibo

知乎 Zhihu

如何使用?

使用方式非常简单 , 首先下载好 jquery.pjax.js 导入到你项目

$.pjax({
    selector : 'a[data-pjax]',
    container : '#main-container', //内容替换的容器
    show : 'fade', //展现的动画,支持默认和fade, 可以自定义动画方式,这里为自定义的function即可。
    cache : false, //是否使用缓存
    storage : false, //是否使用本地存储
    titleSuffix : '-pjax', //标题后缀
    filter : function() {} //过滤器
})

当点击标签带 data-pjax 的 a 标签时 , PJAX 会自动拦截默认 a 标签事件 , 并且会发起一个 Ajax 请求 (触发 pjax.start) 去获取数据页面 , 当获取到页面之后(触发 pjax.end) 进行页面渲染.

而我们的服务端只需要判断在 request 请求头里面是否含有 X-PJAX 就知道返回什么页面了。

String pjax = request.getHeader("X-PJAX");
if(pjax != null && pjax.equals("true")){
    //返回部分页面
}else{
    //返回正常页面
}

推荐 PJAX 配合 NProgress 使用 , 因为这样用户体验会更好。

container.on("pjax.start", function() {
    NProgress.start();
})

container.on("pjax.end", function() {
    NProgress.done();
})

需要注意的地方

由于业务 js 代码可能在部分页面中,所以要注意使用 delegate 添加的事件 这个是事件委托 所以会导致事件重复添加 在这里我给一个解决的方法

//在请求页面之前 解绑事件
container.on("pjax.start", function() {
    $('#main').undelegate();
})

注意 这里不要写成

$(document).undelegate();

如果写成了 document 会解绑一些组件添加的事件 然而加载部分页面并不会初始化组件 就会导致组件失效 比如 bootstrap 的 tab

最后

还想更快一点? 没问题 去看看 Google 提供的 AMP 技术, 目前 wordpress 已经有插件支持。

如果你使用的 Chrome 浏览器浏览 AMP 项目会有彩蛋。