Я создаю приложение Symfony, и когда я работаю над ним, оно работает слишком медленно. Мне интересно, что может быть причиной этого, поэтому я пошел в хронологию профилировщика, чтобы увидеть, что происходит, но я был поражен, что все эти классы имеют очень большие данные 10 МБ, 22 МБ и так далее. Смотрите картинку:
Это моя связка объектов. Желтый — мой собственный класс с моими ветками. Я не понимаю, что это за задержка и что это за большие данные …. Может кто-нибудь объяснить мне, что происходит и как это можно оптимизировать, потому что на производстве, если это так, как сейчас, это слишком медленно … Итого время 3962 мс
Вот контроллер — ничего необычного из консоли генерировать с небольшими изменениями:
<?php
namespace George\ObjectsBundle\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use George\ObjectsBundle\Entity\Object;
use George\ObjectsBundle\Form\ObjectType;
/**
* Object controller.
*
* @Route("/admin/object")
*/
class ObjectController extends Controller
{
/**
* Lists all Object entities.
*
* @Route("/", name="object")
* @Method("GET")
* @Template()
*/
public function indexAction(Request $request)
{
$session = $request->getSession();
$locale = $request->getLocale();
$em = $this->getDoctrine()->getManager();
$entities = $em->getRepository('ObjectsBundle:Object')->findAll();
// echo $locale;
/*
$category = new Object();
$category->translate('bg')->setTitle('Chaussures');
$category->translate('en')->setTitle('Shoes');
$category->translate('bg')->setDescription('Chaussures');
$category->translate('en')->setDescription('Shoes');
$category->translate('bg')->setAddress('Chaussures');
$category->translate('en')->setAddress('Shoes');
$category->setMode('a');
$category->setLat('12');
$category->setLongt('12');
echo $category->translate('bg')->getTitle();
$category->mergeNewTranslations(); $em->persist($category);
$em->flush();
*/
return array(
'entities' => $entities,
);
}
/**
* Creates a new Object entity.
*
* @Route("/", name="object_create")
* @Method("POST")
* @Template("ObjectsBundle:Object:new.html.twig")
*/
public function createAction(Request $request)
{
$entity = new Object();
$form = $this->createCreateForm($entity);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('object'));
}
return array(
'entity' => $entity,
'form' => $form->createView(),
);
}
/**
* Creates a form to create a Object entity.
*
* @param Object $entity The entity
*
* @return \Symfony\Component\Form\Form The form
*/
private function createCreateForm(Object $entity)
{
$form = $this->createForm(new ObjectType(), $entity, array(
'action' => $this->generateUrl('object_create'),
'method' => 'POST',
));
$form->add('submit', 'submit', array('label' => 'Create'));
return $form;
}
/**
* Displays a form to create a new Object entity.
*
* @Route("/new", name="object_new")
* @Method("GET")
* @Template()
*/
public function newAction()
{
$entity = new Object();
$form = $this->createCreateForm($entity);
return array(
'entity' => $entity,
'form' => $form->createView(),
);
}
/**
* Finds and displays a Object entity.
*
* @Route("/{id}", name="object_show")
* @Method("GET")
* @Template()
*/
public function showAction($id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('ObjectsBundle:Object')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Object entity.');
}
$deleteForm = $this->createDeleteForm($id);
return array(
'entity' => $entity,
'delete_form' => $deleteForm->createView(),
);
}
/**
* Displays a form to edit an existing Object entity.
*
* @Route("/{id}/edit", name="object_edit")
* @Method("GET")
* @Template()
*/
public function editAction($id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('ObjectsBundle:Object')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Object entity.');
}
$editForm = $this->createEditForm($entity);
$deleteForm = $this->createDeleteForm($id);
return array(
'entity' => $entity,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
);
}
/**
* Creates a form to edit a Object entity.
*
* @param Object $entity The entity
*
* @return \Symfony\Component\Form\Form The form
*/
private function createEditForm(Object $entity)
{
$form = $this->createForm(new ObjectType(), $entity, array(
'action' => $this->generateUrl('object_update', array('id' => $entity->getId())),
'method' => 'PUT',
));
$form->add('submit', 'submit', array('label' => 'Update'));
return $form;
}
/**
* Edits an existing Object entity.
*
* @Route("/{id}", name="object_update")
* @Method("PUT")
* @Template("ObjectsBundle:Object:edit.html.twig")
*/
public function updateAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('ObjectsBundle:Object')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Object entity.');
}
$deleteForm = $this->createDeleteForm($id);
$editForm = $this->createEditForm($entity);
$editForm->handleRequest($request);
if ($editForm->isValid()) {
$em->flush();
return $this->redirect($this->generateUrl('object_edit', array('id' => $id)));
}
return array(
'entity' => $entity,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
);
}
/**
* Deletes a Object entity.
*
* @Route("/{id}", name="object_delete")
* @Method("DELETE")
*/
public function deleteAction(Request $request, $id)
{
$form = $this->createDeleteForm($id);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('ObjectsBundle:Object')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Object entity.');
}
$em->remove($entity);
$em->flush();
}
return $this->redirect($this->generateUrl('object'));
}
/**
* Creates a form to delete a Object entity by id.
*
* @param mixed $id The entity id
*
* @return \Symfony\Component\Form\Form The form
*/
private function createDeleteForm($id)
{
return $this->createFormBuilder()
->setAction($this->generateUrl('object_delete', array('id' => $id)))
->setMethod('DELETE')
->add('submit', 'submit', array('label' => 'Delete'))
->getForm();
}
}
Основная ветка для админа:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
{% block title -%}<title>Admin</title>{% endblock %}
{% block stylesheets %}
{% stylesheets
'@CoreBundle/Resources/public/css/*' %}
<link href="{{ asset(asset_url) }}" rel="stylesheet">
{% endstylesheets %}
{% endblock %}
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
</head>
<body>
{% block menu -%} {% endblock %}
{% block body -%} {% endblock %}
{% block javascripts -%}
{% javascripts
'@CoreBundle/Resources/public/js/jquery-1.11.3.min.js'
'@CoreBundle/Resources/public/js/bootstrap.min.js'
'@CoreBundle/Resources/public/js/fine-uploader.min.js'
'@CoreBundle/Resources/public/js/jquery-ui.min.js'
'@CoreBundle/Resources/public/js/datatables.min.js'
'@CoreBundle/Resources/public/js/Buttons-1.1.0/js/dataTables.buttons.min.js'
'@CoreBundle/Resources/public/js/Buttons-1.1.0/js/buttons.html5.js'
'@CoreBundle/Resources/public/js/Buttons-1.1.0/js/buttons.bootstrap.min.js'
'@CoreBundle/Resources/public/js/JSZip-2.5.0/jszip.min.js'
'@CoreBundle/Resources/public/js/RowReorder-1.1.0/js/dataTables.rowReorder.min.js'
%}
<script src="{{ asset(asset_url) }}" type="text/javascript"></script>
{% endjavascripts %}
{% endblock %}
{% block readyjs -%}
{{ tinymce_init() }}
<script type="text/javascript" >
function post_order ( ord, url)
{
$.ajax({
method: "POST",
url: url,
data: { elem: ord }
})
.done(function( msg ) {
// alert( msg );
});
}
$(document).ready(function () {
var optionsDatatables = {
dom: 'Bfrtip',
buttons: [
'copyHtml5', 'excelHtml5', 'csvHtml5'
]
}
if($('#dattab').hasClass('allow-order'))
{
//if we want more properties
// optionsDatatables.rowReorder = {
//selector: 'tr',
// update: true,
// dataSrc: '.ord-id'
// }
optionsDatatables.rowReorder = true;
}
var table = $('#dattab').DataTable(optionsDatatables);
var order;
if($('#dattab').hasClass('allow-order')) {
$('#dattab').on('draw.dt', function () {
var rows = table.rows().data();
var ord = new Array();
for (var i = 0, ien = rows.length; i < ien; i++) {
ord[i] = rows[i].DT_RowId;
}
order = ord;
$('#save_sort').fadeIn();
});
}
$('#save_sort').click(function(){
console.log(order);
post_order(order,$('#dattab').data('url'));
$(this).fadeOut();
});
});
</script>
{% endblock %}
</body>
</html>
Индекс, который расширяет базу
{% extends "CoreBundle::admin_inner.html.twig" %}
{% block body -%}
<div class="container">
<div class="row">
<div class="col-xs-12">
{#{{ app.request.locale }}#}
<h1>Object list</h1>
{% for locale in ['en', 'bg'] %}
<li>
<a href="{{ path(app.request.get('_route'), app.request.get('_route_params')| merge({'_locale' : locale})) }}">
{{ locale }}
</a>
</li>
{% endfor %}
{{ app.session.get('_locale') }}{#
{{ app.request.locale }}#}
<div class="table-responsive">
<table class="table table-hover table-bordered" id="dattab">
<thead>
<tr>
<th>Id</th>
<th>Title</th>
<th>Description</th>
<th>Mode</th>
<th>Lat</th>
<th>Longt</th>
<th>Address</th>
<th>Created</th>
<th>Updated</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for entity in entities %}
<tr>
<td>{{ loop.index }}</td>
<td>{{ entity.translate(app.session.get('_locale')).title }} </td>
<td>{{ entity.translate(app.session.get('_locale')).description }} </td>
<td>{{ entity.mode }}</td>
<td>{{ entity.lat }}</td>
<td>{{ entity.longt }}</td>
<td>{{ entity.translate(app.session.get('_locale')).address }}</td>
<td>{% if entity.created %}{{ entity.created|date('Y-m-d H:i:s') }}{% endif %}</td>
<td>{% if entity.updated %}{{ entity.updated|date('Y-m-d H:i:s') }}{% endif %}</td>
<td>
<a href="{{ path('object_edit', { 'id': entity.id }) }}"class="btn btn-primary"> <span class="glyphicon glyphicon-edit"aria-hidden="true"></span> Edit</a>
<a href="{{ path('admin_floor', { 'id': entity.id }) }}"class="btn btn-info"> <span class="glyphicon glyphicon-edit"aria-hidden="true"></span> Floors</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<ul>
<li>
<a href="{{ path('object_new') }}">
Create a new entry
</a>
</li>
</ul>
</div>
</div>
</div>
{% endblock %}
И внутренний с меню:
{% extends "CoreBundle::admin_base.html.twig" %}
{% block menu %}
{{ include('CoreBundle::menu.html.twig') }}
{% endblock %}
Сначала я бы проверил, все ли ресурсы вашего веб-интерфейса загружаются правильно (скрипты, изображения, CSS).
Это может значительно замедлить ваше приложение.
Вы можете проверить это в Firebug или консоли разработчика.
Других решений пока нет …