Webpage Performance – From 7 Seconds To Less Than 2

It’s not a second
7 seconds away
Just as long as I stay
I’ll be waiting

One week ago I noticed that my site was missing a landing page so I started building one. The next day I had a pretty nice page, responsive, animated and with all the bells and whistles required in 2014. There was a custom font from google, two embedded youtube videos, css3 animation and then, in a moment of glory, I fired up the URL on my 4 years old smartphone:
Oh the horror! There was a mess!
It loaded, eventually, using the slow Parisian “3G”, but it was unusable. Yup, “there’s no hardware acceleration” I said to myself, and with little delay I filled my css with translate3d(0,0,0). Yes, it did help, or maybe “it’s just an illusion”. Not sure. This is the moment you realize that some numbers would be nice to have at hand.
Google PageSpeed Insights
GTmetrix
Pingdom Tools

Well, the numbers were: 7.71 seconds to load, 42 requests and ~1MB download size. I did not bothered to look at the speed index…
So I rolled up my sleeves and started with the big stuff, compressing the images:
Kraken was good, but the free version doesn’t resize
jpeg-optimizer only does jpegs
Smush it

This shaved about 250K. And around 4 seconds to load. Not too shabby, but finding the right amount of compression is a tedious work.
So what’s next? Yes, css & javascript:
Online JavaScript/CSS Compressor
YUI Compressor

All things compressed, it is time to aggregate all the stuff in the correct order. Numbers again? 37 requests, 650K downloaded in 2.3 seconds. I don’t stop, I never do!
But you can! Because now I am thinking to reach out and grab the 100/100 from all the page performance analyzers that I know of.
That means I will let go of my google font, customize a FontAwesome build, and chose carefully the CDNs for serving the statics. I had a solitary CDNjs that served only the Fastclick script but switched to jsdelivr and in the end, being so small, I’ve inlined it all at the end of the page.

Ok, now it’s getting tricky. The two youtube video that I was talking about earlier, well I used the iframe embed but that came along with css and javascripts of about 400K in size and beside this, you have some page speed penalty points. Time to load on demand the videos and in the meantime show a thumbnail with a play button as overlay. Fine and dandy.
Oh yes, those numbers: 22 requests, 518.8kB and 1.34s load time of wich 280ms is the TTFB (Time To First Byte)

Any fool can know. The point is to understand.

Waterfall

Waterfall

Validation of viewstate MAC failed

Continuing the Roundabout saga…
My app is hosted on a shared server, so today I got a nice message when testing the login page:
Validation of viewstate MAC failed
This exception appears because Controls using DataKeyNames require Viewstate to be encrypted.
The solutions provided here did not worked or were too complicated. In the end it was an one-liner that saved the day:

<machineKey validationKey="000replaceme000" decryptionKey="111replaceme111" validation="SHA1" decryption="AES" />

Add this in web.config’s element and that’s it. You can use this tool to generate it.

Enable gzip compression with web.config

  • Posted on 8th May 2014,
  • by
  • under IT

HTTP compression can reduce the amount of time it takes to download the resources needed to render your web site.
You can directly enable gzip compression for your asp.net website by adding the following lines in web.config’s system.webServer section:

<system.webServer>
  ...
  <httpCompression directory="%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files">
    <scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll"/>
    <dynamicTypes>
      <add mimeType="text/*" enabled="true"/>
      <add mimeType="message/*" enabled="true"/>
      <add mimeType="application/javascript" enabled="true"/>
      <add mimeType="*/*" enabled="false"/>
    </dynamicTypes>
    <staticTypes>
      <add mimeType="text/*" enabled="true"/>
      <add mimeType="message/*" enabled="true"/>
      <add mimeType="application/javascript" enabled="true"/>
      <add mimeType="*/*" enabled="false"/>
    </staticTypes>
  </httpCompression>
  <urlCompression doStaticCompression="true" doDynamicCompression="true"/>
</system.webServer>

This configuration will enable gzip compression on static and on dynamic content. I have tried it on Windows Shared Hosting and it worked fine.

Browser caching for static resources can save a user time if they visit your site more than once, so include explicit caching headers.
And since you already have the file open, to further improve performance and to squeeze out every byte from your headers, do the following:

<system.webServer>
  ...
  <httpProtocol>
      <customHeaders>
          <add name="Cache-Control" value="max-age=0" />
          <remove name="X-Powered-By" />
      </customHeaders>
  </httpProtocol>
  <staticContent>
      <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="365.00:00:00" />
  </staticContent>
</system.webServer>

Because there’s no reason not to strip these headers out:

<system.web>
    ...
    <httpRuntime enableVersionHeader="false" />
</system.web>

Revealing the specific software version of the server may allow the server machine to become more vulnerable to attacks against software that is known to contain security holes. Implementers SHOULD make the Server header field a configurable option.

You can test your site with PageSpeed now!