在 Laravel 应用中使用 pjax 进行页面加速
说明
PHPHub 使用 pjax 来加速网页的加载, 这篇文章是在开发完此功能后做的笔记.
什么是 Pjax
.--.
/ \
## a a
( '._)
|'-- |
_.\___/_ ___pjax___
."\> \Y/|<'. '._.-'
/ \ \_\/ / '-' /
| --'\_/|/ | _/
|___.-' | |`'`
| | |
| / './
/__./` | |
\ | |
\ | |
; | |
/ | |
jgs |___\_.\_
`-"--'---'
项目地址见 这里, 官方的介绍:
pushState + ajax = pjax
详细的解释请看 知乎上的这个问题, 或者自己去查阅资料.
简单点描述, 就是利用 ajax
技术去服务器获取文档, 在不刷新浏览器页面的情况下, 更新当前页面, 并且能保证页面的 js
和 css
等 assets
文件不会被重复加载, 然后利用浏览器提供的 pushState
功能, 对 URL 进行更新, 并能保证用户通过点击 back 按钮回溯到历史页面.
注意: 并不是所有浏览器都支持 pushState, 关于浏览器的兼容请见这里, 当浏览器不兼容的时候, 会自动使用原始的浏览方式进行访问.
为什么要使用 Pjax
因为不需要整个页面刷新, 并且 assets
文件都不需要重新加载, 很大程度上提高了页面的加载速度.
服务端安装 rcrowe/Turbo
使用 package rcrowe/Turbo .
安装 rcrowe/Turbo
在 composer.json
里的 require
属性下添加:
"rcrowe/turbo": "0.2.*"
然后 composer update
或者 composer install
配置 Providers
编辑 app/config/app.php
文件, 在选项 providers
数组里面添加:
"Turbo\Provider\Laravel\TurboServiceProvider",
下载 pjax.js
在 public\js
文件夹下
wget https://raw.github.com/defunkt/jquery-pjax/master/jquery.pjax.js
然后在模版里面加载此文件
<script src="{{ cdn('js/jquery.pjax.js') }}"></script>
最后页面里调用:
$(document).ready(function()
{
$(document).pjax('a', 'body');
});
上面的代码解释是, 把所有的 a
标签的点击事件截获, 如果当前浏览器支持 pjax
的话, 发送一个 ajax 请求, 并把参数 _pjax=body
带过去.
如果一起顺利的话, 在 Chrome 的 debuger 里能看到类似于这样的请求:
至此, 已经顺利配置完毕.
添加加载动画
接下来要来添加一个页面加载的动画, 效果如下:
添加 nprogress
使用 rstacruz/nprogress 来实现.
添加的方法是 下载 文件, 然后把 nprogress.js
和 nprogress.css
添加到页面中:
<script src='nprogress.js'></script>
<link rel='stylesheet' href='nprogress.css'/>
调用
修改上面的代码, 修改后的代码如以下:
$(document).ready(function()
{
$(document).pjax('a', 'body');
$(document).on('pjax:start', function() {
NProgress.start();
});
$(document).on('pjax:end', function() {
NProgress.done();
self.siteBootUp();
});
});
这样的话, 每一次点击页面的时候就会有很酷炫的效果了. :dancer:
关于此次的代码修改, 见这个 commit.
--- EOF --
欢迎关注 LaravelTips
, 这是一个专注于为 Laravel 开发者服务, 致力于帮助开发者更好的掌握 Laravel 框架, 提升开发效率的微信公众号.
@Cooper 貌似改了挺久的了, 考虑到 seo 友好.
@isPythoner 你是在说访问 phphub 的时候吗?
@isPythoner
?_pjax=body
这个参数是pjax
自动添加的, TA 会判断浏览器是否支持, 如果支持的话, 就添加, 否的话就如正常的访问.至于外部 js 加载慢的, 尽量把 js 放到页面底部, 这样就不影响页面渲染.
@lovecn 好建议.
@baocaixiong 刚刚解决了这个问题, 原因见这里: Github issue
@liball 你可以去 http://segmentfault.com/t/pjax 发个问题, 详细描述, 然后把链接贴给我.
我也来学习学习
:100:
:100:
不支持laravel5.1吗?会报错。。。
我点击左侧菜单中的a链接,载入指定连接的页面后,当我再次f5刷新页面后,只能显示载入的页面内容。这时候样式,js,其他页面内容都没了。这应该怎么解决啊
这个需要后端识别
_pjax
请求吗,或者说_pjax
请求和普通
请求后端返回的数据是不是不一样的?前者返回的是页面的部分内容,后者返回的是整个页面,是这样理解吗?那后端应该如何处理这个逻辑呢?