Berriart Berriart

Desarrollo web con software libre

Añadir javascripts al final del código con Symfony

Guardar este artículo en Delicious Compartir este artículo en Twitter Compartir este artículo en Facebook

Uno de los consejos que se suelen dar para mejorar el tiempo de carga de una web es añadir el Javascript al final de un documento web, justo antes de la etiqueta </body>. Últimamente trabajo bastante con Symfony y por defecto los Javascript que se incluyen en los ficheros view.yml se cargan en la cabecera del documento (justo antes de la etiqueta </head>). Por eso generalmente hago algunas modificaciones para cambiar esto y ponerlos al final.

Esa inclusión se realiza en el filtro sfCommonFilter, por lo tanto lo primero es crear un filtro que sustituirá a ese y que colocará los javascripts donde nosotros queremos, al final. Lo incluiremos en la carpeta libs/filters y en este caso se llamara myProjectCommonFilter:

<?php
/**
* myProjectCommonFilter Helper
*
* myProjectCommonFilter automatically adds javascripts to the bottom of the page and stylesheets to the top in the sfResponse content.
* This class is based in the sfCommonFilter helper of the symfony package.
*
* @package    symfony
* @subpackage filter
* @author     Alberto Varela <alberto@berriart.com>
* @version    2010-07-07
*/
class myProjectCommonFilter extends sfFilter
{
  /**
  * Executes this filter.
  *
  * @param sfFilterChain $filterChain A sfFilterChain instance
  */
  public function execute($filterChain)
  {
    // execute next filter
    $filterChain->execute();

    // execute this filter only once
    $response = $this->context->getResponse();

    // include stylesheets
    $content = $response->getContent();
    if (false !== ($pos = strpos($content, '</head>')))
    {
      $this->context->getConfiguration()->loadHelpers(array('Tag', 'Asset'));

      if (!sfConfig::get('symfony.asset.stylesheets_included', false))
      {
        $html .= get_stylesheets($response);
      }

      if ($html)
      {
        $response->setContent(substr($content, 0, $pos).$html.substr($content, $pos));
      }
    }

    // include javascripts
    $content = $response->getContent();
    if (false !== ($pos = strpos($content, '</body>')))
    {
      $this->context->getConfiguration()->loadHelpers(array('Tag', 'Asset'));
      $html = '';
      if (!sfConfig::get('symfony.asset.javascripts_included', false))
      {
        $html .= get_javascripts($response);
      }

      if ($html)
      {
        $response->setContent(substr($content, 0, $pos).$html.substr($content, $pos));
      }
    }

    sfConfig::set('symfony.asset.javascripts_included', false);
    sfConfig::set('symfony.asset.stylesheets_included', false);
  }
}

Ahora solo tenemos que decirle a Symfony que queremos utilizar este nuevo filtro en vez del sfCommonFilter y para eso tenemos que modificar el fichero config/filters.yml de nuestra aplicación y cambiar el filtro common:

common:
  class: myProjectCommonFilter

En un principio eso es todo, pero debéis tener cuidado si también escribís código Javascript directamente en la página sin usar ficheros externos. Tened en cuenta que siempre que ese código ‘inline’ necesite utilizar alguna de las librerías externas deberá estar escrito por debajo de las llamadas a éstas y por lo tanto tendréis que modificar el filtro que os he puesto más arriba.

1 Comentario
  1. Sergio Flores

    Hola.

    Y si en vez de hacer eso no simplemente modificas el layout bajando la línea “include_javascripts”?

    Saludos!

Deja un comentario