Move storefront script to head with defer
INFO
This document represents an architecture decision record (ADR) and has been mirrored from the ADR section in our Shopware 6 repository. You can find the original version here
Context
- Currently, our main storefront scripts (inline scripts as well as
all.js
) are located at the bottom of the page near the body end tag. - The
async
attribute is used for theall.js
but it isn't really suitable because our own JavaScript plugins depend on DOM elements in order to be initialized, and we have to wait for the document to be finished anyway. - Additionally, the
DOMContentLoaded
is not compatible withasync
scripts because they might run before this particular event. That's whydocument.readystatechange --> complete
is being used at the moment. - This has the downside, that none of our JavaScript plugins initializes before the entire document is fully loaded including all resources like images.
Decision
- In order to improve the script loading all default
<script>
tags are moved to the<head>
and get adefer
attribute in favor ofasync
. - To initialize the JavaScript plugins, the
DOMContentLoaded
is being used instead ofdocument.readystatechange --> complete
.- This ensures that the JavaScript plugins initialization must only wait for the document itself but not for additional resources like images.
- This change allows the browser to download/fetch the scripts right away when the
<head>
is parsed instead of when almost the entire document is already parsed. - Because of
defer
the script execution will wait until the document is parsed (Just right before theDOMContentLoaded
event). defer
also ensures that the different<script>
's are executed in the order in which they are declared.
Consequences
All app/plugin script tags which extended one of the base_body_script
child blocks must be moved to Resources/views/storefront/layout/meta.html.twig