10 ways we made SlideShare faster
October 18, 2013
At SlideShare, we love metrics. Be it weekly traffic data, number of uploads, number of pro sign ups or page load time; we track each number very closely and strive to improve the numbers everyday. For Second Quarter of 2013, SlideShare's CTO Jonathan Boutelle came up with the target of reducing our page load time to 5 seconds, which was hovering at an average of 7.5 seconds at that time.
This was not an easy task. We were already following web practices listed at Yslow. We had made every extra effort to achieve good grades at webpagetest. When it comes to page load time every millisecond reduction counts. Read on to find out how we got close to our target.
1. Load all third party libraries after window.load - To start with, all the javascript required for social sharing widgets eg Facebook like button should be loaded asynchronously.As a second step, move the script tags from the html page to a JavaScript(JS) file and bind the asynchronous loading of the external JS libraries to window.loadevent. For example, to load FB Like Button, place the following code in the JS file included in the head
$(window).load(function(){
(function(d){
var js, id = 'facebook-jssdk',
ref = d.getElementsByTagName('script')[0];
if (d.getElementById(id)) {return;}
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
ref.parentNode.insertBefore(js, ref);
}(document));
}
And this is how our new relic graph looked like after we made this change.
2. Asynchronously Load Jquery - Another useful trick is to load jQuery asynchronously so that other components on the page are not blocked.We used jql plugin which can be inlined in the HTML page.You don’t have to worry about missing document.ready( ) calls since jQl automatically catches all jQuery().ready() calls and executes them as soon as jQuery is loaded and the DOM is ready.
3. Combine and Compress - Combining the JS files help in eliminating the initial DNS lookup and TCP connection components that goes in every request. This is very evident from Yslow requests but an interesting tweak to this will be conditional compiling.For example let’s say your page requires jquery, file1.js, logged_in.js, logged_out.js.
Conditional compiling should give you combined_logged_in.js[jquery+file1.js+logged_in.js] and combined_logged_out.js[jquery+file1.js+logged_out.js]
For compressing JS , closure compiler is known to give the best results.
4. Smarter JS packaging - SlideShare has different functionality for logged in and logged out users. We load only base files for logged out users and additional JS files when the user logs in.Similarly the HTML5 player loads different type of combined JS files depending on the content type say presentations or documents.There is also a possibility that some plugins that you added initially are not being used anymore. Removing them is the first step towards minimizing size of assets that block page load.
5. Defer loading of JS - The main component of SlideShare which is the HTML5 player needs to be loaded as fast as possible. For this we are dependent on document.ready event. Therefore,the JS that is required for above the fold functionality is minimal and is loaded quite early.The other JS that is required for additional user functionality is loaded after window.load.
6. Lazy Load HTML and JS - This is a commonly used technique to show user generated content on page like comments etc only when the user interacts.We removed the inline html required for user actions like embed code and retrieved it on user click. This reduces the page size that the browser needs to parse and speeds up the load time.
7. Use of Cache Busters - All the assets like images, sprites, javascript files should have a cachebuster appended at the end of the URL so that the browser can cache the assets and makes a new request only if cache buster has changed.
8. Remove HTTPS calls from an http page- This can help you chop off a few milliseconds spent in SSL negotiation.
9. DNS prefetching - SlideShare uses multiple cdns to fetch various assets. We figured out that we can reduce DNS look up time by preresolving DNS in the browser.
10. Redesigning HTML5 player - Apart from these we also made certain improvements in our HTML5 player.The core of the SlideShare – HTML5 player is written in JavaScript using jQuery.The HTML5 player is a complex system which supports displaying presentations,documents , slidecasts and now Infographics too! To make a dent in the page load time by a good margin, we realized that we need to redesign the HTML5 player
-
We started with the idea that the player should be able to display content even if JavaScript is disabled in the browser and JS should only be used to make the player alive.
-
All the markup was generated on the client side using javascript which led to a lot of DOM manipulation. This was resolved by moving markup creation logic to backend.
-
The layout of slides and other styling logic was rewritten so that CSS rules can be used effectively instead of relying on JS
-
To make the user experience delightful, we included the first slide in the markup itself so that it is triggered by the browser parser instead of waiting on JS.
-
So what was the result of the above experiments? Our new relic graphs tell the entire story. A whooping drop from 5.7 to 5.03 seconds!
Before
After
We used webpagetst extensively to measure the performance of the changes we were making. Here is how we have moved the needle for document complete event.
Before
After
None of the above would have been possible without the help of Jean Benois and Jeba Emmanuel.