Last active
September 22, 2021 08:53
-
-
Save dfkaye/5948735 to your computer and use it in GitHub Desktop.
use data URIs to inline all your JavaScript to production
This file contains hidden or 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
| 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 |
A couple things:
- 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
textproperty. To sum up, I'm not sure what the conversion to data URI buys you in this scenario. - IIRC, not all browsers allow data URIs to be used as a script source.
- 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.
Thx again ~ looking for any perf diffs btwn script.src=dataURI vs src=aUrl ~ but script.text=srcText is defnitely better :)
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
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?