【问题标题】:What is the best way to load polyfills for custom elements?为自定义元素加载 polyfill 的最佳方式是什么?
【发布时间】:2017-08-26 17:50:59
【问题描述】:

我目前正在使用自定义元素。我正在努力寻找正确的方法(或者感觉像是正确的方法)来填充缺乏支持的浏览器(似乎只有 Firefox?)。

我目前正在做以下事情:

if ('customElements' in window) {
    var e = document.createElement('script');
    e.src = '/static/elements/my-element.js';
    document.body.appendChild(e);   
} else {
    var e = document.createElement('script');
    // customElements
    e.src = 'https://cdnjs.cloudflare.com/ajax/libs/webcomponentsjs/1.0.8/webcomponents-sd-ce.js';
    e.onload = function() {
        var c = document.createElement('script');
        // ShadyCSS
        c.src = '/static/js/custom-style-interface.min.js';
        c.onload = function() {
            var i = document.createElement('script');
            i.src = '/static/elements/my-element.js';
            document.body.appendChild(i);
        }
        document.body.appendChild(c);
    }
    document.body.appendChild(e);
}

这行得通,但显然效率极低(尤其是在慢/高延迟网络上),而且看起来也很嘈杂。在尝试支持 Firefox 之前,我可以简单地做:

<script src="/static/elements/my-element.js"></script>

现在我上面有这个可憎的东西。必须有更好的方法,但我似乎找不到。

如何确保 customElement 和 ShadyCSS polyfill 在 my-element.js 之前运行而不会延迟下载?任何指针都非常感谢!

编辑: 现在我正在使用另一种方法,我将在此处添加。我不认为它是完美的,但似乎比我的第一种方法或强迫每个人都下载 polyfills,不管他们是否需要它们更好。

function insertScript(url, downloadAsync) {
    const script = document.createElement('script');
    document.head.appendChild(script);
    script.async = downloadAsync;
    script.src = url;
    return script;
}

function downloadAsync(url) {
    return new Promise((resolve, reject) => {
        const script = insertScript(url, 'true');
        script.onload = resolve;
        script.onerror = reject;
    });
}

var deps = [];
if (!('customElements' in window)) {
    deps.push(downloadAsync('/url/of/polyfill.js'));
    // if you need more than 1 polyfill add more deps.push
}

Promise.all(deps).then(() => {
    insertScript('/static/elements/my-element.js');
});

【问题讨论】:

    标签: javascript web-component shadow-dom polyfills custom-element


    【解决方案1】:

    推荐的方法是始终load the complete polyfill(仅限82 ko)。

    <script src="/path/to/webcomponents-lite.js"></script>
    <script src="/static/elements/my-element.js"></script>
    

    由于脚本加载是同步的,因此 polyfill 和自定义元素将以正确的顺序加载。

    如果您只想支持 Firefox 和 Edge,您可以将 webcomponents-lite.js 替换为 webcomponents-sd-ce.js (64 ko),但您会大多数情况下只增加几毫秒。


    或者,对于非常糟糕的网络,您可以use the webcomponents-loader.js (4 ko) 为您执行特征检测和加载。

    您也可以将其缩小,或者更好的是,将其内容直接插入您的主页以节省一个请求往返延迟。

    【讨论】:

    • 强制每个人使用 82kb / 64kb,无论他们是否需要,我都不愿意这样做。我尝试使用webcomponents-loader.js,但我的自定义元素似乎在实际的 polyfill 运行之前运行(动态加载的脚本似乎是异步运行的?)。
    • 是的,它是异步的,因此您应该按照链接中的说明等待 WebComponentsReady 事件
    猜你喜欢
    • 2011-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-13
    • 2016-01-30
    • 2012-09-02
    • 2010-11-09
    相关资源
    最近更新 更多