Monthly Archives: November 2010

move your Javascripts to Pagebottom with ease in symfony

Currently i am doing some page speed improvements to my site, and wanted to move all my javascripts to the page bottom.

My first approach was simply moving the script helper to the page bottom:

<?php include_javascripts() ?>
</body>

But that wont worked as expected.
Some Widget or Subsites may write some inline scripts, that uses included class from the top of the page.

For example (original):

<script type="text/javascript" src="jquery.js" >

<script type="text/javascript">
  $.somefunction();
</script>

would result in (moved helper to the bottom):

<script type="text/javascript">
  $.somefunction();
</script>

<script type="text/javascript" src="jquery.js" ></script>

that leads to nasty javascript errors!

Here is the solution for that:
Its a simple symfony Filter which greps all script tags and moves them in correct order the bottom of the page!

activate the filter after your rendering filter in your filters.yml

rendering: ~

scripts:
  class: DomScriptFilter

Here is the Filter:

/**
 * this filter moves all script tags to the bottom of the dom
 *
 * @author robert
 * @package lib.filter
 */
class DomScriptFilter extends sfFilter
{
  /**
   * @var EXPRESSION finds all script tags and moves them to the bottom
   */

  const EXPRESSION = "/<script [^>]*>([\d\D\w\W\s\S]*?)<\/script>/";

  /**
   * executes this filter
   *
   * @param sfFilterChain $filterChain
   */
  public function execute($filterChain)
  {
    $filterChain->execute();

    $content = $this->getContext()->getResponse()->getContent();

    preg_match_all(self::EXPRESSION, $content, $scripts);
    preg_replace(self::EXPRESSION, '', $content);

    $content = str_replace('', join('',$scripts[0]).'', $content);

    $this->getContext()->getResponse()->setContent($content);
  }
}

and voila it works as expected (with filter):


<script type="text/javascript" src="jquery.js" >
<script type="text/javascript">
  $.somefunction();
</script>

Now the page feels much faster, since we dont have to wait for javascripts to load to render the page…