A proper way to manage loading your three.js script could be to use requestIdleCallback()
.
Once the page is loaded and the browser window is idle, the script would begin loading.
Example:
function loadThreeJS(deadline){
//your three.js script
}
requestIdleCallback(loadThreeJS)
You can pass in an optional timeout parameter, where if the callback has not completed within the timeout period, it will requeue the callback for when the next event loop is idle.
requestIdleCallback(loadThreeJS, { timeout: 3000 })
Documentation can be found here.
Another way would be to use a Promise and load the script after a DOMContentLoaded
event.
The following also uses requestIdleCallback()
, but is more specific to your question because it inserts script tags into the document. It was borrowed from here and adapted for use directly in the browser:
If you need the script element to have type=module
, set the options variable like this: let options = {timeout: 3000, type: "module"}
let src = "https://cdnjs.cloudflare.com/ajax/libs/three.js/r121/three.min.js" // your three.js script file source
let options = {timeout: 3000}
document.addEventListener("DOMContentLoaded", function(event) {
new Promise((resolve, reject) => {
let { timeout } = options
if (typeof timeout === 'number') {
timeout = Math.max(timeout, 1)
if (typeof requestIdleCallback === 'function') {
requestIdleCallback(loadScript, {
timeout
})
return
}
setTimeout(loadScript, timeout)
return
}
loadScript()
function loadScript () {
const script = document.createElement('script')
script.addEventListener('load', () => resolve(script))
script.addEventListener('error', () => reject(new Error(`Failed to load script: "${src}"`)))
if (options.type) script.type = options.type
if (options.charset) script.charset = options.charset
if (options.id) script.id = options.id
if (typeof options.noModule === 'boolean') script.noModule = options.noModule
script.async = options.async !== false
script.defer = options.defer !== false
script.src = src
document.head.appendChild(script)
}
})
})
Script load time on my test was 15ms for the ThreeJS script CDN URL.