johndwells / Minimee

Minimize & combine your CSS and JS files. Minify your HTML. Because size (still) DOES matter.
http://johndwells.github.com/Minimee
56 stars 16 forks source link

LabJS or alternative support? #6

Closed sjelfull closed 11 years ago

sjelfull commented 12 years ago

May this be something for Minimee? http://www.totalserve.net.au/blog/post/automin-with-labjs-compatibility-for-deferred-javascript-parsing

johndwells commented 12 years ago

Hi Fred!

You're the 2nd person in 24hrs to ask. It's actually possible with Minimee v2. I've asked the other person (@tyssen) to post the question in the @devot_ee forums and I'll reply with details on how to use it.

Thanks for the heads up though! Appreciate you thinking of Minimee. :)

Hope all's well! John

On 30 August 2012 11:37, Fred Calsen notifications@github.com wrote:

May this be something for Minimee? http://www.totalserve.net.au/blog/post/automin-with-labjs-compatibility-for-deferred-javascript-parsing

— Reply to this email directly or view it on GitHubhttps://github.com/johndwells/Minimee/issues/6.

Pura Vida John D Wells http://www.johndwells.com

johndwells commented 12 years ago

Actually, I should just demonstrate it here!

So with the V2 beta, there's a new tag exp:minimee:link, which returns just the link to a cached file. It requires first using Minimee's queue="" parameter.

Using the TotalServe's example, in Minimee2 it would be:

{exp:minimee:js queue="labjs"}
    <script type="text/javascript" src="/js/jquery.min.js"></script>
    <script type="text/javascript" src="/js/jquery.custom.js"></script>
{/exp:minimee:js}

... and then, or sometime later ...
<script type="text/javascript" src="/js/LABjs.min.js"></script>
<script>
    $LAB.script("{exp:minimee:link js='labjs'}");
</script>

This also means that you could use the wait() feature of LABjs. Let's look at LABjs' own example:

{exp:minimee:js queue="framework"}
    <script type="text/javascript" src="/js/framework.js"></script>
{/exp:minimee:js}

{exp:minimee:js queue="plugin.framework"}
    <script type="text/javascript" src="/js/plugin.framework.js"></script>
{/exp:minimee:js}

{exp:minimee:js queue="myplugin.framework"}
    <script type="text/javascript" src="/js/myplugin.framework.js"></script>
{/exp:minimee:js}

{exp:minimee:js queue="init"}
    <script type="text/javascript" src="/js/init.js"></script>
{/exp:minimee:js}

... and then, or sometime later ...
<script type="text/javascript" src="/js/LABjs.min.js"></script>
    $LAB
        .script("{exp:minimee:link js='framework'}").wait()
        .script("{exp:minimee:link js='plugin.framework'}")
        .script("{exp:minimee:link js='myplugin.framework'}").wait()
        .script("{exp:minimee:link js='init'}").wait();
</script>

Hope that makes sense!

Cheers, John

tyssen commented 12 years ago

That's pretty cool and would help with conditionally loading scripts for different sections as you can use EE conditionals in the template (I never use EE for CSS or js templates, always use flat files).

Although if you're using Minimee to collate all your scripts into a single file, and on one page you add in a different script that's only needed for that page, that's going to make Minimee output a different file, so the browser would be downloading all that data for scripts it's already downloaded just because a new script has been added. Or do you output the new script on its own and have the browser take the extra http request?

What's your thoughts on that?

johndwells commented 12 years ago

Hey John,

That's a good point - my approach is to keep it as a separate file, and "suffer" the extra http request. Either that or simply have it always bundled with the site's core JS.

Alternatively, I often will simply output that extra JS inline with the HTML, either by minifying & embedding it with Minimee, or having the JS as part of my template to begin with.

Frankly I haven't yet started to work with things like requireJS or LABjs, they don't really suit our needs. I'm also trying to cut down on more and more JS dependencies. What's your experience with them?

Cheers, John

tyssen commented 12 years ago

I was using Headjs for a while but switched over to LABjs recently which has a lot more flexibility which I've only just skimmed the surface of so far. I'm not an expert with them by any means, still feel like I'm finding my way with them.

johndwells commented 11 years ago

Gents,

I thought I'd mention that I'm finally releasing Minimee2 this week. I've just created a new Docs page: http://johndwells.github.com/Minimee.

