Witam,
Robie projekt w Laravel 7 oraz z wykorzystaniem: https://packagist.org/packages/kalnoy/nestedset.
Mam skrypt który wyświetla mi dane dla jstree https://www.jstree.com
Mam następujący kod kategorii:
Schema::create('categories', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('category_name', 155);
$table->string('description', 155)->nullable();
$table->string('keywords', 155)->nullable();
$table->longText('content')->nullable();
$table->char('enable', 1)->default(0);
$table->string('photo', 155)->nullable();
$table->bigInteger('order')->default(0);
$table->string('slug', 160)->nullable();
NestedSet::columns($table);
$table->engine = "InnoDB";
$table->charset = 'utf8mb4';
$table->collation = 'utf8mb4_unicode_ci';
});
use App\Traits\ScopeActiveTrait;
use Illuminate\Database\Eloquent\Model;
use Kalnoy\Nestedset\NodeTrait;
use Spatie\Sluggable\HasSlug;
use Spatie\Sluggable\SlugOptions;
class Category extends Model
{
use ScopeActiveTrait;
use NodeTrait;
use HasSlug;
/**
* Get the options for generating the slug.
*/
public function getSlugOptions() : SlugOptions
{
return SlugOptions::create()
->generateSlugsFrom('category_name')
->slugsShouldBeNoLongerThan(160)
->saveSlugsTo('slug');
}
protected $guarded = ['id'];
protected $fillable = ['category_name', 'description', 'keywords', 'content', 'enable', 'photo', 'order', 'slug', '_lft', '_rgt', 'parent_id'];
public $timestamps = false;
}
Kategorii mam ok 170000 rekordów.
Generuje kod dla mojego jstree za pomocą:
public function categoryTree(Category $category, SelectedProductCategory $selectedProductCategory, Request $request)
{
$tree = Cache::remember('categories', 31536000, function () use ($category) {
return $category->active()->get();
});
$nodes = $this->generateJsTree($tree->toTree(), ($request->exists('id')) ? $selectedProductCategory->where('product_id', $request->input('id'))->orderBy('id', 'ASC')->get() : null);
return $nodes;
}
private function generateJsTree($nodes, $selectedCategories): array
{
$categoryArray = array();
$traverse = function ($categories, $prefix = '-') use (&$traverse, &$categoryArray, $selectedCategories) {
foreach ($categories as $category) {
$selected = false;
if (!is_null($selectedCategories)) {
$selected = $selectedCategories->contains('category_id', $category->id) ? true : false;
}
$categoryArray[] = ['id' => $category->id, 'text' => $category->category_name, 'parent' => $category->parent_id ?? '#', 'state' => ['opened' => false, 'selected' => $selected]];
$traverse($category->children, $prefix . '-');
}
};
$traverse($nodes);
return $categoryArray;
}
(zakładam aktualizację cache raz na rok)
SelectedProductCategory = zaznaczone kategorie
class SelectedProductCategory extends Model
{
protected $fillable = ['product_id', 'category_id'];
protected $guarded = ['id'];
}
Schema::create('selected_product_categories', function (Blueprint $table) {
$table->id();
$table->bigInteger('product_id')->unsigned()->default(0);
$table->foreign('product_id')->references('id')->on('products')->onDelete('cascade');
$table->bigInteger('category_id')->unsigned()->default(0);
$table->foreign('category_id')->references('id')->on('categories')->onDelete('cascade');
$table->timestamps();
});
Problem w tym że skrypt generuje się 2 minuty, zarówno na serwerze jak i na lokalnym komputerze :( Plik z cache zajmuje ok 300MB. Co dziwne zarówno jak mam plik z cache, jak i bez niego - skrypt zawsze długo się generuje.
W jaki sposób można to zoptymalizować?