[ 8 posts ]

Jeroen Versteeg

YUI Contributor

  • Username: jayvee
  • Joined: Tue Aug 24, 2010 12:01 am
  • Posts: 15
  • Location: Utrecht, Netherlands
  • Twitter: asystance
  • GitHub: asystance
  • Gists: asystance
  • Offline
  • Profile

Multi YUI instances - what's the best practice?

Post Posted: Tue Aug 24, 2010 12:51 am
+0-
Hey,

I just started using YUI 3 for our web app and enjoy developing so far. I've come across one really weird issue, which brought up the question of whether to use multiple YUI instances or not.

Let me show you what I did first:
Code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>

<head>
  <script type="text/javascript" src="yui.js"></script>
  <script type="text/javascript" >
    function log ( msg ) {
      document.getElementById( 'log' ).value += msg + "\n";
    }
  </script>

  <script type="text/javascript" src="util/javascript/test.js"></script>

  <script type="text/javascript" >
    YUI().use( 'event-base' ).on( 'domready', function () { log('head section inline code'); } );
  </script>
</head>

<body>

  <script type="text/javascript">
    YUI().use( 'event-base' ).on( 'domready', function () { log('pre-textarea inline code'); } );
  </script>

  <textarea id="log" cols="60" rows="30"></textarea>

  <script type="text/javascript">
    function someFunc () {
       log( 'post-textarea inline code' );
    }
    YUI().use( 'event-base' ).on( 'domready', someFunc );
  </script>

</body>
</html>


In this example, log function is not called in the order you would expect (the code in test.js was called last). I had this working in a test script and could not figure out what the difference was, until I finally saw that I had used
Code:
YUI.use()  // instead of YUI().use()

which made it work.

The documentation seems to suggest that you should use separate YUI instances, so I created a new instance for pretty much every call to YUI.

So what is the best practice concerning instantiation of YUI? Is it "ok" to just use
Code:
var Y = YUI().use( '*' );

And use this (global) instance everywhere? This works great in the example I listed above, but is it really the way to go?

Caridy Patino

YUI Contributor

  • Username: caridy
  • Joined: Mon Dec 08, 2008 5:40 pm
  • Posts: 491
  • Location: Miami, FL
  • Twitter: caridy
  • GitHub: caridy
  • Gists: caridy
  • IRC: caridy
  • YUI Developer
  • Offline
  • Profile

Re: Multi YUI instances - what's the best practice?

Post Posted: Tue Aug 24, 2010 6:53 am
+0-
Hey Jeroen,

This is a very good question, actually many folks have the same dilemma. And there is not an answer for that. It depends on your application. From my point of view, there are few things you have to evaluate:

- Who controls your deployment?
- How many people/teams work on your project?
- What kind of dev process are these teams using?
- What kind of performance optimization are you planning to do for production?

And certainly many more questions.

Now, other things that you should know:

- No matter how many YUI instances you have, the loader and the metadata is global, and will be queue unless you use complete different yui versions in the same app.
- Y.Global provides a communication pipeline between different instances, even if those instances are running different versions of yui3.
- Don't assume global, instead wrap with XYZ.use ();

That said, I always recommend to use a single instance for webpages (or simple web apps). And having an application layer (maybe a YUI instance) to control the whole application, and having specific behaviors using other YUI instances that can send or receive messages from the app layer at any given time (maybe through Y.Global).

Best Regards,
Caridy

Jeroen Versteeg

YUI Contributor

  • Username: jayvee
  • Joined: Tue Aug 24, 2010 12:01 am
  • Posts: 15
  • Location: Utrecht, Netherlands
  • Twitter: asystance
  • GitHub: asystance
  • Gists: asystance
  • Offline
  • Profile

Re: Multi YUI instances - what's the best practice?

Post Posted: Wed Aug 25, 2010 12:56 am
+0-
Caridy, thanks for the quick answer.

caridy wrote:
This is a very good question, actually many folks have the same dilemma. And there is not an answer for that. It depends on your application. From my point of view, there are few things you have to evaluate:

- Who controls your deployment?
- How many people/teams work on your project?
- What kind of dev process are these teams using?
- What kind of performance optimization are you planning to do for production?

And certainly many more questions.

We're a team of two developing a web app that doesn't need high performance, so I'd like to make developing with YUI as easy as possible.

caridy wrote:
- No matter how many YUI instances you have, the loader and the metadata is global, and will be queue unless you use complete different yui versions in the same app.
- Y.Global provides a communication pipeline between different instances, even if those instances are running different versions of yui3.

