Last active
May 1, 2021 15:42
-
-
Save ebidel/1ba71473d687d0567bd3 to your computer and use it in GitHub Desktop.
Fast Polymer app loading - optimized for first render, progressively enhanced lazy loading
This file contains 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> | |
<!-- 1. Async HTML Imports do not block rending. Benefit of keeping it declarative | |
(instead of dynamically loading it later in JS) is that the parser can go | |
to town pre-fetching resources, etc. --> | |
<link rel="import" id="bundle" href="elements.html" async> | |
</head> | |
<!-- 2. Don't use <body unresolved>. It's a simple FOUC solution, but hides | |
the page until imports and Polymer are loaded. Intead, control FOUC manually with | |
a splash screen. --> | |
<body class="loading"> | |
<!-- 3. Light weight splash screen is outside of Polymer/imports and styled by | |
the main page. 1st paint is fast, even on polyfilled browsers. Alternatively, | |
one could create an "app shell" and style the page's un-upgraded elements | |
similar to their final upgraded version. --> | |
<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 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. Conditionally load the webcomponents polyfill if needed by the browser. | |
// This feature detect will need to change over time as browsers implement | |
// different features. | |
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() { | |
// (Optional) Use native Shadow DOM if it's available in the browser. | |
window.Polymer = window.Polymer || {dom: 'shadow'}; | |
// 6. Fade splash screen, then remove. | |
var onImportLoaded = function() { | |
var loadEl = document.getElementById('splash'); | |
loadEl.addEventListener('transitionend', loadEl.remove); | |
document.body.classList.remove('loading'); | |
// App is visible and ready to load some data! | |
}; | |
var link = document.querySelector('#bundle'); | |
// 5. Go if the async Import loaded quickly. Otherwise wait for it. | |
// crbug.com/504944 - readyState never goes to complete until Chrome 46. | |
// crbug.com/505279 - Resource Timing API is not available until Chrome 46. | |
if (link.import && link.import.readyState === 'complete') { | |
onImportLoaded(); | |
} else { | |
link.addEventListener('load', onImportLoaded); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
How about browser support on it? How to avoid this:
crbug.com/504944 - readyState never goes to complete until Chrome 46.
on Mac Chrome 41 i have empty element (just tag) and its withoutasync
!<link rel="import" id="bundle" href="elements.html">
?I need that because i need to debug my code.. and i got that i described in previous comment.
Tested on Mac Chromium 24 - works fine.
Fixed (i found fix there on gaming youtube) by adding this case with interactive on line37: