Picture of a persono typing code on a computer

Advanced Optimization of CSS and Javascript in Magento 2

Why is CSS and JavaScript Optimization Important?

CSS and JavaScript are very important to Magento websites. JavaScript (JS) and CSS are the backbone of your site’s design. However, JavaScript makes sure that the site frontend works. JavaScript can display and hide certain site elements. JS can also use Ajax, a set of web development techniques, to talk to a remote server.

Essentially, JavaScript consists of some of the most important programming languages that keep your website going. CSS, on the other hand, is a set of directives that are used to conceive your site’s look.

When your Magento website loads, one of the things that need to load with the website is JavaScript and CSS.

What is Start Render Time?

Start Render Time is best defined as the moment that something appears on your website. You see, there is a moment in between websites where you type in the URL, and you see the actual website. During that time, you will see a blank white screen.

If you see a blank white screen for a really long time, that means that the JavaScript and CSS are taking a long time to load. If you see a blank white screen for a short amount of time, then that means the JavaScript and CSS are taking a short time to load.

When measuring start render time, a good rule of thumb is to keep the blank white screen in view for about 500 milliseconds, which is what you should also aim for when calculating an ideal Time to First Byte (TTFB). That means that the website is taking an adequate time to load.

How CSS and JavaScript Influence Start Render Time

CSS and JavaScript need to load in order for the website to be fully loaded. If there is too much CSS to load, then the website will load slowly. This means that the start render time will be longer, and your customer will just see a big white screen for longer than what they need.

On the other hand, JavaScript is usually read as the site is loading. Therefore, the blank screen will appear until the web browser has finished reading and executing all the JavaScript files.

Essentially, if your CSS and JavaScript take too long to load, that means that your customer will see a blank, white screen for longer than they have to. This will lead them to either think the website is broken or they will grow impatient and simply leave.

Usually, 40% of site visitors will spend less than three seconds on a slow website before leaving it. This means that if your website loads slowly, you can lose your potential customers to your competitors in about three seconds. This is something that no ​business owner wants​.

To fix these two issues and ensure perfect start render time, you would need to optimize the CSS and optimize JavaScript. In this post, we will detail how you can accomplish this.

CSS Optimization

CSS is the backbone of your website’s design. It describes the fonts, colors, and the overall layout of your webpage. Having a good layout of CSS is fundamental to having a successful website. However, it’s easy to get lost in CSS and allow the code to get out of hand. In that case, CSS can take a long time to load, and an optimization strategy will be needed.

CSS Optimization will increase our site speed and help your Magento website convert visitors into customers. Let’s take a look into what helps us optimize CSS and how to do it.

What is Above-The-Fold CSS?

Above-the-fold CSS refers to CSS on the top of the page that loads first. Let’s take the following page as an example:

The idea behind above-the-fold CSS is that this part of the webpage will load first, and then the rest of the CSS will keep loading until you get to the bottom of the page. This will speed up the start render time because the browser will load your page from top to bottom, as opposed to all

at once. By doing this, website owners can essentially trick their site visitors into believing that the website loads fast when, in reality, only parts of the ​website load fast​.

Find Above-The-Fold CSS and inline it at the top of the page

Identify Critical CSS

Critical CSS is CSS that is needed to paint above-the-fold content. It might differ from page to page. You can manually select CSS rules that are critical, but there are automatic tools. On big sites, manual selection could take weeks, so these tools save a lot of time.

Tools to extract critical CSS

There are online resources to get above-the-fold css:

And there are install and run utilities:

More above-the-fold CSS extraction tools you can find on this ​GitHub page​ by Addy Osmani. We will be using Grunt Critical plugin by Ben Zörb. Thank you, Ben!

Grunt Critical Plugin

Grunt​ is a javascript task runner. If you have never used Grunt (like myself), the first thing you should know is that Grunt automates things. Need your css minified, cleaned up, or beautified Grunt can do that all by running a simple cli command.

I will show you how to setup your grunt environment. For more information, please refer to the ​official Grunt project documentation​.

Install Grunt

Installing this additional software is something you should do in your local development environment, not on a production server.

Install Grunt on your computer by following the simple procedure (you should be familiar with simple bash or shell commands in the terminal). First, install Node.js and npm (My workstation is Debian Linux).

apt-get install nodejs 
apt-get install npm
apt-get install nodejs-legacy
apt-get install phantomjs

NB: if you are on a headless server you need to install xvfb to run phantomjs which is required to run grunt-critical:

