Improving Page Load Performance: Pingdom, YSlow and GTmetrix
GTmetrix is a rather advanced tool that offers a lot on its free tier, but it also offers premium tiers. If you sign up, you can compare multiple websites, multiple versions of the same website, tested under different conditions, and save tests for later viewing.
YSlow is still relevant, although its best days were those when Firebug ruled supreme among the browser inspectors. It offers a Chrome app and other implementations — such as add-ons for Safari and Opera, a bookmarklet, an extension for PhantomJS, and so on.
For advanced users, PhantomJS integration means that one could, for example, automate the testing of many websites — hundreds or thousands — and export the results into the database.
YSlow’s Ruleset Matrix has for a number of years been a measuring stick for website performance.
Pingdom Tools is a SaaS service that offers monitoring and reporting of website performance, and it has strengthened its market position in recent years. It also offers a DNS health check and website speed testing on its free tier, which is comparable to GTMetrix and YSlow.
For the purposes of this article, we purchased a fitting domain name — ttfb.review — and installed Drupal with some demo content on it. We also installed WordPress on wp.ttfb.review, and demo installations of Yii and Symfony on their respective subdomains.
We used the default WordPress starting installation. For Drupal, we used the Devel and Realistic Dummy Content extensions to generate demo content. For Symfony we used the Symfony demo application, and for Yii we used basic application template.
This way, we’ll be able to compare these installations side-by-side, and point out the things that deserve attention.
Please be aware that these are development-level installations, used only for demonstration purposes. They aren’t optimized for running in production, so our results are likely to be subpar.
After logging in (registration is free), we tested all four of our demo websites, and compared the results side-by-side:
We can see that our Drupal installation loaded the fastest, while Yii’s installation took a whopping ten seconds to load. However, it wouldn’t be smart to use this for any kind of technology comparison, as these are not production-ready websites, and those systems that require more knowledge and work to set up are expected to come in “debug” (or development) mode. The other thing to keep in mind is that to get any conclusive results, it’s advisable to repeat the tests a couple of times. Our testing server’s virtualization system is OpenVZ, for which resource allocation can be inconsistent.
We can see the relevant metrics:
- total number of requests
- total page size
- total time of loading
We could say that these are the primary metrics we ought to pay attention to, the most important of which is loading time. All the other metrics we see are useful guidelines that give us clues on how to improve our loading time.
Shaun Anderson of the Hobo SEO agency from UK published an article on the correlation between website speed and conversions/Google ranking — with some interesting results.
The thing to keep in mind is that time matters most. All other metrics are mere guidelines.
This comparison can be seen online on GTmetrix, so readers can analyze it item by item.
The first set of results is in the PageSpeed tab, where we can see that the only thing that this algorithm complains about with our Yii installation (the slowest in our test) is JS minification (or, rather, the lack of it). Drupal is the best, although it has most of the red flags. If we take page size into consideration, Symfony fares the best, with a page weight of only 507KB.
We can see from this example that mere test grades don’t tell us everything.
If we switch to the YSlow tab, we see more realistic scores:
But it’s still hard to ascribe the loading time difference to any of these items. That’s why we have the Waterfall tab: it shows us where the delay is. Waterfall comparison, for lack of screen real-estate, can only compare two results side-by-side, so we’ll compare Drupal and Yii installations (best and worst loading time) on this results page:
This finally gives us some clue that none of the previous tools gave us. The whole nine seconds spent by Yii are spent on the first (main) request for the website’s HTML — not for the static resources. If we hover over the long, purple line on the Yii chart, we’ll have GTmetrix spell out for us the exact anatomy of that nine-second response:
Here we can detect where the problem lies — in the “Waiting” phase, in the page generation phase, or to use a more familiar term, TTFB, Time To First Byte. This means that the problem lies purely on our Nginx or PHP side. The things we can do about this are manifold, and have a lot to do with the exact application we are dealing with. We would need to inspect where the issue lies on our backend.
It could be a resource-hungry application, inefficient database queries, server-software RAM constraints, etc. A tool that can come in handy here to monitor server processes is Monit, along with application-specific tools and procedures to diagnose and improve loading time. Two things that will almost always improve TTFB are: more server resources, and caching solutions like Varnish. If the static resources were the main culprit, we would need to pay more attention to warnings on the PageSpeed and YSlow tabs, gzipping, minification, and perhaps deploy our website on a CDN like Cloudflare.
One of the reasons for the difference between Drupal and Yii might be the fact that Drupal comes with “batteries included”, more production-ready out of the box, while Yii comes ready for extensive development.
We can see that the Drupal installation comes, by default, with some caching solutions turned on:
After tinkering with Drupal for a bit, and toying with its built-in modules and configuration options like BigPipe and caching, we could reduce the load time by another half-second:
On GTmetrix, we can compare our tests from the home page:
We can also simply add different report URL suffixes to see them side-by-side:
For the Video tab, we must enable the video-recording option in our Advanced options:
(By the way, we can see that in subsequent tests, Drupal’s cache warm-up reduced our website’s load time by a further 200 miliseconds.)
Now we have video available in the Video tab of the results:
This way, we can sometimes visually get clues about the loading issues or bottlenecks. The system also offers to generate a filmstrip of the page load.
In single tests, there’s also a Timings tab which separates the loading phases and gives us the time and explanation of each phase, like the Time To First Byte that we mentioned earlier:
(This is the ttfb.review of Drupal’s one-second load.)
The History tab on the single page reports is for the monitored pages, or multiple tests over time, where we can see our progress:
For comparisons, we have the Graphs tab:
There are more settings that can be found in the off-canvas sidebar:
By repeating the tests, in the course of writing this article, we saw the load time for the Yii app drop to 1.2 seconds, and Symfony to 1.6 seconds.
With Symfony, a look at the History tab shows that TTFB remained the same, and the 400 millisecond improvement is most likely due to the difference in loading of static resources:
But the next two charts show that there was nothing to claim credit for the speed improvement except the accidentally better network throughput:
With Yii, the improvement is more radical across all three metrics, TTFB, onload and fully loaded time:
Here, the improvements are accidental and due to either the server overload or the network throughput changes, but as we make changes on our website, and improve across these different metrics, we will be able to monitor our progress in the History tab.
GTmetrix has many more options, and it goes beyond the scope of one article. For example, even on the free plan, we can test with mobile or desktop browsers, and we can simulate the speed of the visitor’s network — ADSL, 3G, etc.
We can also test the website from different locations on the globe:
This can come in handy when we’re expecting visitors from more than one region, or when we’re measuring the impact of implementing a CDN into our stack. Network latency can make a couple of seconds of difference in the load time from one location on the globe to another.
YSlow, with its ruleset, came from the work of the Yahoo developers Exceptional Performance team. It became a prominent web performance tool primarily as a Firebug add-on, but this has been rendered obsolete with Firefox Quantum.
We can select a ruleset to apply, set the strictness of the criteria, and then get results under Grade, with grades by items, from A to F, with explanations and links for each item/dimension.
In the Grade tab, we can filter our results. For example, with our Yii app, filtering the results to just those pertaining to the Server, we see this:
This gives us a quick overview of the things we can improve by adjusting our server settings — gzipping the content, setting the Expires headers, deploying the website on a CDN, etc.
Each of the YSlow recommendations/grades gives us a brief explanation, and a link to read more about the topic.
The Components tab gives us an overview of all the resources or URLs loaded during the page load time, including the page itself, JS, CSS, images, their sizes, compressed sizes, cookies, headers sent.
In the case of our Yii demo app, for example, we can see in our Components tab that we aren’t compressing our JS properly (the size is the same as uncompressed), nor setting any Expires headers — which should be done in a production app:
More about the criteria and rules can be found here.
The Statistics tab has a great overview of all of the elements that make up the page, percentage in the total weight of the page, and overview of the same with a primed browser cache. This is something we can manipulate with the Expires header. GTmetrix has an article about the Expires header. This performance dimension affects repeated visitors — those who, due to our Expires instruction being sent to our visitor’s browser, have the static resources kept in the browser’s cache for repeat visits for a certain, specified amount of time.
On the YSlow website, there’s a more in-depth guide about each of the 23 criteria it uses for grading the tested websites, with further tips for optimization.
After doing the test and getting a brief overview, as shown above, further down on the report page we have itemized recommendations about improving our load time:
We can see here the recommendations regarding the Expires headers that we mentioned above, among other things.
Below that, we can inspect our HTTP responses, and whether we have problematic redirections, or invalid responses (in the case that some of the resources didn’t load):
In the case of another production website we had tested — a really resource-heavy website with a lot of static resources — the results looked like this:
Back to our test Drupal installation on http://ttfb.review, Pingdom gives us — further down the result page — a breakdown of the content by type, weight and percentage:
In the case of the mentioned resource-heavy website we tested (we didn’t leave the URL visible, because it is a rather bad example of a website, which is running in production), we can see the problematic parts: a massive video, Google maps, a chat widget by an external provider:
Back with our Drupal site, Pingdom allows us to dissect the whole page load, request by request, allowing us to see which requests/responses make up the most of our load time:
Then, by colors, we can further break down the phases of every single request/response, and locate the bottlenecks, either by getting rid of the most expensive resources, or gzipping them, minifying the JS and CSS, or deploying them on a CDN.
We can also combine them where possible to reduce the number of requests, or implement the HTTP/2 protocol, which allows for more asynchronous, non-blocking loading of resources.
Bellow this waterfall chart, Pingdom has a color legend, explaining each.
In the case of our Drupal website, since we set up the domain DNS settings from scratch, when we started writing this article, we set our domain’s A record TTL — Time To Live, or domain record caching time — to 1 minute, trying to speed up the deployment of our domain. To reduce the ping, the DNS part of the first request, we would increase TTL time once the domain is set up to a maximum. This way, the domain setting would be cached, and there would be no need for thorough domain DNS lookup.
Each of these requests has a dropdown button on the right, and clicking it, we get insight into each request’s and response’s headers:
Here we can debug whether a request is cached on the server, whether the content is cached, and so on.
With a website deployed on Cloudflare, for example, we can see from a resource’s headers that
cf-cache was HIT — meaning the resource is cached, we can see it is gzipped, the expires headers are set, as well as cache-control headers:
On a Cloudflare-deployed website, we can see on our Pingdom waterfall chart, downloads of resources are more parallel, asynchronous and non-blocking. This can also be achieved by setting up our server to use the HTTP/2 protocol:
(There’s no waiting for one request/response cycle to finish for the next one to begin.)
Some improvement here can be achieved by preloading resources.
With Pingdom, like with GTmetrix, we can choose the location from which to test. We tried to test our Yii demo installation, http://yii.ttfb.review, from Sweden (previous GTmetrix tests were done from Vancouver, Canada), and the difference is obvious. Our website now took 445 milliseconds to load:
In this case, we also see the DNS latency is taking maybe more than it should. We should reduce the TTL DNS setting, and the blue parts on static resources are the “Connect” phase, so we can assume that HTTP/2 with its keepalive improvements would be able to leverage a single connection to push all of these resources, without the overhead of establishing a new TCP connection for every resource:
The simplest path here would probably, again, be a CDN.
The DNS latency is even more visible when we test from California:
We can safely assume that solving the DNS issue and serving static resources more efficiently would slash the load time by one third.
Pingdom offers premium monitoring solutions similar to GTmetrix. It can monitor uptime, send alerts, monitor average load times, etc.
Both GTmetrix and Pingdom give us an option to export HAR files. HAR — or HTTP Archive format files — are JSON-formatted archive files for logging of a web browser’s interaction with a site. We are attaching a HAR file from our GTmetrix test of the WordPress test installation (which has a lot of problems to debug, by the way).
This file is a standard format for debugging website responsiveness.
This file can then be imported into Google’s Har Analyzer:
This can then be further analyzed, shared, etc.
Other tools that deserve to be mentioned are Page Load Time for Chrome, which works as a neat browser widget with brief loading stats:
Then, there’s the Dotcom Tools web speed test:
It offers 24 testing locations, and then detailed waterfall charts for each one.
There’s also PageSpeedGrader:
Google’s PageSpeed Insights is another tool we can use to get insights and recommendations for possible improvements and best practices, both for mobile and desktop visitors:
In this article, we’ve set up some demo web installations and tried to show how we can debug the various elements that make up the page load time. There are other tools that can discover bottlenecks, that give us insights into the server processes, like New Relic, DataDog, and other server-involved tools like Monit — advanced tools, but a bit more invasive regarding server infrastructure.