Well if that's so than I spotted a bug! Check this example (basically a working version of the code in the opening post). I would expect the different scripts to be executed in the order they appear in the document. If I use a global instance, this is exactly what happens!

As I said in the opening post, if I use "YUI.use()" (instead of "YUI().use()") everywhere, the code works as expected. But is that a bug or a feature?

caridy wrote:
- Don't assume global, instead wrap with XYZ.use ();

What do you mean with XYZ?

caridy wrote:
That said, I always recommend to use a single instance for webpages (or simple web apps). And having an application layer (maybe a YUI instance) to control the whole application, and having specific behaviors using other YUI instances that can send or receive messages from the app layer at any given time (maybe through Y.Global).

That sounds like a good idea for js-driven apps, but it's a bit overkill for ours. We just want to enhance usability here and there and use one library for cookies, AJAX requests, DOM enhancements, tabs, etc.

Like I described, if I use different instances, the domready events don't fire in order, so I was wondering if adding
var Y = YUI().use( '*' );
to the bottom of yui.js and using Y everywhere is considered a bad practice with significant drawbacks.

Kind regards,
Jeroen

Caridy Patino

YUI Contributor

  • Username: caridy
  • Joined: Mon Dec 08, 2008 5:40 pm
  • Posts: 491
  • Location: Miami, FL
  • Twitter: caridy
  • GitHub: caridy
  • Gists: caridy
  • IRC: caridy
  • YUI Developer
  • Offline
  • Profile

Re: Multi YUI instances - what's the best practice?

Post Posted: Wed Aug 25, 2010 8:41 am
+0-
Hey Jeroen,

That's not a bug, that's a mistake in the definition that you're using in your first example:

Basically, you're assuming the .on will be available immediately, which is not the case:

Code:
YUI().use( 'event-base' ).on( 'domready', function () { log('head section inline code'); } );


This is an async process, and that's why you should use a callback, and that's also why you can't control the order or execution. Should be like this:

Code:
YUI().use( 'event-base' , function(Y) {
  Y.on( 'domready', function () { log('head section inline code'); }
});


But still, has a mention, the order will be a problem for you. I don't know the exact reasons why the order is important for you, but anyway. Now, why global.html works? well, in a single instance, every listener will be executed in the order in which they were defined, which is what you want.

I think, for an small application that will be a good option.

Best Regards,
Caridy

Caridy Patino

YUI Contributor

  • Username: caridy
  • Joined: Mon Dec 08, 2008 5:40 pm
  • Posts: 491
  • Location: Miami, FL
  • Twitter: caridy
  • GitHub: caridy
  • Gists: caridy
  • IRC: caridy
  • YUI Developer
  • Offline
  • Profile

Re: Multi YUI instances - what's the best practice?

Post Posted: Wed Aug 25, 2010 8:46 am
+0-
Btw, wraping with XYZ.use was just a statement. What It means is that you should wrap any YUI related code into a YUI().use() statement.

Code:
YUI().use('module1', 'module2', function(Y) {
  // now you can assume that module1 and module 2 are ready to be used.
  // and you can do lazy load here again
  Y.use('module3', function() {
      // now you can assume that module3 is ready to be used.
  });
});


Best Regards,
Caridy

Luke Smith

YUI Contributor

  • Username: lsmith
  • Joined: Thu Aug 28, 2008 7:50 am
  • Posts: 507
  • Location: Sunnyvale
  • Twitter: ls_n
  • GitHub: lsmith
  • Gists: lsmith
  • IRC: ls_n
  • YUI Developer
  • Offline
  • Profile
Tags:

Re: Multi YUI instances - what's the best practice?

Post Posted: Wed Aug 25, 2010 9:54 am
+5-
For small application development in a controlled environment, it's not bad practice to use a shared global Y. You just need to remember that (barring the exception I'll mention in a sec) Y.use('the','modules') is asynchronous. The APIs for the requested modules won't be available immediately following the call to use(). That's the purpose of the callback passed as the second param.

Code:
var Y = YUI();
Y.use('node','io-base', function () {
    /* node and io APIs are ready for use */
});

// node and io APIs are NOT available here
Y.one("#boom");


The exception to this that I hinted at is if you include the module script(s) in the source either as additional <script> tags or combo'ed with the yui-min.js file. You can use the Configurator to help produce the appropriate combo <script>. In this case, the use() call WILL be synchronous because YUI doesn't need to fetch any additional resources. So...

