[This content was originally published in the Digital Echidna Blog on August 6, 2019]
In the previous installment, I talked conceptually about how to approach testing and what we are trying to learn. This time we’re going to get our hands dirty and start collecting data.
We looked at an example set of data last time, but you’ll want to run tests of your own on the site you’re trying to speed up. My favourite tool is https://www.webpagetest.org/ which is free and provides a wealth of data. I usually have it run three tests and it will use the median for the stats it returns for your page.
The view we looked at is below the main waterfall in the Connection View. This presentation nicely groups together to the types of requests we’re concerned with, so it’s a convenient way to triage where we need to investigate further. On that note, let’s talk about how we can drill down and collect more data in the areas we identified.
Most often, issues relating to the page load show up as extended “first-byte” times. This is the latency between when the browser requested the page and when data starts returning. A high value (greater than 500ms in most cases) means the webserver is working hard to render the page.
Caching is usually your first line of defence here. On most sites, you’ll want to ensure both of core’s cache modules are installed: Internal Page Cache and Internal Dynamic Page Cache. Internal Page Cache is similar to the caching that was available in Drupal 7 but is vastly improved, including an ability to dynamically invalidate a page’s cache when the underlying data changes. Because of this, pages are cached indefinitely.
You can, however, configure how long browsers and proxies will cache the page, which can reduce load on your server. In your site’s admin menu, head to Config > Development > Performance and set the caching time to something sensible, like 10 minutes.
Dynamic Page Cache is new to Drupal 8, and is able to cache pages but exclude any part that is personalized, which provides a significant improvement for authenticated users.
Another core module you should have enabled is Big Pipe, which allows Drupal to insert placeholders for dynamic elements and then asynchronously replace them after the page has started to render. More simply, it allows Drupal to defer figuring out the complex parts of your page and render them later, which allows the user to see the page more quickly.
Too Much of a Good Thing?
If your page is still slow, it may be time to review the overall complexity of the site. It’s wonderful that the Drupal community makes so many modules freely available, but we still need to be judicious in our use of them. Too many modules make for a slow site. In particular, there are some modules you should try to avoid using in a production environment:
- Anything development related, especially Devel and its submodules;
- A lot of the UI modules: Views UI, Field UI, etc. Best practice is to use these on your local or a development environment, export the updated configuration, and then import that on production;
- Statistics: this puts additional load on your server and bloats your database quickly. It’s important to collect data, but better to offload the effort to an outside service like Google Analytics;
- Search: many hosts offer a dedicated search service like Apache Solr, so better to offload the work needed to index content and query for matches;
- Database log: in production, you should really use syslog instead; and
- PHP filter: This should only ever be used for initial “proof of concept” work and never in production. Having this enabled creates both speed and security problems.
Of course, another option to make the page load faster is simply to throw more server resources at it: more RAM, CPU, etc. While this can be effective as a short-term strategy (for example, while investigating the root causes of performance issues), in the long run it’s an expensive way to deal with issues that likely have cheaper solutions available.
If you’re able to control the software in the server environment, there are options here that can help too. Using a recent version of PHP will often help, as will the use of a data cache like APCu, Mecached, or Redis. For sites will lots of anonymous traffic, a reverse proxy like Varnish can allow all these anonymous page request to be satisfied before they even reach Drupal. Going a step further, using a Content Delivery Network (CDN) like Cloudflare will achieve the same, but often from a point of presence that’s closer to the visitor’s physical location, to also reduce network latency.
If you want even more data on your page loads, there are some excellent tools available. The contrib Site Audit will do an automated scan and generate a report with lots of details about how well your site adheres to Drupal best practices, including some to areas discussed above, such as caching. A server-level view of how your site’s code is executing can be invaluable for helping to identify performance bottlenecks. Application Performance Monitoring solutions like Blackfire or New Relic offer a much deeper level of reporting, at a price.
In our next installment, we’ll look at on-site assets, with a similar discussion on how to optimize them and do additional investigation, if necessary. Read part three.