---
title: ParserBlockingScript
description: Identifies script tags that don't have defer or async attributes.
source_url:
  html: >-
    https://shopify.dev/docs/storefronts/themes/tools/theme-check/checks/parser-blocking-javascript
  md: >-
    https://shopify.dev/docs/storefronts/themes/tools/theme-check/checks/parser-blocking-javascript.md
api_name: liquid
---

# Parser​Blocking​Script

Identifies HTML script tags that don't have `defer` or `async` attributes.

When neither of those attributes are used, a script tag blocks the construction and rendering of the DOM until the script is loaded, parsed and executed. It also creates congestion on the network, messes with the resource priorities and significantly delays the rendering of the page.

Considering that JavaScript on Shopify themes [should always be used to progressively enhance the experience of the site](https://shopify.dev/docs/storefronts/themes/best-practices/performance/defer-scripts), themes should never make use of parser-blocking script tags.

As a general rule, use `defer` if the order of execution matters, and use `async` if it doesn't.

Learn more about [improving your theme's performance](https://shopify.dev/docs/storefronts/themes/best-practices/performance).

***

## Examples

The following examples contain code snippets that either fail or pass this check.

### ✗ Fail

This example loads jQuery synchronously because inline scripts depend on it:

```html
{{ 'theme.js' | asset_url | script_tag }}
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
...
<button id="thing">Click me!</button>
<script>
  $('#thing').click(() => {
    alert('Oh. Hi Mark!');
  });
</script>
```

### ✓ Pass

This example contains an alternative to synchronous jQuery. Because the script tag has a `defer` attribute, jQuery is guaranteed to be loaded when DOMContentLoaded fires. This technique could be used as a first step to refactor an theme that depends on jQuery.

```html
<script src="{{ 'theme.js' | asset_url }}" defer></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js" defer></script>
...
<button id="thing">Click me!</button>


<!-- Even without the `src` attribute, the script tag still acts as a blocking script, but its impact is reduced by using the `document.addEventListener` call. -->
<script>
  document.addEventListener('DOMContentLoaded', () => {
    $('#thing').click(() => {
      alert('Oh. Hi Mark!');
    });
  });
</script>
```

**Note:**

Theme Check only lints script tags that include the `src` attribute.

This example avoids jQuery.

```html
<button id="thing">Click Me</button>
<script>
  const button = document.getElementById('thing');
  button.addEventListener('click', () => {
    alert('Oh. Hi Mark!');
  });
</script>
```

***

## Options

The following example contains the default configuration for this check:

```yaml
ParserBlockingScript:
  enabled: true
  severity: error
```

| Parameter | Description |
| - | - |
| `enabled` | Whether this check is enabled. |
| `severity` | The [severity](https://shopify.dev/themes/tools/theme-check/configuration#check-severity) of the check. |

***

## Disabling this check

If you can't avoid violating the rule, you should disable the check using the [comment syntax](https://shopify.dev/docs/storefronts/themes/tools/theme-check/configuration#disable-checks-using-liquid-comments). This ensures that you intentionally disable the check for each instance.

Disabling this check isn't recommended.

```liquid
{% # theme-check-disable ParserBlockingScript %}
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
{% # theme-check-enable ParserBlockingScript %}
```

***
