Last active
May 1, 2021 15:42
-
-
Save ebidel/c72e5b9b7ce7588ef468 to your computer and use it in GitHub Desktop.
Fast Polymer app loading (Promises version) - optimized for first render, progressively enhanced lazy loading
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<style> | |
body.loading #splash { | |
opacity: 1; | |
} | |
#splash { | |
position: absolute; | |
top: 0; | |
left: 0; | |
right: 0; | |
bottom: 0; | |
transition: opacity 300ms cubic-bezier(0,0,0.2,1); | |
opacity: 0; | |
will-change: opacity; | |
z-index: 1; | |
background: url(...) no-repeat; | |
background-color: #E53935; | |
} | |
</style> | |
<script> | |
// Note: this version requires Promises, which are in all the | |
// latest browsers except IE 11. Edge will ship them. | |
// Note: native Promise.defer() is deprecated. Have to create our own. | |
function deferred() { | |
var result = {}; | |
result.promise = new Promise(function(resolve, reject) { | |
result.resolve = resolve; | |
result.reject = reject; | |
}); | |
return result; | |
}; | |
// (Optional) Use native Shadow DOM if availabe in the browser. | |
window.Polymer = window.Polymer || {dom: 'shadow'}; | |
// 1. Create deferred Promise to capture async import's load. | |
var importsLoadedDeferred = deferred(); | |
function onImportsLoaded(e) { | |
// 3. Resolve the Promise when the async import has loaded. | |
importsLoadedDeferred.resolve(e.target); | |
} | |
</script> | |
<!-- 2. Use non-render blocking async import with onload handler. | |
Note: the handler needs to be defined before this import. --> | |
<link rel="import" href="elements.html" onload="onImportsLoaded(event)" async> | |
</head> | |
<body class="loading"> <!-- Don't use simple FOUC solution <body unresolved>. --> | |
<div id="splash"></div> | |
<!-- Elements wait on the page and are upgraded when elements.html loads. --> | |
<paper-drawer-panel> | |
... | |
</paper-drawer-panel> | |
<script src="app.js" async></script> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 4. Dynamically load web components polyfills based on feature detection. | |
var webComponentsSupported = ('registerElement' in document | |
&& 'import' in document.createElement('link') | |
&& 'content' in document.createElement('template')); | |
if (!webComponentsSupported) { | |
var script = document.createElement('script'); | |
script.async = true; | |
script.src = '/bower_components/webcomponentsjs/webcomponents-lite.min.js'; | |
script.onload = finishLazyLoading; | |
document.head.appendChild(script); | |
} else { | |
finishLazyLoading(); | |
} | |
function finishLazyLoading() { | |
// 5. Wait on importsLoadedDeferred to resolve. When it does, | |
// the import has loaded. | |
importsLoadedDeferred.promise.then(function(htmlImport) { | |
// 6. Fade splash screen, then remove. | |
var loadEl = document.getElementById('splash'); | |
loadEl.addEventListener('transitionend', loadEl.remove); | |
document.body.classList.remove('loading'); | |
// App is visible and ready to load some data! | |
}); | |
} |
What browser is that? This code is working for me in Chrome / Safari / FF.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@ebidel the Promise.defer() you've created causes an issue:
i believe this is because you are trying to copy a native method (resolve and reject native methods) into ( result object )