1 回答

TA貢獻(xiàn)1886條經(jīng)驗(yàn) 獲得超2個(gè)贊
這個(gè)問題及其潛在的問題引起了我的興趣,所以我想了解更多關(guān)于整個(gè)問題的信息。我自己創(chuàng)建了一個(gè)測試場景。
優(yōu)化
首先對(duì)刀片模板的代碼進(jìn)行一些優(yōu)化:
// index.blade.php
<select>
? ? @include('categories.options', ['categories' => $categories, 'level' => 0])
</select>
// options.blade.php
@foreach ($categories as $category)
? ? <option value="{{ $category->id }}">{{ str_repeat("--", $level) }} {{ $category->name }}</option>
? ? @include('categories.options', ['categories' => $category->categories, 'level' => $level+1])
@endforeach
然后,我生成了一個(gè)包含大約 5000 個(gè)嵌套類別、8 層深度的數(shù)據(jù)庫,以測試加載時(shí)間。我的假設(shè)是,如果您向類別模型添加急切加載,則可以優(yōu)化加載時(shí)間:
// Category.php
// this eager loads ALL nested relations using levels + 1 queries
protected $with = ['categories'];
// this is not needed and doesn't make any difference
protected $with = ['categories.categories'];
結(jié)果如下:
? ? ? ? ? ? ? ? ? ? ? ?Time? Queries? Memory
--------------------------------------------------
? No eager loading? ?12,81 s? ? ?5101? ?112MB
with eager loading? ? 1,49 s? ? ? ? 9? ? 31MB
?2 x eager loading? ? 1,54 s? ? ? ? 9? ? 31MB
Caching? ? ? ? ? ? ? ?0,08 s? ? ? ? 0? ? ?4MB
(stats recorded mainly with debugbar)
正如您所看到的,急切加載絕對(duì)是有意義的。在模型中放入一個(gè)單一的關(guān)系也足夠了$with = ['categories'],laravel 將立即加載所有嵌套的關(guān)系 - 整潔!
緩存
因此,為了讓網(wǎng)站盡可能快地加載(我能想到的),唯一真正的解決方案是緩存。
// create new job in console
php artisan make:job RenderCategoryView
// RenderCategoryView.php
public function handle() {
? ? // get all top level categories
? ? $categories = \App\Category::where('category_id', null)->get();
? ? $html = \View::make('categories.options', ['categories' => $categories, 'level' => 0])->render();
? ? file_put_contents(resource_path('views/categories/options_cache.blade.php'), $html);
? ? return true;
}
@include現(xiàn)在您可以像這樣替換刀片模板:
// index.blade.php
@include('categories.options_cache')
要測試 options_cache 文件的生成,您可以執(zhí)行以下操作:
php artisan tinker
\App\Jobs\RenderCategoryView::dispatchNow();
我還在返回索引視圖之前刪除了現(xiàn)在不必要的數(shù)據(jù)庫查詢,新的加載時(shí)間為83 ms。這并不奇怪,因?yàn)楝F(xiàn)在所有內(nèi)容都被緩存了。
要在創(chuàng)建、編輯或刪除類別后自動(dòng)生成新的視圖緩存,您應(yīng)該將其包含在相應(yīng)的控制器中:
\App\Jobs\RenderCategoryView::dispatch();
- 1 回答
- 0 關(guān)注
- 126 瀏覽
添加回答
舉報(bào)