Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [PHP]Jak zoptymalizować wyświetlanie kategorii w Laravel 7?
trifek
post 8.08.2020, 11:57:19
Post #1





Grupa: Zarejestrowani
Postów: 340
Pomógł: 0
Dołączył: 28.09.2015

Ostrzeżenie: (0%)
-----


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:


  1. Schema::create('categories', function (Blueprint $table) {
  2. $table->bigIncrements('id');
  3. $table->string('category_name', 155);
  4. $table->string('description', 155)->nullable();
  5. $table->string('keywords', 155)->nullable();
  6. $table->longText('content')->nullable();
  7. $table->char('enable', 1)->default(0);
  8. $table->string('photo', 155)->nullable();
  9. $table->bigInteger('order')->default(0);
  10. $table->string('slug', 160)->nullable();
  11. NestedSet::columns($table);
  12. $table->engine = "InnoDB";
  13. $table->charset = 'utf8mb4';
  14. $table->collation = 'utf8mb4_unicode_ci';
  15. });
  16.  
  17.  
  18.  
  19. use App\Traits\ScopeActiveTrait;
  20. use Illuminate\Database\Eloquent\Model;
  21. use Kalnoy\Nestedset\NodeTrait;
  22. use Spatie\Sluggable\HasSlug;
  23. use Spatie\Sluggable\SlugOptions;
  24.  
  25. class Category extends Model
  26. {
  27. use ScopeActiveTrait;
  28. use NodeTrait;
  29. use HasSlug;
  30.  
  31. /**
  32.   * Get the options for generating the slug.
  33.   */
  34. public function getSlugOptions() : SlugOptions
  35. {
  36. return SlugOptions::create()
  37. ->generateSlugsFrom('category_name')
  38. ->slugsShouldBeNoLongerThan(160)
  39. ->saveSlugsTo('slug');
  40. }
  41.  
  42. protected $guarded = ['id'];
  43. protected $fillable = ['category_name', 'description', 'keywords', 'content', 'enable', 'photo', 'order', 'slug', '_lft', '_rgt', 'parent_id'];
  44. public $timestamps = false;
  45.  
  46. }


Kategorii mam ok 170000 rekordów.



Generuje kod dla mojego jstree za pomocą:

  1. public function categoryTree(Category $category, SelectedProductCategory $selectedProductCategory, Request $request)
  2. {
  3. $tree = Cache::remember('categories', 31536000, function () use ($category) {
  4. return $category->active()->get();
  5. });
  6.  
  7. $nodes = $this->generateJsTree($tree->toTree(), ($request->exists('id')) ? $selectedProductCategory->where('product_id', $request->input('id'))->orderBy('id', 'ASC')->get() : null);
  8. return $nodes;
  9. }
  10.  
  11. private function generateJsTree($nodes, $selectedCategories): array
  12. {
  13. $categoryArray = array();
  14. $traverse = function ($categories, $prefix = '-') use (&$traverse, &$categoryArray, $selectedCategories) {
  15. foreach ($categories as $category) {
  16. $selected = false;
  17. if (!is_null($selectedCategories)) {
  18. $selected = $selectedCategories->contains('category_id', $category->id) ? true : false;
  19. }
  20.  
  21. $categoryArray[] = ['id' => $category->id, 'text' => $category->category_name, 'parent' => $category->parent_id questionmark.gif '#', 'state' => ['opened' => false, 'selected' => $selected]];
  22. $traverse($category->children, $prefix . '-');
  23. }
  24. };
  25. $traverse($nodes);
  26. return $categoryArray;
  27. }


(zakładam aktualizację cache raz na rok)



SelectedProductCategory = zaznaczone kategorie


  1. class SelectedProductCategory extends Model
  2. {
  3. protected $fillable = ['product_id', 'category_id'];
  4. protected $guarded = ['id'];
  5. }
  6.  
  7. Schema::create('selected_product_categories', function (Blueprint $table) {
  8. $table->id();
  9. $table->bigInteger('product_id')->unsigned()->default(0);
  10. $table->foreign('product_id')->references('id')->on('products')->onDelete('cascade');
  11. $table->bigInteger('category_id')->unsigned()->default(0);
  12. $table->foreign('category_id')->references('id')->on('categories')->onDelete('cascade');
  13. $table->timestamps();
  14. });
  15.  




Problem w tym że skrypt generuje się 2 minuty, zarówno na serwerze jak i na lokalnym komputerze sad.gif 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ć?
Go to the top of the page
+Quote Post
Pyton_000
post 8.08.2020, 12:57:42
Post #2





Grupa: Zarejestrowani
Postów: 8 068
Pomógł: 1414
Dołączył: 26.10.2005

Ostrzeżenie: (0%)
-----


Generowanie na raz takiej porcji danych to zły pomysł. Użyj Ajax, załaduj kategorie root a potem doczuytuj sobie dynamicznie kolejne poziomy
Go to the top of the page
+Quote Post
SmokAnalog
post 9.08.2020, 00:15:10
Post #3





Grupa: Zarejestrowani
Postów: 1 707
Pomógł: 266
Dołączył: 3.07.2012
Skąd: Poznań

Ostrzeżenie: (0%)
-----


jsTree nawet wspiera Ajax, więc nie musisz zbyt dużo kombinować. Masz bardzo dużo tych kategorii. Tak jak Pyton napisał, pozostaje Ci wczytywać je porcjami. przy odpowiednio zindeksowanej bazie, a zakładam, że ta paczka do Laravela odpowiednio definiuje indeksy dla kolumn, wyszukiwanie danych po ID rodzica będzie błyskawiczne.

Jeśli chcesz się bawić w optymalizację, to możesz np. rozważyć doczytywanie wszystkich kategorii potomnych danego poziomu już w momencie rozwijania dowolnej kategorii z poziomu wyżej, czyli np. jak Twoje drzewko wygląda tak:

Kod
- Jedzenie
--Owoce
---Jabłka
----Zielone
----Czerwone
---Banany
---Owoce leśne
--Warzywa
itd.


W momencie, załadowania strony mógłbyś już mieć wczytane wszystkie kategorie drugiego poziomu, czyli Owoce i Warzywa. Gdy ktoś kliknie Jedzenie, mógłbyś wczytać kategorie trzeciego poziomu, czyli Jabłka, Banany i Owoce Leśne. Gdy ktoś wybierze Owoce, wczytujesz już Zielone i Czerwone dla jabłek itd. Innymi słowy, wyprzedzasz zawsze o jeden poziom. W ten sposób w większości przypadków osiągniesz płynność interfejsu na poziomie aplikacji desktopowej, bo klikanie w poszczególne kategorie zajmie pewnie co najmniej sekundę. Taki podsuwam pomysł, choć i bez tego będzie przyzwoicie.
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 19.04.2024 - 00:41