The release is actually quite evolved from what has been sitting on the V2 branch for some time, but I've made a concerted effort to keep it entirely backwards-compatible with M1 configuration & usage.

In addition, I've introduced a new tag which allows for better integration with LABjs (or RequireJS, etc). I've written up an example on that docs page.

As always, interested in feedback!

Cheers, John

tyssen commented 11 years ago

Looks awesome! So is that available now or later in the week?

I notice you've modified your example for LABjs so it doesn't use queue any more. I'm having trouble getting my head around when you'd use queue. Could you give a more specific example of the sort of situations you'd use it in?

johndwells commented 11 years ago

Hi John,

It's available now up on Github, but by EECI I'll have it updated on @devot-ee and my own site.

I wanted you to know that I've made a big effort to not only be compatible with earlier versions of 2.x, but also 1.x as well - even though the docs might lead you to think that tags have changed or been removed (e.g. exp:minimee:embed), in reality everything is still there. A lot of alias tags and legacy protection has been put in place so that - hopefully - upgrades for everyone will be smooth as butter.

So in regards to Queueing, the idea is that if your site didn't "know" all of the assets that might need to be included until your template, snippets & embeds were all parsed, then Queue would allow you to "collect" these assets and then cache them only once ready.

Considering the "traditional" (non-partials) way of building out an EE site, you would likely have and _embed_head.html containing all of your <head> CSS links, and then another _embed_foot.html containing your footer and scripts.

Let's say then you have a Login page which, when displayed, needs an extra CSS file. To get that included, you might pass an embed variable as a "switch" to let _embed_head.html know to include it:

{embed='embeds/_embed_head.html' show_login_css='yes'}

And then within that embed:

{if {embed:show_login_css} == 'yes'}
    {exp:minimee:css}
        <link href="styles/login.css" />
    {/exp:minimee:css}
{/if}

Which works just fine, but your embed would have to be "aware" of every possible CSS asset that you may need to include. Moreso, each asset would have to be processed by Minimee separately (e.g. you'd have an if+minimee block for every one). This complexity doubles when you'd have to do the same for your JS in the footer.

Enter Queueing. Stepping back to the first code sample, we could do:

{embed='embeds/_embed_head.html'}

{exp:minimee:css queue='head_css'}
    <link href="styles/login.css" />
{/exp:minimee:css}

And then the embed would simply contain:

{exp:minimee:display css="head_css"}

Of course you could also "queue" more assets as you go, and they'd all be minified and combine upon output.

If that's all still making sense, I should raise a caveat: I would not do this approach when "building" your site's master CSS or JS files. Each new asset added to the queue creates a new cache name, and therefore a new cache file. If every page of your site included a different combination of assets, then each would have its own cache file that your visitor would have to download time and again (albeit minified).

Better would be to keep "core" assets cached together and constant, and use Queue for just the one or two assets on occasion that might need to be dropped in.

TBH, what I usually do in that case is use Stash and simply embed the code inline, which saves down on one more HTTP request.

I sure hope that makes sense!

Cheers, John

tyssen commented 11 years ago

Ah so the queue means EE is globally aware of the file without the need to pass it between templates with an embed or Stash variable? If that's the case, good to know, although I don't think it's a situation that's caused me too much trouble in the past.

Anyway, grabbing the latest version now.

Cheers John

johndwells commented 11 years ago

John - I should also mention another time Queue can come in very handy, and that is when you need to specify different settings for different files of what will eventually become a single cache resource.

For example, Minimee by default re-writes all relative image & @import URLs to be absolute to the site's Base URL, meaning:

/* before Minimee */
img { background-image: url(../img/icon.png); }
/* after */
img { background-image: url(http://yoursite.com/img/icon.png); }

But if you are including assets from multiple domains, and some of those external domains also are using relative URLs, these should not be rewritten to your Base URL, rather they should be rewritten to their own root domain URL.

The way to handle this is to Queue your assets first, breaking each queue up by domain, and passing via parameter any settings necessary (e.g. css_prepend_url="http://othersite.com").

Then you package it all up with a single call to exp:minimee:display and you're set. There's an example of this in the online docs...

Cheers, John

tyssen commented 11 years ago

Excellent, sounds good. :)