Wyświetlanie kategorii z użyciem cache w Laravel - optymalizacja

0

Witajcie.
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);
                $.each(selectedNodes, function () {
                    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;

    }


    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;
    }


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 :)

0

Jesśli tyle zajmuje to tyle zajmuje, na potrzeby testu to ok ale nikt normalny nie wyswietla tyle kategorii na stronie. Wiadomo ze wyswietlasz glowne i po kliknieciu lub rozwinieciu doczytujesz kolejne.

1 użytkowników online, w tym zalogowanych: 0, gości: 1