andrewdavey / cassette

Manages .NET web application assets (scripts, css and templates)
http://getcassette.net
MIT License
536 stars 144 forks source link

Explicit references in scripts should include/concatenate/minify referenced script #240

Closed evandavis closed 12 years ago

evandavis commented 12 years ago

Asset references, as implemented, inform the ordering of included bundles but do not actually include the bundle.

I would like to be able to include scripts into a minified bundle using inline asset references in JavaScript files, not Bundle.Reference() in a view. This would allow Cassette to serve as both an optimization and a dependency management tool.

andrewdavey commented 12 years ago

I'm not sure I completely understand. Cassette does both optimization and dependency management.

How have you configured Cassette in the CassetteConfiguration.cs file?

evandavis commented 12 years ago

Yes, I have.

Here is what I'm trying to achieve:

/Scripts
    /Core
        bundle.txt
        app.js
        util.js
        constants.js
        jquery.js
    /Modules
        maps.js
        widget.js
    /Plugins
        jquery-ui.js
        highcharts.js
    /Views
        /Home
            index.js

Given this heirachy, my page will include the Core bundle (concat/minified) and the appropriate file from Views/Home to match the {controller}/{action} in my MVC routing. If index.js requires highcharts.js from Plugins and widget.js from Modules, I'd like to serve a single concatenated, minified file to the browser without having to configure every possible combination in CassetteConfiguration.cs.

Rather, I would like for the references in a single script file to be automatically included in the bundle for that file.

andrewdavey commented 12 years ago

The issue with that approach is that you'll be potentially serving the content of Plugins more than once.

By having Plugins as its own bundle you can better leverage browser caching. The first page will download Plugins (and the page-specific bundle), then the next page only has to download its page-specific bundle, Plugins is already in browser cache.

I'm assuming that shared bundles like Core and Plugins tend to be larger that page-specific bundles. So it makes sense to want them cached aggressively.

evandavis commented 12 years ago

This is a limited example. Our application is huge and has over 25 plugins which I would prefer not to serve everywhere. The same with modules; I don't want that code to be included/run everywhere.

A realistic example for us is needing to load 4-5 disparate plugins and modules, meaning I'm loading up to 7 scripts (core, view, and plugins/modules) instead of 2 (core bundle, view bundle).

kamranayub commented 12 years ago

Why, though? I can understand modules, I would use AddPerIndividualFile for that. But plugins? I get what you're saying but like @andrewdavey said, you're running the risk of making users re-download the same plugin they already downloaded in the last page. It would be better to treat plugins as a single bundle, even if you have 50 of them... because users will probably need all 50 if they're traversing your site. Yes, they will take the upfront cost of downloading the bundle... but then they won't ever again until you release a new plugin bundle version. In your model, I could download the same plugin 3 times and multiply that by all your 25 plugins and you're making me download more than I would have had you not just used a single bundle.

Otherwise you could modularize your plugins and bundle them according to a workflow or something; so you reference a plugin bundle in your scripts rather than individual plugins.