Code:
<script src=".../combo?yui-min.js&node.js&io-base.js"></script>
<script>
var Y = YUI();
Y.use('node', 'io-base'); // makes no async resource requests.  Happens immediately

Y.on("domready", function () {
    Y.one('#works_fine');
    ...


All that said, the recommended pattern of use is to localize logic in modules, and have one YUI instance that uses these modules and vivifies the page with the APIs provided in the modules. Using multiple YUI instances is mostly only beneficial when you have some code that you want to be isolated and untamperable by other code on the page.

I prefer not to use('*'), but (again) for controlled environments, that should be ok. Have a look at Dav Glass's quick_yui.js script on GitHub
HTH,
L

Jeroen Versteeg

YUI Contributor

  • Username: jayvee
  • Joined: Tue Aug 24, 2010 12:01 am
  • Posts: 15
  • Location: Utrecht, Netherlands
  • Twitter: asystance
  • GitHub: asystance
  • Gists: asystance
  • Offline
  • Profile

Re: Multi YUI instances - what's the best practice?

Post Posted: Thu Aug 26, 2010 7:55 am
+0-
Thanks a lot for all your replies Caridy and Luke!

caridy wrote:
That's not a bug, that's a mistake in the definition that you're using in your first example:

Basically, you're assuming the .on will be available immediately, which is not the case:

Code:
YUI().use( 'event-base' ).on( 'domready', function () { log('head section inline code'); } );


This is an async process, and that's why you should use a callback, and that's also why you can't control the order or execution. Should be like this:

Code:
YUI().use( 'event-base' , function(Y) {
  Y.on( 'domready', function () { log('head section inline code'); }
});


Ok, I see that my use of YUI caused the problem. I don't understand at all why the order of calls is in reverse though, but let's just accept that if I don't play by the rules, quirky behavior is the appropriate punishment :)


caridy wrote:
But still, has a mention, the order will be a problem for you. I don't know the exact reasons why the order is important for you, but anyway.

I use a library called mktree which converts a <ul> into a expandable / collapsable tree. So on every page load, the library scours the page for lists to convert. That's the first call. The second call is output dynamically (if the user is editing the form where an option from the tree was selected) and expands the tree to show a particular item and highlights it. This second call must be made after the tree has been converted.

I think this might be common pattern. One call does setup, the second assumes setup has been done. Of course it would be nicer to create a setup function which takes one (or more) callbacks as arguments instead of doing the calls, but that's the way it's written right now.

caridy wrote:
What It means is that you should wrap any YUI related code into a YUI().use() statement.

Ok, that's what I thought you meant. I actually don't like that elaborate setup because it makes simple code a lot harder to read. For example, if all I want to do is get a cookie, I'd prefer that to not take more than one simple line of code. That's why I'm looking for a way to do the initialization of one YUI instance once and use that everywhere.

caridy wrote:
Now, why global.html works? well, in a single instance, every listener will be executed in the order in which they were defined, which is what you want.

I think, for an small application that will be a good option.

lsmith wrote:
The exception to this that I hinted at is if you include the module script(s) in the source either as additional <script> tags or combo'ed with the yui-min.js file. You can use the Configurator to help produce the appropriate combo <script>. In this case, the use() call WILL be synchronous because YUI doesn't need to fetch any additional resources.

That's exactly what I've done in the second example, and also add var Y = YUI().use( '*' ); to the end of yui.js, and use that global variable everywhere I need it.

That makes code easy to read, as I don't require the setup-with-callback, and all the calls are synchronous.

Dav Glass's quick_yui.js looks easy and clean, but since I load every module we need, what's the advantage of using this over of my "naive" one-liner initialization? As far as I can tell, quick_yui makes sure calls are made synchronously, but since I've loaded everything I need, YUI().use() is synchronous anyway, right?

Luke Smith

YUI Contributor

  • Username: lsmith
  • Joined: Thu Aug 28, 2008 7:50 am
  • Posts: 507
  • Location: Sunnyvale
  • Twitter: ls_n
  • GitHub: lsmith
  • Gists: lsmith
  • IRC: ls_n
  • YUI Developer
  • Offline
  • Profile

Re: Multi YUI instances - what's the best practice?

Post Posted: Tue Aug 31, 2010 11:35 am
+0-
Yeah, your second example is a perfectly reasonable application of YUI 3 using a shared global Y.
  [ 8 posts ]
Display posts from previous:  Sort by  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum