Ой, ничего не найдено!

К сожалению, по вашему запросу пока ничего нет (но это только пока!), зато вы можете подписаться на нашу замечательную email-рассылку, чтобы не пропустить самое интересное в будущем.

  • 313

7 уровней оптимизации Laravel: от новичка до мастера-фокусника

  • 3 минуты на чтение

Как сэкономить до 98% ресурсов, или как превратить простой Laravel-код в магию, которую мало кто осмелится трогать?

Готовьтесь: мы отправимся в увлекательное путешествие по ступеням оптимизации в Laravel. От наивного «лишь бы всё работало» до уверенного «коллеги либо назовут вас волшебником, либо обвинят в шаманстве». Поехали!

Уровень 1: Первый шаг — жадная загрузка (Eager Loading)

Всё начинается с классики. Вы только-только узнали, что такое with(), и чувствуете себя героем: никакого N+1, только два запроса — и все данные под рукой.

use App\Models\Post;
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
    $posts = Post::with('user')->get();
    return view('posts', ['posts' => $posts]);
});

Результат: Для 100k постов затрачиваем 191 МБ и примерно 0,63 сек. Итоговый «коэффициент ресурсоёмкости» — 120 единиц (условно). Неплохо, но не идеально.

Уровень 2: Первые серьёзные шаги — «А точно ли нужны все эти поля?»

Подключение за минуту
Попробуйте Siteko.net бесплатно в течение месяца
Проверьте хостинг на реальном сайте: скорость, стабильность и поддержка доступны сразу после подключения.
Начать бесплатно

Далее вы задумались: зачем вытаскивать всё подряд? Ограничьте выборку до нужных столбцов, и уже почувствуете разницу.

use App\Models\Post;
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
    $posts = Post::with('user:id,name')
                 ->select('id','user_id','title')
                 ->get();
    return view('posts', ['posts' => $posts]);
});

Результат: Минус 20% ресурсоёмкости. Конечно, вы ещё не спасли мир, но уже выглядите более профессионально.

Уровень 3: Переход на ручное управление — разделяем запросы

Теперь вы идёте дальше. Вместо жадной загрузки — два отдельных запроса: один для постов, другой для пользователей. В итоге вы создаёте своего рода таблицу соответствий.

use App\Models\Post;
use App\Models\User;
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
    $posts = Post::select('id','user_id','title')->get();
    $users = User::whereIn('id', $posts->pluck('user_id')->unique())
                 ->pluck('name', 'id');
    return view('posts', ['posts' => $posts, 'users' => $users]);
});

Результат: Ещё +15% эффективности. Вы уже пьёте кофе с лёгкой улыбкой превосходства.

Уровень 4: Попытка хитрить с distinct

Подключение за минуту
Попробуйте Siteko.net бесплатно в течение месяца
Проверьте хостинг на реальном сайте: скорость, стабильность и поддержка доступны сразу после подключения.
Начать бесплатно

Вы пытаетесь доверить часть оптимизации базе данных: пусть она сама выберет уникальные значения user_id. Результаты? Есть прирост по времени, но с памятью особого выигрыша нет.

use App\Models\Post;
use App\Models\User;
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
    $query = Post::query();
    $posts = (clone $query)->select('id', 'user_id', 'title')->get();
    $users = User::whereIn('id', (clone $query)->select('user_id')->distinct())
                 ->get();
    return view('posts', ['posts' => $posts, 'users' => $users]);
});

Результат: Быстрее, но ощутимого облегчения памяти нет. Что ж, оптимизация — это путь проб и ошибок.

Уровень 5: Скрытая магия — toBase()

Вы обнаружили toBase(), который пропускает всю «магию» Eloquent, оставляя только «чистые» результаты. И вот тут начинается серьёзный прорыв.

use App\Models\Post;
use App\Models\User;
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
    $query = Post::query();
    $posts = (clone $query)->select('id','user_id','title')
                           ->toBase()
                           ->get();
    $users = User::whereIn('id', (clone $query)->select('user_id')->distinct())
                 ->toBase()
                 ->get();
    return view('posts', ['posts' => $posts, 'users' => $users]);
});

Результат: Минус 85% ресурсоёмкости. Теперь вы чувствуете себя настоящим гуру Laravel.

Уровень 6: Ещё шаг — chunkById

Первый месяц за 0 рублей
Хостинг для сайта, который должен работать стабильно
Перенесите проект или запустите новый сайт на Siteko.net и протестируйте сервис без предоплаты.
Перейти к хостингу

Время применить «чанкование». Вы загружаете данные порционно и аккуратно складываете их в коллекцию. К примеру, по 15 000 записей.

use App\Models\Post;
use App\Models\User;
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
    $query = Post::query();
    $posts = collect();
    (clone $query)->select('id', 'user_id', 'title')
                  ->toBase()
                  ->orderBy('posts.id')
                  ->chunkById(15000, function ($collection) use (&$posts) {
                      $posts->push(...$collection);
                  }, 'id');
    $users = User::whereIn('id', (clone $query)->select('user_id')->distinct())
                 ->toBase()
                 ->get();
    return view('posts', ['posts' => $posts, 'users' => $users]);
});

Результат: Ещё плюс 14% к оптимизации. Кажется, вы уже приблизились к пределу.

Уровень 7: Высший пилотаж — Lazy Collections

Финальный козырь в рукаве — lazyById(). Представьте себе chunkById, но более «ленивый» и гибкий. Вы загружаете данные партиями (например, по 10 000), удерживая их в памяти по мере необходимости.

use App\Models\Post;
use App\Models\User;
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
    $query = Post::query();
    $users = User::whereIn('id', (clone $query)->select('user_id')->distinct())
                 ->pluck('name', 'id');
    $posts = (clone $query)
                 ->select('id', 'user_id', 'title')
                 ->toBase()
                 ->lazyById(10000, 'id');
    return view('welcome', [
        'posts' => $posts,
        'users' => $users,
    ]);
});

Результат: Память используется ещё более экономно. Вы стоите на вершине горы оптимизации, смотрите свысока на затраты ресурсов и понимаете, что сократили их примерно на 98% (с 120 до 2,4). Ваши коллеги в шоке — либо восхищены, либо озадачены тем, что вы сотворили.

Итог:

1 месяц бесплатно
Запустите сайт на Siteko.net без стартовых затрат
Быстрый хостинг, понятная панель и поддержка рядом с первого дня. Тестовый месяц доступен сразу после выбора тарифа.
Выбрать хостинг

Вы прошли путь от новичка, довольствующегося eager loading, до мастера, выжимающего из Laravel максимум. Но не забывайте, с чего вы начинали. И не удивляйтесь, если через секунду ваш начальник влетит с вопросом: «А как там прогресс по остальным задачам?» Вы сэкономили серверные ресурсы — но кто сэкономит ваше время теперь?

Хостинг Siteko

Первый месяц бесплатно

Хостинг Siteko.net для стабильного запуска сайта

Разместите проект на Siteko.net и проверьте скорость, панель управления и поддержку без стартовой оплаты.

  • 1 месяц бесплатно для новых клиентов сразу после выбора тарифа.
  • Быстрый старт для лендинга, блога или корпоративного сайта.
  • Поддержка рядом поможет с переносом и настройкой проекта.
Выбрать тариф