on D10, SCORM javascript sometimes loads before opigno_scorm player javascript

Created on 27 September 2023, about 1 year ago
Updated 21 March 2024, 9 months ago

Problem/Motivation

Recently, I encountered an error that would happen on an inconsistent basis. When loading a node with a scorm field after a complete cache clear, the javascript in my Articulate SCORM package would throw an error complaining about the SCORM API not being available. The SCORM API functions are typically added by the opigno scorm player javascript code.

This seemed to happen only on the first page load after a complete cache clearing ("drush cr"). The specific error message from my Articulate-generated SCORM package in the pop-up was

"An error has occurred:

Error - unable to acquire LMS API, content may not play properly and results may not be recorded. Please contact technical support."

I noticed that the issue would not occur at all if I disabled javascript aggregation on my site. In examining changes related to javascript aggregation in D10, I came across this description: https://www.drupal.org/node/3301716 β†’

The relevant portion of this page states: "Instead of a page request creating and writing several files before it can be sent to the browser, now the main page request just generates the URLs, and the actual CSS or JavaScript aggregate is individually created by PHP (and still written to disk assuming it's valid)."

So, what was happening was that the server would return a page with URLs for aggregated javascript files that didn't exist yet. The browser would then request those files and, while the server was busy assembling those files in order to send them back the browser, the browser in the meantime had loaded the contents of the iframe, including the SCORM package's javascript code that checks to see whether certain SCORM API functions are available yet. The SCORM package's javascript would see that those SCORM APIs (to be supplied by the opigno_scorm module's javascript code) were not yet available and throw this error, causing the above message to show in a pop-up and ceasing any attempt to play the SCORM file.

Steps to reproduce

As mentioned, the error would happen inconsistently. To replicate it more consistently, I went into the system module's controller, at core/modules/system/src/Controller/AssetControllerBase.js, and modified the deliver() method to sleep for 5 seconds at the beginning of the method if the $file_name parameter to that method ended with ".js". This didn't make the error happen with 100% consistency, but it did happen much more often for me.

Another thing to note is that this error more readily happens on environments that use a distributed file server for its filesystem. This is because I/O operations typically take longer in this scenario, which affects the time it takes to assemble an aggregate file on the fly.

Proposed resolution

In my situation, I got around this problem by overriding the opigno-scorm--player template to serve the same HTML, but without the iframe tag. Then, I used javascript to wait for the document to completely load before creating the necessary iframe tag. This ensures that the SCORM package's contents (and its javascript) is loaded only after the opigno_scorm module's requisite javascript functions are available. I thought this might make the SCORM content load noticeably slower, but I observed almost no difference in the load time.

πŸ› Bug report
Status

Needs review

Version

3.0

Component

Code

Created by

πŸ‡ΊπŸ‡ΈUnited States ankur

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @ankur
  • πŸ‡ΊπŸ‡ΈUnited States ankur
  • First commit to issue fork.
  • Status changed to Needs review 9 months ago
  • πŸ‡¬πŸ‡§United Kingdom catch

    This is likely a pre-existing race condition but because the HTML is rendered longer before the JavaScript in a cold cache situation in 10.2 (the JavaScript aggregate creation used to block the page being rendered at all) there's more chance of hitting it, as your debugging shows.

    I think the SCORM js needs to go in the header as a quick fix, there might be a way to force the iframe to wait similar to what you implemented locally.

Production build 0.71.5 2024