apt-get install xvfb

and you need to put ​xvfb-run -s “-screen 0 640x480x16” ​before grunt critical-related commands. For example, to install grunt critical on headless server you need to run:

xvfb-run -s "-screen 0 640x480x16" npm install grunt-critical -save-dev

create a directory

mkdir grunt
cd grunt

setup package.json file

npm init

install Grunt CLI as global

npm install -g grunt-cli

install Grunt in your local folder

npm install grunt --save-dev

install Grunt Critical Plugin

npm install grunt-critical --save-dev

Generate critical-path CSS

Magento has the following pages with the similar layout we need to extract critical CSS from:

  • Homepage
  • Cms page
  • Product page
  • Category page
  • Cart page

We need first to grab the critical-path CSS of those pages and second concat remove redundant CSS rules and minify it.

Download the html code of the homepage, CMS page, etc, and store it inside the src/html folder:

mkdir -p src/html
wget -O http://magentostore.com homepage.html
wget -O http://magentostore.com/category category.html
wget -O http://magentostore.com/product product.html
wget -O http://magentostore.com/cms cms.html
wget -O http://magentostore.com/checkout/cart cart.html

Create src/css folder and download the main CSS file from which we extract critical-path css

mkdir src/css; cd src/css wget http://magentostore.com/media/css/8b6d422759c648865bb4d035da915b42.cs s -O main.css

install grunt-contrib-cssmin plugin to minify multiple CSS files into one

npm install grunt-contrib-cssmin --save-dev

create Gruntfile.js inside the grunt folder with the following contents:

