0

I was wondering what was the best way to call a function when the DOM was ready. I mean, I know that

$(document).ready(function(){})

and

$(function(){})

were the same way to implement the action ready of the DOM. My question is more about performance, I usually wrote my JS like this :

$(document).ready(function(){
    console.log('Hello World');
});

But a teacher once tryed to make me change my mind and write like this :

function main(){
    console.log('Hello World!');
}
$(document).ready(main);

The truth is I never did that but now I am wondering what is the best way in terms of performance... If I put everything in an external function does it load faster?

In fact I was writting as the first way because I don't want my functions to be accessible from the DOM so I was doing this :

$(document).ready(function(){
    function Hello(){
            console.log('Hello World');
    }
    Hello();
});

In this way it's impossible to use the function Hello from the DOM or from the console... And so I didn't like my teacher's way. But now I use to encapsulate all my code in an anonymous function and in this way I'm more cumfortable to write like this :

(function($){
    function Hello(){
        console.log('Hello World!');
    }
    $(document).ready(Hello);
})(jQuery);

And that's why I was wondering about performance between the two methods, what do you guys think?

Simon Trichereau
  • 721
  • 11
  • 19
  • 1
    There is zero difference in performance with any of these. Personally I prefer `$(function() { /* code here... */ });` simply as it saves a few bytes. Also note that your IIFE can be removed as the document.ready handler accepts a `jQuery` object as it's first argument, ie. `jQuery(function($) { /* code here... */ });` – Rory McCrossan Jan 29 '18 at 15:42
  • Only difference may be, that you have a named function `main` and a `closure` on the other hand, what may save a _bit_ in memory. Otherwise, no difference. The bigger problem ist, that you will mostly not need the `ready states`. Most people will use them just always, but they are not always necessary. To just encapsulate code an `IIFE` is a better choice ... – eisbehr Jan 29 '18 at 15:43
  • Beside this, using ready states without knowing what it does in fact [can harm your page even more](https://stackoverflow.com/questions/38585373/why-is-my-load-event-function-not-beeing-executed-after-switching-to-jquery-3). – eisbehr Jan 29 '18 at 15:47
  • Just include your script right before

    - that way the DOM will already be loaded, and your script won't slow down loading before it's even needed.

    – powerbuoy Jan 29 '18 at 15:58
  • @powerbuoy I don't like to put the script in the body for one reason. If you put it in the head I know it's blocking the loading of the static page, but If you put it in the body and it lasts a lot to load, then your actions on the dom are not initialized but the user can manipulate it.... For example, if you have a form and in JS you're making a client side validation, if the JS is not loaded but the HTML is, the user can overpass your validation.... – Simon Trichereau Jan 29 '18 at 16:03
  • While that's true, if you follow progressive enhancement (which imo you definitely should!) that doesn't matter. Validation for example obviously needs to be handled by the backend eventually anyway, and the required attribute works well cross browser now. If you enhance the validation with JS, and once every hundred times it doesn't have time to kick in, that really isn't a problem. – powerbuoy Jan 29 '18 at 16:06
  • Actually, because you're running your code inside domready anyway, the same thing could theoretically happen even if you include the script in head. The user could start interacting with a form before domready. – powerbuoy Jan 29 '18 at 16:09
  • Well in fact you're right, but normally the navigator stop loading the page while the script is not loaded, so normally when the dom is ready your script is yet loaded and can be executed... But i read that ready is now asynchronus so I think you're right... – Simon Trichereau Jan 29 '18 at 16:18

3 Answers3

0

TL;DR;

Do whatever you like! There is no such impact to your site.

What COULD be the best way?

In general, you can do whatever you like, but there are some facts that lead us in the right direction, which tells us, that jQuery(function($) {}); is a pretty good choice!

Why? Let's see ...

Fact 1: It's the most shortest way. Okay, an IIFE might be shorter, but this is not a real ready state, just an immediately function call.

Fact 2: It is the preferred way to write a ready state by jQuery itself. Since v3 it's mentioned to use this way.

Fact 3: Why would you use an IIFE to pass in the jQuery object? It's not needed, because the first function parameter is the jQuery object.

Fact 4: It is good to use and to work with and without jQuery noConflict mode. Because the first parameter is the jQuery object, you can always work with $ inside of the ready state, and only have to write jQuery once.

Fact 5: You don't use a named function, just an anonymous closure. In nearly 99,99% of all cases, you only use the ready state handler once. So there is no need for a named function or a function stored inside a variable.

So in my opinion, this is the best choice in general:

jQuery(function($) {
    // ...
});
eisbehr
  • 12,243
  • 7
  • 38
  • 63
0

I know that ready could not be used but I have some cases that I would like to use it.. Let me show you eisbehr ... Imagine we have a function calculating the width and the height of the windows, I would like to call it on the ready state, but also on the resize state... SO If I understand your logic, I should use this :

jQuery(function($){
    var width;
    var height;
    function init(){
        width = $(window).width();
        height = $(window).height();
    }
    init();
    $(window).resize(init);
});

Right? Well I think I will continue like I did for now :

(function($){
    var width;
    var height;
    function init(){
        width = $(window).width();
        height = $(window).height();
    }
    $(document).ready(init); /* or $(init); */
    $(window).resize(init);
})(jQuery);

By the way, thanks for your answer, you correctly answer this: what is the best way? Doesn't matter. Do whatever you like! There is no such impact to your site.

Simon Trichereau
  • 721
  • 11
  • 19
  • Well, actually I would do it [like this](https://jsfiddle.net/26uk07ho/). ;) Your way of wrinting is very rare seen. It's not wrong in any way, but not the way you would see it often. Only thing is, that things like `$(window).resize(init);` as to be placed inside the `init` function too. Otherwise it could have the same problems, as using no ready-state at all. – eisbehr Jan 29 '18 at 16:18
  • Hmmm I understand, well to be honnest I normally never write my scripts like this, I'm more comfortable [this way](https://jsfiddle.net/3f4trtwy/), but I understand your logic and I think I like to be complicated :P – Simon Trichereau Jan 29 '18 at 16:24
  • Another thing should be keepd in mind: while the ready state of jQuery is ansynchronous, the IIFE is not. It will be executed directly, meaning that every code inside is handled directly! In you example it makes no difference. But if you would have large or blocking code there, the bwoser will stop till he is finished with the IIFE. As said, just to keep in mind ... – eisbehr Jan 29 '18 at 16:26
  • @eisbehr in fact this is what I'm looking for, and I didn't know that .ready was now asynchronous... So I will prefer the IIFE method. As I said to powerbuoy if you need the JS to be load before the html content, it's better to use the IIFE, I took the example of a client side validation, you don't want the user to send the form because your validating script was not loaded... But there are lots of other cases – Simon Trichereau Jan 29 '18 at 16:30
  • As said, just good to know. If you know what you do, it's okay. Personally I'm not your opinion and would stay with powerbuoy. You're talking mostly from milliseconds, no time to post a form or something. But with an IIFE you're risking stottering, loading delays and lags, whats not nice for the user and will let you page look like bad coded. But it's up to you how you do things, if you know, what you are doing! ;) – eisbehr Jan 29 '18 at 16:35
-2

Its really up to preference if you want to define the ready function in another place, the performance difference is almost non-existent. I personally prefer

$(document).ready(function(){
    //code for ready should be in here
});

Because i don't need to jump to another function after finding ready.


However the best thing to do is to use native JavaScript whenever possible, unless you are supporting super old browsers.

document.addEventListener("DOMContentLoaded", function(event) { 
  //do work
});

This does almost the same as the ready function and you do not need jQuery for this, also it a bit faster than $(document).ready()

Pavlo
  • 1,157
  • 7
  • 13
  • Should read the docs because `$(function(){})` in jQuery v3 is now preferred and other signatures like the one you are using are deprecated – charlietfl Jan 29 '18 at 15:51
  • And it's not true that `ready` and `DOMContentLoaded` are the same. They have differences. Maybe not for everyone, but at leas it's not the _same_. – eisbehr Jan 29 '18 at 15:52
  • 1
    My bad, i don't use jQuery anymore, but i liked the ready one because of readability, also jQuery 1.6 is used a lot, which is the one i worked a lot on. – Pavlo Jan 29 '18 at 15:53
  • jQuery 1.6 is ancient and should be used as reference for current day answers – charlietfl Jan 29 '18 at 16:00