0

我目前正在玩弄自定義元素。我正在努力尋找正確的方式(或者感覺像正確的方式)來填充缺乏支持的瀏覽器(看起來只有Firefox?)。爲自定義元素加載polyfill的最佳方式是什麼?

我目前做如下:

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 polyfills在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'); 
}); 

回答

2

推薦的方法是總是load the complete polyfill(僅限82 ko)。

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

由於腳本加載是同步的,所以polyfill和自定義元素將以正確的順序加載。

如果你想只支持Firefox和邊緣,你可以替換webcomponents-lite.js通過webcomponents-SD-ce.js(64 KO),但你將獲得只在大多數情況下幾毫秒。


或者,和非常糟糕的網絡,你可以use the webcomponents-loader.js(4 KO)將執行特徵檢測與荷載爲您服務。

您也可以縮小它,甚至更好,直接在您的主頁面插入其內容,以節省一個請求的往返延遲。

+0

強迫82kb/64kb給每個人,不管他們是否需要它,這是我不想做的事情。我嘗試使用'webcomponents-loader.js',但我的自定義元素似乎在實際的polyfill運行之前運行(動態加載的腳本似乎是運行異步?)。 –

+0

是的,它是異步的,因此您應該等待鏈接中所述的WebComponentsReady事件 – Supersharp

相關問題