module.exports = function(grunt) { 
  grunt.initConfig({
   pkg: grunt.file.readJSON('package.json'), 
   cssmin: {
    target: {
     files: {
     'dist/min.css': ['dist/homepage-critical.css',
                     'dist/category-critical.css',
                     'dist/product-critical.css',
                     'dist/cart-critical.css', 
                     'dist/cms-critical.css']
   }
  }
  }, 
  critical: {
    homepage: { 
      options: {
         base: './', 
         css: [
            'src/css/main.css' 
         ],
         width: 1200,
         height: 900 
      },
      src: 'src/html/homepage.html', 
      minify: true,
      dest: 'dist/homepage-critical.css'
  },
    category: {
      options: { 
        base: './',
        css: [ 
           'src/css/main.css'
        ],
        width: 1200, 
        height: 900
      },
      src: 'src/html/category.html', 
      minify: true,
      dest: 'dist/category-critical.css'
  }, 
  product: {
    options: { 
      base: './',
      css: [ 
         'src/css/main.css'
      ],
      width: 1200, 
      height: 900
    }, 
  cart: {
    options: { 
      base: './',
      css: [ 
         'src/css/main.css'
      ],
      width: 1200, 
      height: 900
    },
    src: 'src/html/cart.html', 
    minify: true,
    dest: 'dist/cart-critical.css'
  }, 
  cms: {
    options: { 
      base: './',
      css: [ 
        'src/css/main.css'
      ],
      width: 1200, 
      height: 900
    },
    src: 'src/html/cms.html', 
    minify: true,
    dest: 'dist/cms-critical.css'
  } 
 }
}); 
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.loadNpmTasks('grunt-critical');
};

run grunt tasks to extract critical css and minify it into one file dist/min.css

grunt critical cssmin

or

xvfb-run -s "-screen 0 640x480x16" grunt critical cssmin

on headless server you should see this output:

dist/min.css file should look like this:

Inline Critical-Path CSS

We need to put contents of dist/min.css at the top of our page. In Magento, we simply add min.css to head.phtml:

Move main CSS file to the bottom

Here is how to move all CSS to the bottom of Magento webpage:

  • we create allcss block of type page/html_head and put all CSS inside it:
<block type="page/html_head" name="allcss" as="allcss" template="page/html/allcss.phtml">

<action
method="addItem"><type>skin_css</type><name>css/styles.css</name><params/>
</action>
...
</block>
  • we delete all CSS files from the default head block
  • we put ​getCssJsHtml()​ ?> inside allcss.phtml template
  • we put ​getChildHtml(‘jsfooter’) ?>​ inside templates just after ​​ tag

Once you get everything setup it’s important to test your site in different browsers to make sure it looks OK.

Find and Remove Unused CSS

Having unused CSS can really slow down your applications and just makes your web page longer, which also makes it take longer to load. Therefore, it is important to keep your excess code to a minimum.

You can find and remove unused CSS by following these simple instructions: Download Google Chrome if you have not already.

  • Download Google Chrome if you have not already.
  • Once you have done so, go to ​chrome://flags/.​ There, you will see a list of some new but experimental features in Chrome.
  • Look for ​Developer Tools Experiments​ and click ​enable​. You may look up the name in the search box at the top of the page.
  • Open up your tools (​right click→ inspect​)
  • Go to: more ​tools→ coverage​. You will go to the bottom of the page corner, where you will see three settings: a.
    • Console
    • What’s New
    • Coverage​, the choice you will be choosing
  • Make sure you are in ​sources​. Go to the sidebar and click a file under the CSS folder

The CSS that is in lines 1-5 is CSS that does not get used on the site. While the CSS in line 6 is CSS that gets used.

JavaScript Optimization

Because JavaScript is literally the code that makes webpages interactive, it is important to keep the JavaScript optimized on your Magento site. Here are four important steps to take when making optimizations to JavaScript:

Defer Javascript Loading

By deferring JavaScript loading, what we are doing is we are moving our code to the bottom of the page so that it is the last thing that loads. We do this because deferring the JavaScript will allow the server to give priority to loading the CSS first, thus at least giving the user a webpage to look at while the scripts load.

By doing this, we make the site visitor think the page is loaded. In reality, only the CSS and HTML are loaded. The JavaScript needs time to load.

In order to help you accomplish this, you may use this free ​Defer JavaScript plugin​ for Magento 2.

Identify and Remove Unused JavaScript

Removing unused JavaScript is absolutely essential because whether the code is being used or not, your backend still loads the code as part of your site.

The code that you are not using can be removed, and the energy that goes into loading unused JavaScript can go into loading the website faster.

If you have unused JavaScript on your website, you can find out which code you need to get rid of by doing the following:

  • Downloading Google Chrome if you have not already.
  • Once you have done so, go to ​chrome://flags/.​ There, you will see a list of some new but experimental features in Chrome.
  • Look for ​Developer Tools Experiments​ and click ​enable​. You may look up the name in the search box at the top of the page.
  • Open up your tools (right click→ inspect)
  • Go to: more tools→ coverage. You will go to the bottom of the page corner, where you will see three settings: a. Console
    • What’s New
    • Coverage​, the choice you will be choosing

Do not be afraid to take the box on the bottom and move it up to make it larger. If you click around the area, you will notice a small arrow.

  • Now, click on the gray circle. You will see it turn red (pictured above).
  • There, you will find the following data

With this data, you will be able to figure out how much JavaScript goes unused for the site.

The JavaScript in red shows what goes unused, while the green shows what gets used.

Do Not Use M2 JavaScript Bundle Feature

The theory behind bundling is that if you take a bunch of smaller JavaScript files and bundle them together, then there will be fewer HTTP requests, and the webpage will load faster. This sounds like a great idea on paper, but when the Magento feature was tested out, it was found not to be as good of an idea.

For starters, when the idea was tested out, some developers discovered a bug in the feature. They found that bundled JavaScript file bundles can start processing at 8 MB but finish processing at ​13 MB​. This has been found to be a really large file that will take a lot of time to load.

Another reason why JavaScript bundling is not a good idea is that it actually may require more time for your site to load. When you bundle JavaScript together, you do lower the amount of HTTP requests, but those requests are much larger. Therefore, the responses take much more time to load. The larger the HTTP requests are, the longer it will take for the server to process them.

This means that the time you tried to save by grouping these files together has been used so that the server can fulfill your requests, and it may even take more time for the website to load overall. Therefore, developers like myself have concluded that you do not save any time by doing this.

Main Takeaways

If your website is running slow, there are ways to optimize your CSS and JavaScript in Magento 2 to make it work faster. The best way to see if you need to optimize your CSS and JavaScript is to take a look at your start render time. That is the amount of time you see a blank white screen on your webpage. This also dictates the amount of time that it takes for your CSS and JavaScript to load.

If you see a blank screen on your page for more than three seconds, that generally means that your website is taking too long to load, and you are very likely to lose customers over it.

A great way to avoid this would be to remove unused code and put code above the fold. Above-the-fold code is the practice of moving code to the top of the page so that the user can at least see the top of the page while the rest of the page loads.

Once you have done all of that, you can expect a lower bounce rate, more traffic, and ultimately higher conversion rates.