04月19, 2018

三方js的处理

这阵子,刚好我这边要负责写一个埋点的jssdk。于是在网上搜索了下,找到一个collection

alt

其实像google的统计也是类似的加载方式。像我需要写的jssdk是面向公司的所有部门的,采用script src的方式,很容易造成,如果这个文件挂起,那页面要过很久才会显示出来。

今天刚好团队中也出了类似的事故,在我们的html中,引入了安全联盟的一个js文件,结果那个文件加载了很久,导致页面过了很久才出来。

团队负责人让我这边协助看一下,我初步的想法比较简单,通过document.createElement("script"),但发现不行,因为它的结构是这样的:

<a>
    <script src="xx.js"></script>
</a>

xx.js干了一件恶心的事,就是通过document.write来写出一个img标签。

在网上搜索了一下,找到一个方案:让document.write的广告无阻塞的加载

思路是将a标签里的script放到一个textarea标签中,且hidden。然后写一个方法,来加载textarea的value值,当然这里面得要重写document.write

<a>
    <textarea id="test" style="display: none;"><script src="xx.js"></script></textarea>
</a>
/**
 * 重写document.write实现无阻塞加载script
 * @param { Dom Object } textarea元素
 */
var loadScript = function (elem) {
    var url = elem.value.match(/src="([\s\S]*?)"/i)[1],
        parent = elem.parentNode,
        // 缓存原生的document.write
        docWrite = document.write,
        // 创建一个新script来加载
        script = document.createElement('script'),
        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'
        ) {

            // 恢复原生的document.write
            document.write = docWrite;
            head.removeChild(script);

            // 卸载事件和断开DOM的引用
            // 尽量避免内存泄漏
            head =
                parent =
                elem =
                script =
                script.onerror =
                script.onload =
                script.onreadystatechange = null;

        }
    }

    // 加载script
    head.insertBefore(script, head.firstChild);
};

// 加载js
loadScript(document.getElementById("test"));

本文链接:www.my-fe.pub/post/third-js-load.html

-- EOF --

Comments

评论加载中...

注:如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理。