Skip to content

Instantly share code, notes, and snippets.

@dfkaye
Last active September 22, 2021 08:53
Show Gist options
  • Save dfkaye/5948735 to your computer and use it in GitHub Desktop.
Save dfkaye/5948735 to your computer and use it in GitHub Desktop.
use data URIs to inline all your JavaScript to production
8 JUL 2013
Couldn't sleep - kept thinking about modules with blobs, workers, data:URIs - then realized this was
staring us in the face this whole time, verified it with firebug and some test code, wrote the gist
down - now go build it.
Starts with Tobie Langel's lazy evaluation of JS ~
http://calendar.perfplanet.com/2011/lazy-evaluation-of-commonjs-modules/
and Tom Dale's http://tomdale.net/2012/01/amd-is-not-the-answer/
Each of those proposes | implements a build step that creates a map in JS of files matching source names
or paths to an inlined string of their actual source:
files['/path/to/source/file.js'] = 'var x = require("something.js"); module.exports = /* etc */ ';
In the browser, these are downloaded but not parsed/evaluated by the JS engine until they are first "required"
by another module. As both writers address commonJS, their process resembles this:
function process(path) {
// caching logic omitted for brevity
var source = files[path];
var factory = Function("function(module, exports, require) {" + source + "}");
var module = new Module(path);
factory.call(module, module.exports, module.require)
}
SO WHAT - What's *NEW* in this gist?
Instead of file source as text, convert it to dataURI strings instead.
Involves:
+ For each JavaScript source file, run compression - http://closure-compiler.appspot.com/home
+ Convert compressed version to base64 (see Hixie's data URI kitchen, for example) -
http://software.hixie.ch/utilities/cgi/data/data
Leave default type as text/plain charset utf8
Select Base 64 encoding
> Generate <
data:text/plain;base64, etc etc
+ Copy the generated URI to the mapping of filenames (assuming you're doing it Langel's & Dale's way)
files['/path/to/source/file.js'] = dataURI
+ Use a client-side loader to evaluate | return required files from the map:
// caching logic omitted...
function load(path) {
var dataURI = files[path], d = document, s = d.createElement('script');
s.onload = function (e) {
console.log(e)
};
s.src = dataURI;
d.documentElement.firstChild.appendChild(s);
}
You can view a quick and dirty test page that uses the dataURI technique (without the load/require
commonjs support but with a big source file)
here => https://rawgithub.com/dfkaye/datauri-vs-src-test/master/index.html
Further work -
FOR WORKERS, use blobs as per http://www.html5rocks.com/en/tutorials/workers/basics/#toc-inlineworkers-bloburis
NEXT STEP - figure out decoding to source - hard to debug of course - dataURI? - but so are compressed/minified files
@dfkaye
Copy link
Author

dfkaye commented Jul 12, 2013

Question for Certain Readers ~ Other than debuggging, polyfills and fallbacks for browser support - what are the performance implications of using dynamic script append strategy with URLs vs dataURIs? For sites with multi-file bundles (the current curse), would the dataURI approach perform better than URLs?

@nzakas
Copy link

nzakas commented Jul 12, 2013

A couple things:

  1. Converting to data URI/base64 actually makes the text bigger. I'm not sure that there's much value in doing that over, say, just using the minified JS source text and inserting it into a script node via the text property. To sum up, I'm not sure what the conversion to data URI buys you in this scenario.
  2. IIRC, not all browsers allow data URIs to be used as a script source.
  3. If it works, debugging shouldn't be a problem in modern browsers, they will treat it as a interpreted code and you can step through it like any other.

I guess overall, I'm just not sure what sort of improvement you are looking with this over the things you reference at the beginning.

@dfkaye
Copy link
Author

dfkaye commented Jul 12, 2013

Thx again ~ looking for any perf diffs btwn script.src=dataURI vs src=aUrl ~ but script.text=srcText is defnitely better :)

@jakubrpawlowski
Copy link

I was thinking about it a lot recently. I think we should be encoding Javascript as UTF-8 with percent-encoding (https://en.wikipedia.org/wiki/Percent-encoding) to escape certain characters. You may say it will make a file much larger but (from my initial research) it actually doesn't because the way gzip works- it replaces the repetition and it doesn't matter if the repeated phrase is <div> or %3Cdiv%3E. My goal is to inline entire framework into index.html.

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