4

Given that:

Does it make more sense to break the javascript for an application into "areas" -- one js file for the user/public area of a site, one file for the admin area of a site and so on. Scripts coming from external sites (jquery, other sites in the org) wouldn't really apply.

The upsides I see are

  • Performance: loading one 80kb file is much faster than loading 4 20kb files because of TCP/IP overhead (source). In production, all of the public js will be compiled into one file and served on every request, but I see downsides to including "admin" code in that file.

  • Security: there might be some things in script files that I don't want to expose to unauthorized users. Granted, if it's in script it's not secure, but it would be nice if I could minimize the exposure of things like paths to controller actions that perform database maintenance.

  • Simplicity in development: if the on-ready event will be firing off from each file, it makes sense to me to just put it in one file, that way I won't have to load each file to see what on-readys are in there. The js for sub-areas (like admin) would naturally be in a separate file that wouldn't come from assets

Related: Put javascript in one .js file or break it out into multiple .js files?

Community
  • 1
  • 1
jcollum
  • 43,623
  • 55
  • 191
  • 321

1 Answers1

0

Splitting admin javascript from other javascript sounds like a good idea.

That performance article is definetly right. I haven't seen a situation where caching as much javascript in one file hasn't been the performance winner. Even if the areas don't share javascript, downloading a larger file all at once tends to be faster than multiple downloads.

If you have a lot of libraries and 1-off page specific javascript files then maybe caching all the libraries makes sense, just make sure you measure for cache hits for a typical user when testing.

There are patterns you can use to minimize the onload problem. Splitting things into modules and only initializing those modules based on feature detection has been an effective method for me.

For example, if I have a UserInfo module:

!function(ns) {
  ns.init = function() {
    ns.setup_login()
    ns.show_user_info()
  }
  ns.setup_login = function() { /* blah-blah */ }
  // ... etc
}.call(this, this.UserInfo={})

And if I have some html on the page related to a login:

<div id="user_login">
  <div class="user_info"></div>
  <div class="login_links"></div>
</div>

I can write an initializer like:

$(function() {
  $("#user_login").each(function() { UserInfo.init() })
})

Without this pattern I would've written loading calls to setup_login and show_user_info separately. Usually this lets me initialize a few different modules based on what aspects I detect on the page, and if you group these modules by their dependencies that usually cuts it down even more. (I might've done User.init -> UserInfo.init since maybe I could assume UserInfo depends on User.)

jdeseno
  • 7,753
  • 1
  • 36
  • 34