Skip to content

Instantly share code, notes, and snippets.

@2j2e
Last active December 11, 2015 15:18
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 2j2e/f9e0d41c7ec954364aa5 to your computer and use it in GitHub Desktop.
Save 2j2e/f9e0d41c7ec954364aa5 to your computer and use it in GitHub Desktop.
PostCSS Image Preloader Plugin
var fs = require('fs'),
path = require('path'),
postcss = require('postcss'),
valueParser = require('postcss-value-parser');
module.exports = postcss.plugin('postcss-image-preload', function (opts) {
opts = opts || {};
if (!Object.keys(opts).length)
return function () {
};
if (!opts.output)
throw new Error('[postcss-image-preload] `output` is required')
return function (css, result) {
var images = [];
if (node.type === 'decl' && node.prop == 'background-image') {
var nodeValue = valueParser(node.value);
nodeValue.walk(function (node) {
if (node.type !== 'function' || node.value !== 'url') {
return;
}
if (!node.nodes.length) {
node.warn(result, [`${node.value} should not be empty`]);
return;
}
if (node.nodes[0].type === 'string' && node.nodes[0].value.indexOf('data:') == -1) {
addImage(images, node.nodes[0].value);
}
});
}
generateJs(opts.output, images);
};
function addImage(list, url) {
if (list.indexOf(url) == -1) {
list.push(url);
}
}
function generateJs(output, images) {
if (!images.length)
return;
var absTemplatePath = path.resolve(__dirname, 'postcss-image-reload-template.js');
var absOutputPath = path.resolve(output);
fs.readFile(absTemplatePath, 'utf8', function (err, content) {
if (err) throw err;
var imageArray = '"' + images.join('","') + '"';
content = content.replace('@imageArray', imageArray);
fs.writeFile(absOutputPath, content, function (err) {
if (err) throw err;
console.log('Preloader file has been saved');
});
});
}
});
function preloader() {
var images = [@imageArray];
for (var i = 0; i < images.length; i++) {
var img = new Image()
img.src = images[i];
}
}
window.onload = preloader;
@ai
Copy link

ai commented Nov 25, 2015

css.walk(function (node) {
      if (node.type === 'decl') {

can be replaced by:

css.walkDecls(function (node) {

@ai
Copy link

ai commented Nov 25, 2015

Also you can use postcss-url with custom callback.

@2j2e
Copy link
Author

2j2e commented Nov 25, 2015

Yes, but I like to have all levers for analysis and solution. Code above was only the first step, next - preloading depends on active media query.

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