Mam zagwozdkę. Mam stronę wykorzystującą https://www.jstree.com oraz Laravel 7 z wykorzystaniem https://packagist.org/packages/kalnoy/nestedset
Mam tabelę z kategoriami (164574 rekordów) - która zajmuje około 22,3 MB (po zrzucie z phpmyadmin). Kategorie są praktycznie niezmienne.
Mój model i migracja wyglądają następująco:
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; } 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'; });
Założenie:
1. wyświetlić drzewko kategorii
2. zaznaczyć na drzewku wybrane kategorie
Do zapisu wybranych kategorii mam:
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(); }); class SelectedProductCategory extends Model { protected $fillable = ['product_id', 'category_id']; protected $guarded = ['id']; }
Mój kod do wyświetlania wygląda następująco:
<div id="ajax" class="ajax"></div> <script> $(function () { $('#ajax').jstree({ "checkbox": { "keep_selected_style": false }, "plugins": [ "checkbox", ], 'core': { 'data': { "url": "domain.com/products/categoryTree", "dataType": "json" } } }).on('changed.jstree', function (e, data) { var checked_ids = []; var selectedNodes = $('#ajax').jstree("get_selected", true); checked_ids.push(this.id); }); $('.categoryTree').val(checked_ids); }); }); </script> public function categoryTree(Category $category, SelectedProductCategory $selectedProductCategory, Request $request) { $tree = Cache::remember('categories', 31536000, function () use ($category) { return $category->select(['id', 'category_name', 'parent_id', 'order', '_lft', '_rgt'])->active()->orderBy('order', 'ASC')->get(); }); $nodes = $this->generateJsTree($tree->toTree(), ($request->exists('id')) ? $selectedProductCategory->where('product_id', $request->input('id'))->orderBy('id', 'ASC')->get() : null); return $nodes; } { $traverse = function ($categories, $prefix = '-') use (&$traverse, &$categoryArray, $selectedCategories) { foreach ($categories as $category) { $selected = false; $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; }
Skrypt generuje mi plik z cache (~250MB) na serwerze, jednak drzewko wyświetla się baaaardzo wolno (po 3-5min).
W momencie gdy wkleję link z html do przeglądarki: domain.com/products/categoryTree to wygenerowanie danych zajmuje mu parę minut.
Co może być przyczyną takiego długiego wczytywania?
Co można lepiej zoptymalizować? Bardzo proszę o pomoc
