Я получаю свой Symfony API на React, и получение и отображение данных занимает 2 секунды, хотя там всего 3 строки.
Как я могу оптимизировать время?
видео: https://imgur.com/a/iGaFW0L
Во время записи видео это занимает чуть больше времени, так оно и есть, но чуть быстрее
API Symfony
#[Route('/api/projects', methods: ['GET'], name: 'project_get')]
public function getProjects(ProjectRepository $projectRepository): JsonResponse
{
return $this->json(
[
"status" => 200,
"success" => true,
"data" => $projectRepository->findAll(),
"message" => "Operation completed with success"
],
Response::HTTP_OK, [], ['groups' => 'getProjects']
);
}
Получить на React
useEffect(() => {
fetch("https://localhost:8000/api/projects")
.then((res) => res.json())
.then((projects) => {
console.info("projects",projects.data);
setProjectsFromApi(projects.data);
setLoading(false);
})
}, [])
Если я заменю данные пустым массивом
#[Route('/api/projects', methods: ['GET'], name: 'project_get')]
public function getProjects(ProjectRepository $projectRepository): JsonResponse
{
return $this->json(
[
"status" => 200,
"success" => true,
"data" => [],
"message" => "Operation completed with success"
],
Response::HTTP_OK, [], ['groups' => 'getProjects']
);
}
Для сравнения у меня есть Nodejs API, который намного быстрее, и строк там не намного меньше.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы можете попробовать не сериализовать целые объекты, а точно указать, какие элементы объекта должны быть сериализованы. В конце концов, это лучшая практика. Сериализация сущностей, особенно тех, у которых есть отношения (в вашем случае, я полагаю, это сущность Project), может привести к низкой производительности или бесконечной рекурсии.
Теперь, как вы можете контролировать, какие атрибуты сериализовать? Самый быстрый вариант — просто просмотреть проекты, возвращенные вашим репозиторием, и выбрать, как должен выглядеть окончательный ответ. Фрагмент ниже содержит несколько советов о том, как это сделать.
$projects = $this->projectRepository->findAll();
$response = array_map(
fn (Project $project) => [
'id' => $project->getId(),
'name' => $project->getName(),
'content' => $project->getContent(),
'frameworks' => $project->getFrameworks()->map(
fn (Framework $framework) => [
'id' => $framework->getId(),
'name' => $framework->getName(),
]
)->toArray(),
],
$projects
);
Затем просто передайте ответ в свой атрибут данных в формате JSON. Только убедитесь, что не включаете отношения доктрин.
Если это улучшит производительность, вам следует взглянуть на Symfony Serializer и, возможно, на некоторые DTO, чтобы вы могли контролировать, как выглядят ваши ответы, и точно контролировать, как выполняется сопоставление.
Если вы хотите еще больше оптимизировать производительность, вы можете написать собственный запрос для получения проектов и их инфраструктуры в одном запросе. Как вы можете видеть в своем примере, отношения загружаются прокси-серверами Doctrine, которые по умолчанию являются ленивыми. Это означает, что отношение не загружается до тех пор, пока оно не понадобится. Это также может снизить производительность и привести к печально известной проблеме запроса N+1.
С этим кодом
#[Route('/api/projects', methods: ['GET'], name: 'project_get')]
public function getProjects(ProjectRepository $projectRepository): JsonResponse
{
$projects = $projectRepository->findAll();
$response = array_map(
fn (Project $project) => [
'id' => $project->getId(),
'title' => $project->getTitle(),
'content' => $project->getContent(),
'frameworks' => $project->getFrameworks()->map(
fn (Framework $framework) => [
'id' => $framework->getId(),
'name' => $framework->getName(),
]
),
'languages' => $project->getLanguages()->map(
fn (Language $language) => [
'id' => $language->getId(),
'name' => $language->getName(),
]
)
->toArray(),
],
$projects
);
return $this->json(
[
"status" => 200,
"success" => true,
"data" => $response,
"message" => "Operation completed with success"
],
Response::HTTP_OK
);
}
Это намного быстрее
Хотя этот код может ответить на вопрос, я рекомендую вам также объяснить, что делает ваш код и как он решает проблему вопроса. Ответы с пояснениями обычно более полезны, качественны и с большей вероятностью соберут голоса «за».
Рад, что это помогло, хотя за него проголосовали против :) Именно так работает эта платформа. Взгляните на компонент сериализатора и DTO, чтобы вам не нужно было определять сопоставление в контроллере, а лучше использовать сам DTO или создавать для него Mapper. Я также предлагаю вам взглянуть на компонент Serializer. Желаем удачи в вашем путешествии по Symfony.