CSS przodem, JavaScript tyłem

Ten wpis został napisany dawno temu i może być już nieaktualny.

Załączanie arkuszy styli CSS na górze strony, a skryptów JavaScript jak najpóźniej to tylko dwie z 34 dobrych praktyk opisanych przez Yahoo w Best Practices for Speeding Up Your Website. Stosowanie się do nich pozwoli zmniejszyć wizualnie czas generowania strony w przeglądarce. Oto prosty przykład jak to osiągnąć w symfony. Za każdym razem gdy używamy funkcji pomocniczych use_javascript i use_stylesheet, skrypty i pliki CSS nie są od razu dodawane do kodu html strony. Za to zadanie odpowiedzialny jest filtr sfCommonFilter, który je wstrzykuje na końcu sekcji head (chwilę przed elementem ). Dzięki temu każdy plik jest dodawany tylko raz i wszystkie są w jednym miejscu. Filtr możemy jednak nieco usprawnić porzez zastosowanie się do opisanych we wstępie zaleceń Yahoo. Pliki CSS są już załączane na początku. Musimy tylko przenieść skrypty JavaScript na spód strony (chwilę przed tagiem ).  Aby to osągnąć wystarczy nadpisać klasę sfCommonFilter. Zmiany nie są poważne, użyłem oryginalnego kodu i lekko zmieniłem sposób w jaki skrypty są wstrzykiwane.

class zCommonFilter extends sfFilter
{
  public function execute($filterChain)
  {
    $filterChain->execute();

    $response = $this->context->getResponse();

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

Teraz trzeba  tylko "powiedzieć" symfony, aby  zamiast domyślnego filtru użyła naszego. Jak zawsze robimy to w pliku filters.yml wybranej aplikacji (apps/*/config/filters.yml):

rendering: ~
security:  ~
cache:     ~

common:
  class: zCommonFilter

execution: ~
Jakub Zalas

Jakub Zalas

Architekt, Programista, Trener