本文的示例代码参考clockwork
目录
开始
composer create-project laravel/laravel clockwork && cd clockwork
用户
- 生成数据库
php artisan migrate
- 填充表假数据
php artisan make:seed UsersTableSeeder
vim database/seeds/UsersTableSeeder.php
<?php
use Illuminate\Database\Seeder;
use App\User;
class UsersTableSeeder extends Seeder
{
public function run()
{
// 生成数据集合
$users = factory(User::class)
->times(10)
->make();
// 让隐藏字段可见,并将数据集合转换为数组
$user_array = $users->makeVisible(['password', 'remember_token'])->toArray();
// 插入到数据库中
User::insert($user_array);
}
}
vim database/seeds/DatabaseSeeder.php
<?php
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
public function run()
{
$this->call(UsersTableSeeder::class);
}
}
php artisan db:seed
关于填充数据库测试用数据 更多可以参考Laravel框架 之 RememberMe
分类
- 生成数据库
php artisan make:model Models/Category -m
vim database/migrations/*_create_categories_table.php
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateCategoriesTable extends Migration
{
public function up()
{
Schema::create('categories', function (Blueprint $table) {
$table->increments('id');
$table->string('name')->index()->comment('名称');
$table->text('description')->nullable()->comment('描述');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('categories');
}
}
php artisan migrate
- 定义模型
vim app/Models/Category.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
protected $fillable = [
'name', 'description',
];
}
- 填充表假数据
php artisan make:migration seed_categories_data
vim database/migrations/*_seed_categories_data.php
<?php
use Illuminate\Database\Migrations\Migration;
class SeedCategoriesData extends Migration
{
public function up()
{
$categories = [
[
'name' => '分享',
'description' => '分享创造,分享发现',
],
[
'name' => '教程',
'description' => '开发技巧、推荐扩展包等',
],
[
'name' => '问答',
'description' => '请保持友善,互帮互助',
],
[
'name' => '公告',
'description' => '站点公告',
],
];
DB::table('categories')->insert($categories);
}
public function down()
{
DB::table('categories')->truncate();
}
}
php artisan migrate
如果想要重新迁移数据库和生成假数据 可以使用: php artisan migrate:refresh --seed
话题
- 生成数据库
php artisan make:model Models/Topic -m
vim database/migrations/*_create_topics_table.php
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateTopicsTable extends Migration
{
public function up()
{
Schema::create('topics', function (Blueprint $table) {
$table->increments('id');
$table->string('title')->index();
$table->text('body');
$table->integer('user_id')->unsigned()->index();
$table->integer('category_id')->unsigned()->index();
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('topics');
}
}
php artisan migrate
- 定义模型
vim app/Models/Topic.php
<?php
namespace App\Models;
use App\User;
use Illuminate\Database\Eloquent\Model;
class Topic extends Model
{
protected $fillable = ['title', 'body', 'category_id'];
public function category()
{
return $this->belongsTo(Category::Class);
}
public function user()
{
return $this->belongsTo(User::class);
}
}
- 填充表假数据
vim database/factories/TopicFactory.php
<?php
use Faker\Generator as Faker;
$factory->define(App\Models\Topic::class, function (Faker $faker) {
$sentence = $faker->sentence();
// 随机取一个月以内的时间
$updated_at = $faker->dateTimeThisMonth();
// 传参为生成最大时间不超过,创建时间永远比更改时间要早
$created_at = $faker->dateTimeThisMonth($updated_at);
return [
'title' => $sentence,
'body' => $faker->text(),
'created_at' => $created_at,
'updated_at' => $updated_at,
];
});
php artisan make:seed TopicsTableSeeder
vim database/seeds/TopicsTableSeeder.php
<?php
use App\User;
use Illuminate\Database\Seeder;
use App\Models\Topic;
use App\Models\Category;
class TopicsTableSeeder extends Seeder
{
public function run()
{
// 所有用户 ID 数组,如:[1,2,3,4]
$user_ids = User::all()->pluck('id')->toArray();
// 所有分类 ID 数组,如:[1,2,3,4]
$category_ids = Category::all()->pluck('id')->toArray();
// 获取 Faker 实例
$faker = app(Faker\Generator::class);
$topics = factory(Topic::class)
->times(100)
->make()
->each(function ($topic, $index)
use ($user_ids, $category_ids, $faker)
{
// 从用户 ID 数组中随机取出一个并赋值
$topic->user_id = $faker->randomElement($user_ids);
// 话题分类,同上
$topic->category_id = $faker->randomElement($category_ids);
});
// 将数据集合转换为数组,并插入到数据库中
Topic::insert($topics->toArray());
}
}
vim database/seeds/DatabaseSeeder.php
<?php
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
public function run()
{
$this->call(UsersTableSeeder::class);
$this->call(TopicsTableSeeder::class);
}
}
php artisan migrate:refresh --seed
话题列表
路由
vim routes/web.php
<?php
use App\Models\Topic;
Route::get('/', function () {
return view('welcome');
});
Route::get('/topics', function () {
$topics = Topic::paginate(5);
return view('topics', compact('topics'));
});
视图
vim resources/views/topics.blade.php
<!doctype html>
<html lang="zh-CN">
<head>
<title>Topics</title>
</head>
<body>
@if (count($topics))
@foreach ($topics as $topic)
<div>
<div>
<a>{{ $topic->title }}</a>
</div>
<div>
<a>{{ $topic->category->name }}</a>
<a>{{ $topic->user->name }}</a>
</div>
</div>
<hr />
@endforeach
@else
<div>暂无数据</div>
@endif
</body>
</html>
测试
sudo sh -c "echo '192.168.10.10 clockwork.test' >> /etc/hosts"
浏览器打开http://clockwork.test/topics 效果如下
laravel-clockwork-01.png调试性能
对于后端渲染页面的架构 我们可以使用Laravel框架 之 debugbar中介绍的方法 那么对于SPA的前后端分离架构该如何调试性能呢?
答案 就是今天的主角clockwork
依赖
首先 添加Laravel项目的依赖
composer require itsgoingd/clockwork --dev
php artisan vendor:publish --provider="Clockwork\Support\Laravel\ClockworkServiceProvider"
vim config/clockwork.php
return [
'enabled' => env('APP_DEBUG', false),
];
接着 在Chrome浏览器中安装插件Chrome extension
关于其他浏览器的插件安装 可以参考Usage
调试
浏览器刷新http://clockwork.test/topics 效果如下
laravel-clockwork-02.png性能
通过clockwork获取的数据 可以得到两个非常有用的数据
查询次数 12 = 1 (话题总数) + 1 (话题列表) + 2 (分类和用户) * 5 (话题数量)
总共耗时 664ms
优化方法
那么 对于这类ORM关联数据引起的性能问题该如何解决呢?
通过Eloquent提供的预加载功能来解决ORM关联数据引起的性能问题
vim routes/web.php
<?php
use App\Models\Topic;
Route::get('/', function () {
return view('welcome');
});
Route::get('/topics', function () {
$topics = Topic::with('user', 'category')->paginate(5);
return view('topics', compact('topics'));
});
浏览器刷新http://clockwork.test/topics 效果如下
laravel-clockwork-03.png此时 性能数据如下
查询次数 4 = 1 (话题总数) + 1 (话题列表) + 1 (用户) + 1 (分类)
总共耗时 468ms
整体性能提高了约30% (664ms -> 468ms)
网友评论