1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-09-20 01:08:50 +02:00

Automatically inline small images using data URIs

Summary: Fixes T3300. Images under 32KB are inlined automatically into CSS using data URIs; larger images remain as normal links. I picked the 32KB threshold arbitrarily, based on it looking roughly like it got reasonable results on `core.pkg.css` (inlining most of the random stuff, but not inlining all the 2X sprites and such).

Test Plan: Loaded site, browsed around, looked at generated CSS.

Reviewers: btrahan, chad

Reviewed By: chad

CC: aran

Maniphest Tasks: T3300

Differential Revision: https://secure.phabricator.com/D8225
This commit is contained in:
epriestley 2014-02-13 17:39:47 -08:00
parent e88d0f9c42
commit 005d194cd2

View file

@ -129,7 +129,14 @@ final class CelerityResourceTransformer {
if ($this->celerityMap) {
$resource_uri = $this->celerityMap->getURIForName($alternative);
if ($resource_uri) {
$uri = $resource_uri;
// Check if we can use a data URI for this resource. If not, just
// use a normal Celerity URI.
$data_uri = $this->generateDataURI($alternative);
if ($data_uri) {
$uri = $data_uri;
} else {
$uri = $resource_uri;
}
break;
}
}
@ -226,4 +233,51 @@ final class CelerityResourceTransformer {
return implode("\n\n", $rules);
}
/**
* Attempt to generate a data URI for a resource. We'll generate a data URI
* if the resource is a valid resource of an appropriate type, and is
* small enough. Otherwise, this method will return `null` and we'll end up
* using a normal URI instead.
*
* @param string Resource name to attempt to generate a data URI for.
* @return string|null Data URI, or null if we declined to generate one.
*/
private function generateDataURI($resource_name) {
$ext = last(explode('.', $resource_name));
switch ($ext) {
case 'png':
$type = 'image/png';
break;
case 'gif':
$type = 'image/gif';
break;
case 'jpg':
$type = 'image/jpeg';
break;
default:
return null;
}
// In IE8, 32KB is the maximum supported URI length.
$maximum_data_size = (1024 * 32);
$data = $this->celerityMap->getResourceDataForName($resource_name);
if (strlen($data) >= $maximum_data_size) {
// If the data is already too large on its own, just bail before
// encoding it.
return null;
}
$uri = 'data:'.$type.';base64,'.base64_encode($data);
if (strlen($uri) >= $maximum_data_size) {
return null;
}
return $uri;
}
}