Move CSS Above Scripts

Configuration

The 'Move CSS Above Scripts' filter is enabled by specifying:

Apache:
ModPagespeedEnableFilters move_css_above_scripts
Nginx:
pagespeed EnableFilters move_css_above_scripts;

in the configuration file.

Description

'Move CSS Above Scripts' seeks to make sure scripts do not block the loading of CSS resources.

This is based on the best practice for downloading resources early.

Operation

The 'Move CSS Above Scripts' filter operates only on CSS <link> and <style> tags found after the first <script> tag and moves these tags above the first <script>.

For example, if the HTML document looks like this:

<html>
  <head>
  </head>
  <body>
    <script src="script.js" type="text/javascript"></script>
    <div class="blue yellow big bold">
      Hello, world!
    </div>
    <style type="text/css">
      .foo { color: red; }
    </style>
    <link rel="stylesheet" type="text/css" href="styles/all_styles.css">
  </body>
</html>

Then PageSpeed will rewrite it into:

<html>
  <head>
  </head>
  <body>
    <style type="text/css">
      .foo { color: red; }
    </style>
    <link rel="stylesheet" type="text/css" href="styles/all_styles.css">
    <script src="script.js" type="text/javascript"></script>
    <div class="blue yellow big bold">
      Hello, world!
    </div>
  </body>
</html>

In some browsers the original version will not even download the CSS file until the JavaScript has been downloaded and run. This transformation will make sure the CSS file is loaded first.

Note: You may also want to enable the move_css_to_head filter to avoid a flash of unstyled content. When both filters are enabled, stylesheets are moved into the head and above the first script.

Example

You can see the filter in action at www.modpagespeed.com on this example.

Limitations

This filter operates within the scope of a "flush window". Specifically, large, or dynamically generated HTML files may be "flushed" by the resource generator before they are complete. If the filter encounters a flush after the first <script> tag, subsequently encountered CSS elements will not be moved above it.

Risks

This filter is considered low risk. However, JavaScript that is executed before a CSS element will see a different view of the DOM in the presence of this rewriter: the CSS element will now be in the head. If there is such JavaScript embedded in the middle of a page then this rewriter may change its behavior.

This filter may slow down your webpages for some browsers. Just as JavaScript can block download of CSS in some browsers, some others will not execute JavaScript until preceding CSS has been rendered. This filter is currently considered experimental while we measure its effectiveness.