6

I want to use Content Security Policy (CSP) across my entire site. This requires all JavaScript to be in separate files. I have shared JavaScript used by all pages but there is also page specific JavaScript that I only want to run for a specific page. What is the best way to handle page specific JavaScript for best performance?

Two ways I can think of to workaround this problem is to use page specific JavaScript bundles or a single JavaScript bundle with switch statement to execute page specific content.

Muhammad Rehan Saeed
  • 35,627
  • 39
  • 202
  • 311

2 Answers2

2

Sorry, I know this ended up being a long read, but it'll be worth it to do it as you'll be able to make the choice that's right for your site. For a tl;dr, read the first sentence of each paragraph.

First of all, no matter which route you choose you should put all of the JS common to each page in the same file to take maximum advantage of caching. That's just common sense. Also, in all cases, I assume you're using a competent minifier since that will make a bigger difference than anything else. Packagers also exist if you need one of those -- Google is your friend if you need either of these.

For the page specific JS, you should decide whether it's most important to have your first page load (the user's first contact with your site) be 'fast', or if it's most important to have the following page loads (the user's first contact with any given page) be 'fast'. Modern browser caching is quite good now, so you can rely on the browser loading from cache whenever it can. In general, if it's most important for the first page load to be fast, then create separate JS files (this way, the user isn't stuck downloading 10 MB of data before they even get to your site). If not, then put all the JS in the same file, keeping in mind that if one page has significantly more JS than others, it will adversely affect the load time of every page on your site. Note that this extra load time can be mitigated with the use of async or defer tags, more on that later.

Consider the case where page A has 5 KB of JS and page B has 5 MB of JS. If you put both scripts in the same file, page A will load more slowly (since it needs to load ~5 MB of JS) but page B will load much faster due to the JS file being cached already. If you keep them separate, page A will load much faster than page B, but there will be an average speed decrease compared to the first case. If one page doesn't have significantly more JS than another, use separate files. You'll encounter much better average load time since the "savings" of loading the big file ahead of time will be greatly diminished (you'll also avoid the issue mentioned below).

Another consideration is whether one of the JS files will change often, as this will invalidate the cached version and require the browser to redownload it. If you put all your JS together and only one of the files is volatile (especially if it's a page not often visited, such as a registration page), the end user will face a higher average load time than if you keep them separate. Stack Overflow themselves took an interesting approach to this. It appears they have a function to invalidate the cache of JS unrelated to the page and load it (if necessary) when the JS on the page loads from the cache to save loading time later.

One more thing! Beyond all this, you should also decide whether or not you should use async or defer in your script tags since you're migrating to fully "external" JS.

async allows the page to load and display to the user before the JS is finished downloading. This is a great way to hide the download of a big JS file if you decide to go the "one file to rule them all" route. However, you might also find the JS needs to be downloaded and execute in order for the page to display properly (as is the case when not using async or defer).

As a result, it might be a good idea to use a hybrid of the two suggestions and split your js into individual files that need to be loaded per page for the page to display correctly (one per page), and put all the js that doesn't into a script that loads through an async or defer tag (this being the "one big file"). defer lets the browser load it in the background after the page is displayed to the user.

Ultimately, only you can make the decisions that are right for your app. There's no one magic option that will work in all cases, but that's the reality of software design/engineering. I hope I've made the process clearer for you so you can arrive at the right choice more easily, though.

Peter G
  • 2,773
  • 3
  • 25
  • 35
2

there is lots of ways to execute page specific javascript

Option 1 (check via class)

Set a class to body tag

<body class="PageClass">

and then check via jQuery

$(function(){
  if($('body').hasClass('PageClass')){
    //your code
  }
});

Option 2 (check via switch case)

var windowLoc = $(location).attr('pathname'); //jquery format to get window.location.pathname

switch (windowLoc) {
    case "/info.php":
        //code here
        break;
    case "/alert.php":
        //code here
        break;
}

Option 3 Checking via function

make all the page specific script in the function

function homepage() {
    alert('homepage code executed');
}

and then run function on specific page

homepage();
Ismail Farooq
  • 6,309
  • 1
  • 27
  • 47