assetgraph / assetgraph-builder

AssetGraph-based build system for web apps and web pages.
BSD 3-Clause "New" or "Revised" License
489 stars 42 forks source link

Option to inline everything #105

Closed jbeard4 closed 11 years ago

jbeard4 commented 11 years ago

I would like to use assetgraph-builder to work around an issue with the Appcelerator Titanium WebView.

WebView will work better if it doesn't need to fetch external resources. I would therefore like to use assetgraph-builder to inline all script tags and CSS, regardless of size. I would also like it to inline <img> tags using data URI.

I saw in the options to buildProduction that there is an option --inlinesize, but this only seems to apply to CSS for background images. Is there a way to force all JavaScript to be inlined? Also, is there a way to inline <img> tags as data URI?

papandreou commented 11 years ago

Currently this isn't exposed via command line options, sorry, but it would be quite easy to add, including inlining of <img src=...>, <picture><source src=...></picture> and even <img srcset=...> as that's already supported by the underlying framework. It'd even work for HTML documents linked via <iframe src=...>, but it sounds like the Titanium problem only concerns scripts.

Indeed, the only exposed knob is the --inlinesize switch, which only sets the inlining threshold for CSS images. For JavaScript and CSS it's more or less arbitrarily hardwired at 8 KB: https://github.com/One-com/assetgraph-builder/blob/master/lib/transforms/buildProduction.js#L96-L100

A colleague of mine asked me for pretty much the same feature less than a week ago, so I'm very likely to implement it soon :). If you're impatient, @Munter did a project based on AssetGraph a while ago: https://github.com/Munter/inliner -- that might work as a postprocessor to the buildProduction output.

And of course -- patches welcome. I guess it would make the most sense to rename --inlinesize to something more specific and add separate switches for defining the threshold for JavaScript and CSS.

Currently the inlining of CSS images includes a fallback for old browsers that don't support data: urls. I can't think of a good way to support something equivalent for <img src=...> and the like, so I'd like for that switch to be off by default.

Munter commented 11 years ago

My inliner project is a fork on Remy Sharps. And I'm pretty certain it doesn't cover half as many cases as assetgraph does out of the box. A complete inlining of everything could easily be attained with an extra transform run that just inlines all relations, like seen in this part of assetviz: https://github.com/Munter/assetviz/blob/master/index.js#L122-L138

papandreou commented 11 years ago

@Munter: Ah, sorry for the misremembrance ;)

In 1.8.0beta37 I added switches for finer-grained control of what gets inlined.

Inline everything that supports it: buildProduction --inline yes Inline everything that supports it if less than 8192 bytes: buildProduction --inline 8192 Inline all <script src=...>: buildProduction --inlinehtmlscript yes Inline all stylesheets less than 4096 bytes: buildProduction --inlinehtmlstyle 4096

etc.

@jbeard4: Let me know if that takes care of it. I have a feeling that a point blank --inline yes might actually inline a bit too much (includes cache manifests, shortcut icons, <object>, <embed>, <a href=...>, <iframe src=...> etc.). To just inline all scripts, stylesheets, CSS images, and <img src=...>, try: buildProduction --inlinehtmlscript yes --inlinehtmlstyle yes --inlinecssimage yes --inlinehtmlimage yes

papandreou commented 11 years ago

The supported --inline... switches are derived from the relation names (lower cased): https://github.com/One-com/assetgraph/tree/master/lib/relations