Skip to content
This repository was archived by the owner on Mar 5, 2026. It is now read-only.

Latest commit

 

History

History
102 lines (76 loc) · 3.28 KB

File metadata and controls

102 lines (76 loc) · 3.28 KB

Discourage Use of Parser-Blocking JavaScript (ParserBlockingJavaScript)

This check aims to eliminate parser-blocking JavaScript in your app.

Using the defer or async attributes is extremely important on script tags. When neither of those attributes are used, a script tag will block the construction and rendering of the DOM until the script is loaded, parsed and executed. This can create network congestion, interfere with resource priorities, and significantly delay page rendering.

JavaScript in platformOS apps should always be used to progressively enhance the user experience. Therefore, parser-blocking script tags should never be used.

As a general rule:

  • Use defer if the order of execution matters.
  • Use async if the order of execution does not matter.
  • When in doubt, using either will provide 80/20 of the benefits.

Examples

The following examples show code snippets that either fail or pass this check:

✗ Incorrect Code Example (Avoid using this):

<!-- The script_tag filter outputs a parser-blocking script -->
{{ 'app-code.js' | asset_url | script_tag }}

<!-- jQuery is typically loaded synchronously because inline scripts depend on $, don't do that. -->
<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>

✓ Correct Code Example (Use this instead):

<!-- Good. Using the asset_url filter + defer -->
<script src="{{ 'theme.js' | asset_url }}" defer></script>

<!-- Also good. Using the asset_url filter + async -->
<script src="{{ 'theme.js' | asset_url }}" async></script>

<!-- Better than synchronous jQuery -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js" defer></script>
...
<button id="thing">Click me!</button>
<script>
  // Because we're using `defer`, jQuery is guaranteed to
  // be loaded when DOMContentLoaded fires. This technique
  // could be used as a first step to refactor an old theme
  // that inline depends on jQuery.
  document.addEventListener('DOMContentLoaded', () => {
    $('#thing').click(() => {
      alert('Oh. Hi Mark!');
    });
  });
</script>

<!-- Even better. Web Native (no jQuery). -->
<button id="thing">Click Me</button>
<script>
  const button = document.getElementById('thing');
  button.addEventListener('click', () => {
    alert('Oh. Hi Mark!');
  });
</script>

<!-- Best -->
<script src="{{ 'theme.js' | asset_url }}" defer></script>
...
<button id="thing">Click Me</button>

Configuration Options

The default configuration for this check:

ParserBlockingJavaScript:
  enabled: true

Disabling This Check

This check should only be disabled with the platformos-check-disable comment if there is no better way to achieve the desired outcome than using a parser-blocking script.

Disabling this check is generally not recommended.

Version

This check has been introduced in platformOS Check 0.0.1.

Resources