Skip to content

Instantly share code, notes, and snippets.

@mseeley
Created March 3, 2014 09:29
Show Gist options
  • Save mseeley/9321422 to your computer and use it in GitHub Desktop.
Save mseeley/9321422 to your computer and use it in GitHub Desktop.
WebWorker Image preloader proof of concept (Tested in Mobile Safari 6.0/IOS 6.1.3 and Chrome 33)
<!DOCTYPE html>
<html>
<head>
<title>WebWorker image preloading</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no" />
</head>
<body>
<div id="output"></div>
<script id="imgloader" type="javascript/worker">
// Not race proof or robust. Proof of concept.
self.onmessage = function (e) {
var urls = e.data,
done = urls.length,
onload = function () {
if (--done === 0) {
self.postMessage('Done!');
self.close();
}
};
urls.forEach(function (url) {
var xhr = new XMLHttpRequest();
xhr.responseType = 'blob';
xhr.onload = xhr.onerror = onload;
xhr.open('GET', url, true);
xhr.send();
});
};
</script>
<script>
// Server must expose CORS headers for XHR preload.
var imgs = [
'http://i.imgur.com/JmvCQXd.jpg',
'http://i.imgur.com/L4ipvCE.jpg',
'http://i.imgur.com/fKDIYIP.jpg',
'http://i.imgur.com/4ad4bo5.jpg',
'http://i.imgur.com/VukIBgD.jpg'
],
URL = window.URL || window.webkitURL,
url = URL.createObjectURL(
new Blob(
[document.getElementById('imgloader').textContent],
{ type: "text/javascript" }
)
),
worker = new Worker(url);
worker.onmessage = function (e) {
var frag = document.createDocumentFragment(),
count = imgs.length,
onload = function () {
delete this.onload;
frag.appendChild(this);
if (--count === 0) {
console.log('done')
document.getElementById('output').appendChild(frag);
}
};
// These will come immediately from cache.
// Ensure cache is not disabled by dev tools.
imgs.forEach(function (img) {
var el = document.createElement('img');
// Avoid early reflows as images load without sizes. Wait for onload.
el.onload = onload;
el.src = img;
});
URL.revokeObjectURL(url);
};
// Mix in a cache-bust on every run.
imgs = imgs.map(function (img) {
return img + '?ts=' + Date.now();
});
worker.postMessage(imgs);
</script>
</body>
</html>
@Berkmann18
Copy link

Berkmann18 commented Nov 19, 2017

If I understood correctly, this in-worker DOM use is possible thanks to the worker script being passed as a blob or am I missing something?

@Srikanththyagarajan
Copy link

Does this preload supports IE browser

@jamesta696
Copy link

jamesta696 commented Mar 20, 2021

Pretty cool gist, is there a method to preload CSS & JS files? This is only specific to images.
Your feedback is appreciated!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment