Skip to main content

filter · CSS filters

Move CSS above scripts (move_css_above_scripts)

Category:
CSS
CoreFilters:
No
OptimizeForBandwidth:
No
Risk:
Generally safe

move_css_above_scripts lifts stylesheet references that sit below the page’s first <script> up to just before that first script. A browser will not run a script until the stylesheets above it have loaded, because the script may read layout; with stylesheets scattered around and below scripts, those downloads are discovered late and the script waits on them. Moving each stylesheet directly before the first script puts every download in front of the code that needs it.

How it works

Not a core filter; enable it by name. Live demo: move_css_above_scripts.

When it helps and when it does not

It helps on legacy or machine-generated pages where stylesheets ended up interleaved with or after scripts: template fragments that each carry their own <link>, or ad and widget snippets injecting CSS late in the body. On pages whose CSS already sits in <head> with scripts at the end of <body>, there is nothing after any script to move and the filter changes nothing. The stylesheets keep their order among themselves, so the cascade is unchanged; what changes is where the group sits relative to the script.

How it decides

The first <script> in the document is the anchor. Every <style> block and stylesheet <link> that appears after it moves to directly before that first script, in original order. When move_css_to_head is also enabled, whichever anchor closes first in the document, the </head> or the first script, wins and all moves go there. A stylesheet inside <noscript>, or a <style scoped> block, stays where it is and ends the current move; styles after it move up only as far as the next <script>.

When to use it

  • Not in CoreFilters: it runs only when you enable it by name.
  • Risk rating on these docs: Generally safe.

Risks

  • A stylesheet deliberately placed after a script by code that removes or replaces it at run time is moved too; such pages need the filter off for that path.

  • Verify with the X-Mod-Pagespeed response header and a ?PageSpeedFilters=-move_css_above_scripts comparison; Is it working? has the steps.

Configuration

Enable it in the module configuration, at server, virtual-host or location scope:

Apache

ModPagespeedEnableFilters move_css_above_scripts

nginx

pagespeed EnableFilters move_css_above_scripts;

IIS (pagespeed.config)

pagespeed EnableFilters move_css_above_scripts
<!-- before -->
<script src="/js/theme.js"></script>
<link rel="stylesheet" href="/css/theme.css" />

<!-- after: the stylesheet loads first -->
<link rel="stylesheet" href="/css/theme.css" />
<script src="/js/theme.js"></script>

On the worker

The worker runs its own pipeline, configured by flags. Its equivalent of this filter is the async css transform. Toggleable via --no-async-css; the coverage gate is tuned with --async-css-min-coverage and --async-css-min-deferred-bytes.

Scoping, ForbidFilters and the thresholds filters read: Choosing filters .

Live example

Reorders CSS ahead of scripts so styles are not blocked by JavaScript.

Measured on the demo page, original against optimized:

  • Total bytes

    716 B → 639 B −11%

See the before and after, with the source diff →

Frequently asked questions

What does the move_css_above_scripts filter do?
move_css_above_scripts lifts stylesheet references that sit below the page's first <script> up to just before that first script. A browser will not run a script until the stylesheets above it have loaded, because the script may read layout; with stylesheets scattered around and below scripts, those downloads are discovered late and the script waits on them. Moving each stylesheet directly before the first script puts every download in front of the code that needs it.
Is move_css_above_scripts enabled by default?
No. move_css_above_scripts is not in CoreFilters, the default RewriteLevel; it runs only when you enable it by name with EnableFilters.
How do I enable move_css_above_scripts on Apache and nginx?
Add ModPagespeedEnableFilters move_css_above_scripts on Apache or pagespeed EnableFilters move_css_above_scripts; on nginx. On IIS, add pagespeed EnableFilters move_css_above_scripts to pagespeed.config.

This page is drawn from the move_css_above_scripts entry on CSS filters. Every filter in one table: PageSpeed filters.

Search