We’ve been working on Jira 9 compatibility for one of our apps and we’ve ran into an issue with the order in which static resources are being loaded.
Jira 9 has moved some of the <script />
tags that are generated by the web resource bundler from the <head />
into the top of the <body />
tag. In addition, it has included included defer
attributes to the script includes that are in the <head />
.
This is meant as a performance improvement and will probably speed up the page load significantly, where it not for the slight problem that the web resource bundler is having some issues determining which resources can be lazily loaded at the end of page rendering.
So here is the full story of what is going wrong for us.
Our app uses the atlassian-webresource-webpack-plugin to generate the web-resource tags. Which is working great. All the resources are generated correctly, with the right dependencies. However, the atlassian-webresource-webpack-plugin injects the following code into the common runtime:
if (typeof AJS !== "undefined") {
__webpack_require__.p = AJS.contextPath() + "/s/${uuid}/_/download/resources/${assetWebresource}/";
}
That means that our common runtime now has a dependency on AJS.contextPath
to be available. This is resolved by the code itself by adding a dependency to com.atlassian.plugins.atlassian-plugins-webresource-plugin:context-path
. This works perfectly well as the generate web-resource for the common-runtime actually has that dependency.
<web-resource key="common-runtime">
<dependency>com.atlassian.plugins.atlassian-plugins-webresource-plugin:context-path</dependency>
<resource type="download" name="runtime.3bf4b09dd62a9c0f3c05.js" location="static/runtime.3bf4b09dd62a9c0f3c05.js"/>
</web-resource>
The bundler picks up on this as it loads the scripts in the right order:
As you can see in the screen shot, the code that is responsible for setting AJS.contextPath is loaded as one of the first in the network waterfall, before our common runtime is loaded:
Despite the fact that the bundler is splitting the resources correctly based on the dependencies, we still get an error when loading the page:
The reason for this is that the common runtime that includes the atlassian-webresource-webpack-plugin code is executed before AJS.contextPath
is initialised. The <script />
tag that includes the code that initialises AJS.contextPath
is in the <head />
and should normally be executed first, however, it is marked with a defer
attribute:
The batch that includes our common runtime is now part of the <body />
tag (as an almost direct descendant and not even at the end of the page) and does not have a defer
attribute:
As shown here (thank you @tobias.viehweger for the link), the scripts at the top of body without a defer
attribute are executed prior to the scripts in the head with defer:
Due to this, a race condition is created that breaks any add-on that uses atlassian-webresource-webpack-plugin
and has an assets <web-resource />
. In general it creates a race condition for any code that the bundler decides should move to the top of <body />
tag without a defer
attribute and that relies on AJS.contextPath (or other AJS / WRM resources for that matter).
I would consider this a critical bug, and happy to file a report for this elsewhere. Looking forward to a solution as this blocks Jira 9 compatibility for our apps.
CC: @TomaszPrus @lvysochyn @AndrzejKotas @RomanKolosovskiy @MikolajRydzewski @GregRowinski @FilipNowak @skorytnicki