簡體   English   中英

有沒有辦法加載腳本標簽並在頁面完全加載后執行它包含的腳本?

[英]Is there a way to load a script tag and execute the script it contains after the page is fully loaded?

我試圖在頁面加載到我的 html(或 php)頁面后動態包含一個 three.js 模塊類型腳本標記。 這是我需要的,因為 google pagespeed insight 在有 three.js 的頁面上嚴重失敗,給頁面帶來錯誤和糟糕的速度分數。

  • 我試過 php readfile - 有效,但並沒有真正改變速度測試的行為,我得到了 LCP 的問號結果

  • 我正在考慮在頁面加載后嘗試使用 xhr 插入腳本,這可能是一個解決方案嗎?

settimeout 不是這里的選項

有任何想法嗎?

管理加載 three.js 腳本的正確方法可能是使用requestIdleCallback()

一旦頁面加載完畢並且瀏覽器 window 處於空閑狀態,腳本就會開始加載。

例子:

function loadThreeJS(deadline){
    //your three.js script
}

requestIdleCallback(loadThreeJS)

您可以傳入一個可選的超時參數,如果回調未在超時期限內完成,它將在下一個事件循環空閑時重新排隊回調。

requestIdleCallback(loadThreeJS, { timeout: 3000 })

可以在此處找到文檔。

另一種方法是使用 Promise 並在DOMContentLoaded事件之后加載腳本。

以下內容也使用requestIdleCallback() ,但更具體地針對您的問題,因為它將腳本標簽插入到文檔中。 它是從這里借來的,並改編為直接在瀏覽器中使用:

如果您需要腳本元素具有type=module ,請像這樣設置選項變量: 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)
        }
    })
})

ThreeJS 腳本 CDN URL 的測試腳本加載時間為 15 毫秒。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM