document.write 和 異步

今天碰到一個(gè)大坑,分享一下。

項(xiàng)目中首頁(yè)用了一個(gè)什么安全聯(lián)盟標(biāo)志,具體用處不大,就是逼格顯得高一點(diǎn)點(diǎn)。我們?cè)瓉?lái)是這么用的。

<a key ="" logo_size="124x47" logo_type="business" >
  <script src="http://static.anquan.org/static/outer/js/aq_auth.js"></script>
</a>

然后今天突然發(fā)現(xiàn),這個(gè)js加載需要30多秒,直接阻塞了之后的html以及js加載。整個(gè)頁(yè)面就在那兒白屏了整整30多秒,然后才加載了出來(lái)。(還好這是一個(gè)首頁(yè),說(shuō)實(shí)話平時(shí)瀏覽的人不是特別多,但是也算是重要門戶,后來(lái)緊急先把這個(gè)功能先下了)

大家討論了一下,這種外部引用又不算是特別重要的東西,一定要用異步。

坑又來(lái)了,這段js代碼,中間用了document.write,異步加載寫不進(jìn)去東西直接報(bào)錯(cuò)。

嘗試了以下幾種方案:
1、在script標(biāo)簽直接加上async="true"
2、在頁(yè)面末尾位置將這個(gè)a標(biāo)簽直接append進(jìn)去(首頁(yè)有很多動(dòng)畫效果,引用過jquery)
3、script標(biāo)簽不加src,而是在js中動(dòng)態(tài)加載src

以上方法都是異步方法。均直接報(bào)錯(cuò)。

后來(lái)找到了一種方法:
讓document.write的廣告無(wú)阻塞的加載 - 雨夜帶刀

這篇文章使用了一種方法,利用textarea的延遲渲染和對(duì)document.write的重寫,實(shí)現(xiàn)異步配合document.write的方案。

// html部分
<a key ="" logo_size="124x47" logo_type="business" >
    <textarea id="aTextarea" style="display:none">
        <script src="http://static.anquan.org/static/outer/js/aq_auth.js"></script>
    </textarea>
</a>

// js部分
var loadScript = function( elem ){
    var url = elem.value.match( /src="([\s\S]*?)"/i )[1],
        parent = elem.parentNode,
        docWrite = document.write,    // 緩存原生的document.write
        script = document.createElement('script'),  // 創(chuàng)建一個(gè)新script來(lái)加載
        head = document.head || document.getElementsByTagName('head')[0] || document.documentElement;
    // 重寫document.write
    document.write = function(text){
        parent.innerHTML = text;
    };
    script.type = 'text/javascript';
    script.src = url;
    script.onerror =
    script.onload =
    script.onreadystatechange = function(e){
        e = e || window.event;
        if(!script.readyState || /loaded|complete/.test(script.readyState) || e === 'error'){
            // 恢復(fù)原生的document.write
            document.write = docWrite;
            head.removeChild(script);
            // 卸載事件和斷開DOM的引用
            // 盡量避免內(nèi)存泄漏
            head =
            parent =
            elem =
            script =
            script.onerror =
            script.onload =
            script.onreadystatechange = null;
        }
    };
    // 加載script
    head.insertBefore(script, head.firstChild);
};
loadScript(document.getElementById("aTextarea"));
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Tif_Lib閱讀 503評(píng)論 0 1
  • 本文總結(jié)一下瀏覽器在 javascript 的加載方式。關(guān)鍵詞:異步加載(async loading),延遲加載(...
    4ea0af17fd67閱讀 1,118評(píng)論 0 2
  • 首先我們先來(lái)看一下Script標(biāo)簽的各項(xiàng)屬性: script標(biāo)簽也支持HTML中的全局屬性: 下面我們來(lái)看看一看j...
    tobAlier閱讀 1,277評(píng)論 0 2
  • JavaScript腳本對(duì)現(xiàn)代網(wǎng)站來(lái)說(shuō)是必不可少的。當(dāng)用戶訪問站點(diǎn),需要下載各種資源,例如JS腳本,CSS,圖片,...
    張歆琳閱讀 9,368評(píng)論 0 24
  • 周末天好冷啊~~。今天在家一天沒出去。孩子爸爸和孩子在家戰(zhàn)爭(zhēng)不斷。我都懷疑他們前世是仇人? 孩子的感...
    幸福的小秋閱讀 163評(píng)論 0 0

友情鏈接更多精彩內(nèi)容