on D10, SCORM javascript sometimes loads before opigno_scorm player javascript

Created on 27 September 2023, almost 2 years 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 server would 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

Active

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 over 1 year 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.

  • Merge request !3Resolve #3390018 "Put SCORM js in the Header" β†’ (Closed) created by catch
  • Status changed to Closed: outdated 8 months ago
  • πŸ‡ΊπŸ‡¦Ukraine id.aleks

    Thank you for reporting this issue. It has already been resolved in OpignoLMS 3.2.7, which is now available for download. I am marking this issue as resolved.

  • πŸ‡¨πŸ‡¦Canada maursilveira Windsor, ON

    Hello @id.aleks,

    Is there a way to apply the fix into the Opigno SCORM project? OpignoLMS isn't a dependency of Opigno SCORM, therefore projects may not be using it (which is exactly my case). Or is there another way of resolving this issue without installing OpignoLMS?

    Thank you!

  • πŸ‡ΊπŸ‡¦Ukraine id.aleks

    Hello @maursilveira,

    Sorry if mentioning Opigno LMS caused any confusion. Opigno SCORM is a part of Opigno LMS, which is why I referenced it.
    The Opigno SCORM 3.2.7 release is available for download as well, and the fix is already included in that version.

    I hope this is helpful to you.

Production build 0.71.5 2024