<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Peakhour.IO - Web Performance</title><link href="https://www.peakhour.io/" rel="alternate"></link><link href="https://www.peakhour.io/feeds/tag/web-performance.atom.xml" rel="self"></link><id>https://www.peakhour.io/</id><updated>2026-07-06T13:00:00+10:00</updated><entry><title>How To Exclude Query String Parameters from Search Engine crawling</title><link href="https://www.peakhour.io/blog/how-to-exclude-query-string-parameters-from-search-engines-using-robots-txt/" rel="alternate"></link><published>2024-05-21T13:00:00+10:00</published><updated>2024-05-21T13:00:00+10:00</updated><author><name>Dan</name></author><id>tag:www.peakhour.io,2024-05-21:/blog/how-to-exclude-query-string-parameters-from-search-engines-using-robots-txt/</id><summary type="html">&lt;p&gt;Double crawling of pages by search engines due to filtering options and query strings can be a massive drain on server resources. Learn how to control it using robots.txt.&lt;/p&gt;</summary><content type="html">&lt;p&gt;Last year we wrote about the problem of &lt;a href="/blog/when-good-bots-break-bad/"&gt;excessive crawling from search engine spiders&lt;/a&gt;.
Search engines such as Google and Bing aim to index as much content as possible. For ecommerce sites, this often means
indexing pages with query string parameters used for sorting, filtering, or pagination. Those parameters help users
navigate the site, but they can cause a few predictable crawler problems:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Over-Crawling&lt;/strong&gt;: Search engines may spend too much time crawling similar pages with different parameters, wasting crawl budget.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Duplicate Content&lt;/strong&gt;: Pages with different parameters can be treated as duplicate content, weakening SEO performance.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Server Load&lt;/strong&gt;: Excessive crawling can increase server load, slow down your site, and affect user experience. Search
  engines typically account for 30-50% of page requests to an ecommerce store. Managing their crawling effectively can
  have a material effect on site speed and server spend.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Another common cause of over crawling is internal searches being indexed.&lt;/p&gt;
&lt;p&gt;In our previous article we mentioned using the webmaster tools provided by Google and Microsoft to manage crawler
behaviour by adding ignored parameters. Since then, both tools have been updated and no longer allow you to add
parameters to ignore during a crawl.&lt;/p&gt;
&lt;h2&gt;Differences in Crawling and Indexing&lt;/h2&gt;
&lt;p&gt;Search engines maintain an 'index' of web pages. Pages in this index are what appear in search results. To maintain
the index, the search engine crawls a website to 'discover' new content and keep existing entries up to date. Webmasters
can control what gets indexed with tags or headers in their web pages. These include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Canonical Tags can be used to indicate the preferred version of a page. This helps
  consolidate link 'juice' and tell the search engine which URL to index.&lt;/li&gt;
&lt;li&gt;Noindex tags can be used to prevent specific pages from being indexed. This is useful
  for thank you pages, admin pages or any content you don't want to appear in search results.&lt;/li&gt;
&lt;li&gt;&lt;a href="/learning/seo/nofollow-link-attribute"&gt;Nofollow links&lt;/a&gt; can be used to indicate to a search engine not to pass on SEO
  value to the linked page.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;However, controlling what does or does not get indexed does not prevent content from being crawled. The only way
to do that is via the robots.txt file. You may be familiar with the Disallow directive in
the robots.txt file, but you can also use wildcards to prevent crawling of url parameters.&lt;/p&gt;
&lt;h2&gt;An example...&lt;/h2&gt;
&lt;p&gt;Consider an ecommerce store that has a category page which can then be customised with the following parameters:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;    orderBy
    colors
    brands
    page
    results
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;These may appear in any order, and the combinations can result in 100s or even 1000s of variations of essentially the
same page. Google is fairly smart when presented with this scenario, but Bing.... Bing can crawl very aggressively and
it likes to try everything. In our example above, we may want to stop crawling everything except the page number, in
which case an effective way to control crawler behaviour would be:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;    User-agent: &lt;span class="gs"&gt;*&lt;/span&gt;
&lt;span class="gs"&gt;    Disallow: /*&lt;/span&gt;?*orderBy=*
    Disallow: /*?*colors=*
    Disallow: /*?*brands=*
    Disallow: /*?*results=*
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;We can't really do this in a single Disallow because the parameters might be in any order. By including the ? in the url
we're ensuring that the parameter names are only in the query string, not in the main url path. This prevents crawlers
from wasting crawl budget and putting unnecessary load on server resources.&lt;/p&gt;
&lt;h2&gt;Final Thoughts&lt;/h2&gt;
&lt;p&gt;Search engines can often make up 30-50% of the overall page requests to a website. Managing their behaviour helps
maximise useful crawling and minimise server utilisation. Keep an eye on your access logs for unwanted behaviour, and
use robots.txt where it gives you the right level of control.&lt;/p&gt;</content><category term="Bots"></category><category term="SEO"></category><category term="Bot Management"></category><category term="Web Performance"></category><category term="DNS"></category></entry><entry><title>RFC 9460</title><link href="https://www.peakhour.io/blog/rfc-9460-dns-evolution/" rel="alternate"></link><published>2023-11-16T00:00:00+11:00</published><updated>2023-11-16T00:00:00+11:00</updated><author><name>AC</name></author><id>tag:www.peakhour.io,2023-11-16:/blog/rfc-9460-dns-evolution/</id><summary type="html">&lt;p&gt;Introducing SVCB and HTTPS records in DNS and their impact on web connectivity.&lt;/p&gt;</summary><content type="html">&lt;p&gt;RFC 9460 introduces two DNS record types: "SVCB" (Service Binding) and "HTTPS". They let browsers learn more connection details during DNS lookup, before redirects and TLS negotiation add extra steps. The result is cleaner connection setup, with practical improvements in speed, security, and efficiency.&lt;/p&gt;
&lt;h2&gt;Understanding the Current Process&lt;/h2&gt;
&lt;p&gt;Traditionally, when a browser connects to a website, it follows a sequence:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Browser requests site via HTTP.&lt;/li&gt;
&lt;li&gt;Server redirects request to HTTPS.&lt;/li&gt;
&lt;li&gt;Browser receives ALPN (Application-Layer Protocol Negotiation) during the HTTPS handshake.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The model is secure, but it is not optimal. It involves multiple round trips, which affects Time to First Byte (TTFB) and the overall user experience. Load balancing and failover are also less direct than they could be. RFC 9460 changes this by allowing DNS to provide the necessary connection details earlier. That reduces the steps involved in establishing a secure connection, lowering TTFB.&lt;/p&gt;
&lt;h2&gt;The Impact of SVCB and HTTPS Records&lt;/h2&gt;
&lt;p&gt;SVCB and HTTPS records move useful connection hints into DNS. They speed up the time-to-first-packet by incorporating the Alt-Svc HTTP header and ALPN TLS extension into DNS, which shortens connection setup. These records also enable redirection at the zone apex, a task not possible with CNAMEs. They simplify DNS load distribution and failover, making web services more resilient. They also remove the need for HSTS preloading and support Encrypted Client Hello (ECH), formerly ESNI, for better privacy.&lt;/p&gt;
&lt;h2&gt;Adoption and Industry Response&lt;/h2&gt;
&lt;p&gt;Adoption started before the RFC was finalised. Firefox has been conducting HTTPS lookups since May 2020, limited to DNS over HTTPS (DoH). Apple's iOS, Safari, and macOS have followed suit since September 2020. Chrome introduced partial support in December 2020 and has recently enabled ECH by default. Various DNS service providers have also started supporting HTTPS and SVCB records.&lt;/p&gt;
&lt;p&gt;As reported on &lt;a href="https://netmeister.org/blog/https-rrs.html"&gt;Netmeister&lt;/a&gt;, adoption is still early but not insignificant. As of October 2023, about 10 million domains have implemented an HTTPS record for their 'www' service names, roughly 4.4% of domains. Around 9.1 million domains, or about 4.0%, use the record on their bare second-level domain name. Among the top 1 million domains, approximately 22.5K (25.5%) use HTTPS records for 'www' service names, and nearly 24K (25.6%) use them on bare domains.&lt;/p&gt;
&lt;p&gt;&lt;img alt="October 2023 Usage" src="/static/images/blog/https-records-oct-2023.png"&gt;&lt;/p&gt;
&lt;h2&gt;What the Records Look Like&lt;/h2&gt;
&lt;p&gt;A typical &lt;a href="/learning/service-binding-record/"&gt;SVCB record&lt;/a&gt; might look like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;_example.com. 7200 IN SVCB 1 svc4.example.net. (alpn=&amp;quot;h2,h3&amp;quot; port=&amp;quot;8004&amp;quot;)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This record indicates that the service at &lt;code&gt;_example.com&lt;/code&gt; can be accessed at &lt;code&gt;svc4.example.net&lt;/code&gt; using either HTTP/2 or HTTP/3 on port 8004.&lt;/p&gt;
&lt;p&gt;An &lt;a href="/learning/https-record/"&gt;HTTPS record&lt;/a&gt; could be:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;example.com. 3600 IN HTTPS 0 svc.example.net.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This record suggests that &lt;code&gt;example.com&lt;/code&gt; should be accessed securely through &lt;code&gt;svc.example.net&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Apex Domains and the Importance of SVCB/HTTPS Records&lt;/h2&gt;
&lt;p&gt;One long-running DNS limitation is the inability to use CNAME records at the apex (root level) of a domain due to conflicts with other necessary records like NS and SOA. RFC 9460's SVCB/HTTPS records address this by enabling apex domain aliasing without those conflicts. This matters for efficient content delivery networks (CDNs) and load balancing strategies.&lt;/p&gt;
&lt;h2&gt;These records enhance capability&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;1. Load Balancing:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Consider a website that needs to distribute traffic across multiple servers. SVCB records can indicate different server endpoints with varying priorities.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;example.com. IN SVCB 10 server1.example.com. (alpn=&amp;quot;h2,h3&amp;quot;)
example.com. IN SVCB 20 server2.example.com. (alpn=&amp;quot;h2&amp;quot;)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In this example, &lt;code&gt;server1.example.com&lt;/code&gt; is the preferred endpoint (lower priority number), offering both HTTP/2 and HTTP/3 protocols. If it's unavailable, traffic automatically shifts to &lt;code&gt;server2.example.com&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. Failover Mechanism:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;For a service that requires high availability, SVCB records can express failover directly:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;critical-service.example.com. IN SVCB 1 primary-service.example.com. (alpn=&amp;quot;h2,h3&amp;quot;)
critical-service.example.com. IN SVCB 2 backup-service.example.com. (alpn=&amp;quot;h2&amp;quot;)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here, &lt;code&gt;primary-service.example.com&lt;/code&gt; is the primary endpoint. If it fails, the system automatically falls back to &lt;code&gt;backup-service.example.com&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. Apex Domain Usage:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A practical advantage of SVCB/HTTPS records is their ability to handle apex domains, where CNAME records are not feasible. This is important for root domain aliasing to different service providers.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;example.com. IN HTTPS 0 cdn-provider.example.net.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This record indicates that the apex domain &lt;code&gt;example.com&lt;/code&gt; is to be served through &lt;code&gt;cdn-provider.example.net&lt;/code&gt;, overcoming traditional DNS limitations.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4. Encrypted ClientHello Support:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Future enhancements of SVCB could include keys for Encrypted ClientHello, which improves privacy and security during the initial TLS handshake.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;secure.example.com. IN SVCB 1 tls-service.example.net. (ech=&amp;quot;base64-encoded-key&amp;quot;)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This record can be used to initiate a TLS connection with &lt;code&gt;tls-service.example.net&lt;/code&gt; using the provided Encrypted ClientHello key.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;5. Directing Traffic to Specific Protocols:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;For services that need to direct clients to newer or more efficient protocols, SVCB records can specify the exact protocols to use.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;api.example.com. IN SVCB 1 api-server.example.com. (alpn=&amp;quot;h3&amp;quot;)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Clients that understand HTTP/3 can connect directly using this protocol, bypassing the usual HTTP/1.1 or HTTP/2 protocols.&lt;/p&gt;
&lt;h2&gt;The Long Wait&lt;/h2&gt;
&lt;p&gt;HTTPS has been around for a while, so RFC 9460 raises an obvious question: why did this take so long? Apex records have had their share of problems, including not being able to use CNAMEs and having to resort to custom records like ALIAS or Cloudflare's 'cname flattening'.&lt;/p&gt;
&lt;p&gt;It is a fair question. We've had some bizarre records hanging around for ages along with a wide range of solutions to the "CNAME at the zone apex"
problem.&lt;/p&gt;
&lt;p&gt;Credit to the creators of RFC 9460 for getting this through and obtaining browser support:
   - B. Schwartz from Meta Platforms, Inc.
   - M. Bishop from Akamai Technologies
   - E. Nygren from Akamai Technologies&lt;/p&gt;
&lt;h2&gt;Final Thoughts&lt;/h2&gt;
&lt;p&gt;RFC 9460 gives DNS a more useful role in HTTPS connection setup. SVCB and HTTPS records let operators publish endpoint, protocol, failover, and privacy information before the browser starts negotiating the connection. That gives service providers more precise control over how clients reach web services, with practical benefits for performance, reliability, and security.&lt;/p&gt;</content><category term="Interest"></category><category term="HTTP"></category><category term="Web Performance"></category><category term="Rate Limiting"></category><category term="TLS Fingerprinting"></category><category term="CDN"></category><category term="DDoS"></category></entry><entry><title>Enterprise-Level Caching for All</title><link href="https://www.peakhour.io/blog/magento-2-plugin/" rel="alternate"></link><published>2023-11-02T13:00:00+11:00</published><updated>2023-11-02T13:00:00+11:00</updated><author><name>Dan</name></author><id>tag:www.peakhour.io,2023-11-02:/blog/magento-2-plugin/</id><summary type="html">&lt;p&gt;Elevate your e-commerce with our newly released Magento 2 plugin. Experience enterprise-level caching features accessible to all Peakhour customers.&lt;/p&gt;</summary><content type="html">&lt;p&gt;We've released our Magento 2 plugin for e-commerce stores using Magento. It brings Peakhour's caching features into
Magento, including capabilities that other providers often reserve for enterprise plans. With Peakhour,
'Enterprise for Everyone' means making those features available to all customers, regardless of plan.&lt;/p&gt;
&lt;h2&gt;Why Cache Tags Matter&lt;/h2&gt;
&lt;p&gt;&lt;a href="/learning/cache-tags/"&gt;Cache tags&lt;/a&gt; solve a practical website management problem: keeping your cache current when content changes.
In Magento 2, a single change, such as updating a product's price, can affect multiple pages. Cache tags ensure that only
the relevant cached content is updated, maintaining cache efficiency and reducing server load. That matters for
website speed and user experience, which directly affect sales and SEO rankings.&lt;/p&gt;
&lt;h2&gt;Enterprise for Everyone&lt;/h2&gt;
&lt;p&gt;While other providers offer cache tags only in expensive enterprise plans, Peakhour makes this feature available
to everyone. Our infrastructure and caching algorithms make that possible. We also offer other
enterprise-level features, including DDoS protection, real-time analytics, and custom caching rules, so
'Enterprise for Everyone' is reflected in the product rather than just the plan names.&lt;/p&gt;
&lt;h2&gt;Peakhour vs. Magento and Varnish Caching&lt;/h2&gt;
&lt;p&gt;Our plugin goes beyond Magento's built-in caching and Varnish cache in several ways:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Custom Cache Tags&lt;/strong&gt;: Unlike Magento's built-in cache, we offer custom cache tags for more granular cache control.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Advanced Algorithms&lt;/strong&gt;: Our caching algorithms go beyond Varnish, helping improve cache hit rates and lower server load.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Additional Features&lt;/strong&gt;: With Peakhour, caching sits alongside real-time analytics, DDoS protection, and custom caching rules, features often missing in standard Magento or Varnish setups.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Expected Performance Improvements&lt;/h2&gt;
&lt;p&gt;By using Peakhour's Magento 2 plugin, you can expect performance improvements:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Faster Page Loads&lt;/strong&gt;: Our caching can reduce page load times by up to 50%, giving users a smoother experience.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Reduced Server Load&lt;/strong&gt;: Efficient caching means fewer requests to your origin server, reducing server load by as much as 70%.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Improved SEO&lt;/strong&gt;: Faster websites are favoured by search engines, which can improve SEO rankings.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Higher Conversion Rates&lt;/strong&gt;: A faster website gives users a better experience, which can lead to higher conversion rates and increased sales.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Installation Options&lt;/h2&gt;
&lt;p&gt;You can install the Magento 2 plugin through Magento Connect, Composer, or a ZIP file. For
more detail, see our &lt;a href="/docs/how-to-guides/integrations/magento-2/"&gt;plugin page&lt;/a&gt;.&lt;/p&gt;</content><category term="CMS"></category><category term="Caching"></category><category term="Magento"></category><category term="CDN"></category><category term="Drupal"></category><category term="WordPress"></category><category term="Web Performance"></category></entry><entry><title>Useful tips to accelerate your Magento store</title><link href="https://www.peakhour.io/blog/accelerate-magento/" rel="alternate"></link><published>2023-11-01T13:00:00+11:00</published><updated>2023-11-01T13:00:00+11:00</updated><author><name>Dan</name></author><id>tag:www.peakhour.io,2023-11-01:/blog/accelerate-magento/</id><summary type="html">&lt;p&gt;There are many things you can do to speed up your Magento store, here are just a few.&lt;/p&gt;</summary><content type="html">&lt;p&gt;Out of the box, Magento is not the fastest ecommerce platform. Magento 2 is built with Full Page Cache in mind, so repeat page requests do not always have to hit the application. A slow Magento store can frustrate customers, increase bounce rates, and cost sales. There are several practical ways to accelerate &lt;a href="/learning/ecommerce-security/securing-magento-shopify/"&gt;your Magento&lt;/a&gt; store and improve the user experience. These are good places to start.&lt;/p&gt;
&lt;h2&gt;Caching is King&lt;/h2&gt;
&lt;p&gt;Caching is usually the biggest performance lever for a Magento store. By storing pre-generated versions of pages, you reduce server response times and avoid asking Magento to rebuild the same page for every request.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Full Page Caching (FPC)&lt;/strong&gt;: Magento includes built-in FPC, but it can be extended. Varnish is a common choice for this role. Magento 2 has native support for Varnish, which acts as a web application accelerator.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Redis&lt;/strong&gt;: Use Redis for session and cache storage. It is an in-memory data structure store that can speed up backend operations by reducing database load.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Edge Caching&lt;/strong&gt;: Use Peakhour Edge to cache your dynamic pages close to users. This serves content from a nearby delivery path and reduces latency. Peakhour's &lt;a href="/docs/how-to-guides/integrations/magento-1/"&gt;Magento 1&lt;/a&gt; and &lt;a href="/docs/how-to-guides/integrations/magento-2/"&gt;Magento 2&lt;/a&gt; plugins make this straightforward to set up.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Optimise Your Images&lt;/h2&gt;
&lt;p&gt;Images often make up the bulk of a page's weight. Optimising them is one of the simplest ways to improve load times.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Compression&lt;/strong&gt;: Use image compression tools to reduce file sizes without a noticeable loss in quality.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Next-Gen Formats&lt;/strong&gt;: Serve images in modern formats like WebP or AVIF, which offer better compression. A CDN can often handle this conversion automatically.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Lazy Loading&lt;/strong&gt;: Implement lazy loading for images that are "below the fold" (not immediately visible). This means they only load when they are about to enter the user's viewport.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Minify and Merge CSS/JavaScript&lt;/h2&gt;
&lt;p&gt;Magento has built-in features for merging and minifying CSS and JavaScript files.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Minification&lt;/strong&gt;: Removes unnecessary characters (like whitespace and comments) from code to reduce file size.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Merging&lt;/strong&gt;: Combines multiple CSS or JavaScript files into a single file to reduce the number of HTTP requests.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: Always test thoroughly after enabling merging, as it can sometimes cause issues with certain themes or extensions.&lt;/p&gt;
&lt;h2&gt;Keep Your Environment Updated&lt;/h2&gt;
&lt;p&gt;The environment your Magento store runs in has a direct effect on performance.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Latest PHP Version&lt;/strong&gt;: Use the latest stable version of PHP supported by your Magento version. Each new release brings performance and security improvements.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Server Resources&lt;/strong&gt;: Ensure your server has adequate RAM and CPU power to handle your traffic, especially during peak times.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Web Server&lt;/strong&gt;: Use a high-performance web server like Nginx, which is known for its speed and efficiency.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Use Edge Caching and Delivery&lt;/h2&gt;
&lt;p&gt;An edge delivery layer is a practical requirement for many ecommerce stores. It caches your static assets (images, CSS, JavaScript) close to users.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Reduced Latency&lt;/strong&gt;: Users receive content from the server geographically closest to them, which speeds up load times.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reduced Origin Load&lt;/strong&gt;: By serving cached content, an edge cache reduces the number of requests that hit your origin server, improving its performance and stability.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enhanced Security&lt;/strong&gt;: Peakhour also offers security features like a Web Application Firewall (WAF) and DDoS protection.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Database Optimisation&lt;/h2&gt;
&lt;p&gt;A slow database can slow the whole store.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Clean Logs&lt;/strong&gt;: Regularly clean out Magento's log tables (e.g., &lt;code&gt;log_customer&lt;/code&gt;, &lt;code&gt;log_visitor&lt;/code&gt;). These can grow very large and slow down database queries.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enable Flat Catalog&lt;/strong&gt;: For Magento 1 and older versions of Magento 2, enabling the Flat Catalog for products and categories can improve performance by reducing the complexity of database queries.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Re-index Regularly&lt;/strong&gt;: Keep your Magento indexes up to date. A cron job should be set up to handle this automatically.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Audit Third-Party Extensions&lt;/h2&gt;
&lt;p&gt;Poorly coded or unnecessary third-party extensions are a common cause of Magento performance issues.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Review Extensions&lt;/strong&gt;: Audit your installed extensions regularly. If you're not using one, disable or uninstall it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use a Profiler&lt;/strong&gt;: Use Magento's built-in profiler or a tool like New Relic to identify slow-running code, which can often be traced back to a specific extension.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These changes will not fix every Magento performance problem, but they cover the areas that usually matter first: cache behaviour, asset weight, the hosting environment, database maintenance, and extension overhead.&lt;/p&gt;</content><category term="CMS"></category><category term="Magento"></category><category term="Web Performance"></category><category term="Drupal"></category><category term="WordPress"></category><category term="Caching"></category><category term="CDN"></category></entry><entry><title>HTTP/2 Rapid Reset Attack Deepdive</title><link href="https://www.peakhour.io/blog/http-rapid-reset-attack-deepdive/" rel="alternate"></link><published>2023-10-12T00:00:00+11:00</published><updated>2023-10-12T00:00:00+11:00</updated><author><name>AC</name></author><id>tag:www.peakhour.io,2023-10-12:/blog/http-rapid-reset-attack-deepdive/</id><summary type="html">&lt;p&gt;The technicalities of the HTTP/2 Rapid Reset vulnerability and steps to fortify against DDoS threats.&lt;/p&gt;</summary><content type="html">&lt;p&gt;Distributed &lt;a href="/products/ddos-protection/"&gt;Denial of Service&lt;/a&gt; (DDoS) attack vectors keep changing. The recent spike in HTTP/2-based DDoS
attacks has been notable for its volume, with some attacks surpassing 398 million requests per second. Peakhour observed
these attacks and worked through how to understand and mitigate them. This article explains how they work and what
operators can do to reduce exposure.&lt;/p&gt;
&lt;h2&gt;The Rise of HTTP/2 in DDoS Attacks&lt;/h2&gt;
&lt;p&gt;HTTP/2 was designed to make web traffic more efficient. The same features that improve performance for legitimate users
can also be abused in DDoS traffic.&lt;/p&gt;
&lt;p&gt;Much of HTTP/2's efficiency lies in "stream multiplexing." It allows multiple messages to be sent over a single TCP
connection. While HTTP/1.1 processes each request serially, HTTP/2 can manage multiple concurrent streams on a single
connection. This means a client can send multiple requests in a single round trip, increasing how much work each
connection can drive.&lt;/p&gt;
&lt;h2&gt;The 'Rapid Reset' Attack Explained&lt;/h2&gt;
&lt;p&gt;The "Rapid Reset" attack is a specific DDoS technique built around HTTP/2. The attacker starts by opening
multiple streams, much like in a standard HTTP/2 attack. However, instead of waiting for responses, they cancel each
request immediately.&lt;/p&gt;
&lt;p&gt;The client does this by sending a RST_STREAM frame, indicating that a previous stream should be cancelled. The rapid
request-and-reset sequence means the server spends resources processing the request, only for it to be cancelled before a
response is generated. This tactic amplifies the server's workload without the attacker needing to wait for responses,
which increases the pressure each connection can place on the server.&lt;/p&gt;
&lt;h2&gt;Variants of the Rapid Reset Attack&lt;/h2&gt;
&lt;p&gt;Attackers also used variations of the Rapid &lt;a href="/blog/http-rapid-reset-attack/"&gt;Reset attack&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;One variant involves delaying the reset action. The attacker opens multiple streams, waits, then cancels the streams
  and instantly opens new ones. This method can evade some rate-based defences.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Another variant avoids stream cancellations. Instead, the attacker tries to open more streams than the server allows.
  This aims to keep the server continually busy, processing a near-constant flow of requests.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Effective Mitigation Techniques&lt;/h2&gt;
&lt;p&gt;Mitigation is not as simple as blocking individual malicious requests. A more effective approach is to close the entire
TCP connection when malicious activity is detected. The HTTP/2 protocol supports connection termination through the
GOAWAY frame. This feature needs to be used aggressively to prevent &lt;a href="/blog/http-rapid-reset-attack/"&gt;Rapid Reset&lt;/a&gt; attacks, rather than
relying on the more passive, standard implementation.&lt;/p&gt;
&lt;p&gt;Deciding which connections to treat as malicious is a challenge. One potential strategy is to monitor connection
statistics. If a connection exceeds a set threshold of cancelled requests, it might be deemed malicious. Responses to
suspect activity could range from sending a GOAWAY frame to terminating the TCP connection.&lt;/p&gt;
&lt;p&gt;For the non-cancelling variant, the best approach is to shut down connections that breach the concurrent stream limit,
either immediately or after a few violations.&lt;/p&gt;
&lt;h2&gt;Broader Protocol Implications&lt;/h2&gt;
&lt;p&gt;These attack techniques are specific to HTTP/2, but the wider protocol lesson still matters. The HTTP/3 (QUIC) protocol
isn't directly vulnerable in the same way. As a precaution, server implementations should consider limiting the work done
by a single connection.&lt;/p&gt;
&lt;h2&gt;The Importance of Industry Collaboration&lt;/h2&gt;
&lt;p&gt;When the threat of the Rapid Reset attack became apparent, the industry collaborated to address the issue. The
vulnerability was disclosed to key HTTP/2 implementers, helping to devise and distribute effective countermeasures. The
vulnerability is logged against &lt;a href="https://www.cve.org/CVERecord?id=CVE-2023-44487"&gt;CVE-2023-44487&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;HTTP/2 'Rapid Reset' DDoS attacks pose a serious risk to services using the protocol. To reduce exposure, service
providers should promptly apply available software patches and updates.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Learn how Peakhour's Application Security Platform helps protect against Layer 7 DDoS attacks, including the HTTP/2 Rapid Reset vulnerability. &lt;a href="/contact-sales/"&gt;Contact our team&lt;/a&gt; to secure your infrastructure.&lt;/em&gt;&lt;/p&gt;</content><category term="DDoS"></category><category term="DDoS"></category><category term="Rate Limiting"></category><category term="HTTP"></category><category term="Bot Management"></category><category term="Web Performance"></category><category term="DNS"></category></entry><entry><title>Interaction to Next Paint (INP)</title><link href="https://www.peakhour.io/blog/interaction-to-next-paint/" rel="alternate"></link><published>2023-09-11T13:00:00+10:00</published><updated>2023-09-11T13:00:00+10:00</updated><author><name>Dan</name></author><id>tag:www.peakhour.io,2023-09-11:/blog/interaction-to-next-paint/</id><summary type="html">&lt;p&gt;Google is introducing a new Core Web Vital to replace First Input Delay, read on to learn all about it.&lt;/p&gt;</summary><content type="html">&lt;p&gt;Google has announced that &lt;a href="https://web.dev/inp/"&gt;Interaction to Next Paint (INP)&lt;/a&gt; will replace First Input Delay (FID) as a
&lt;a href="/blog/web-vitals/"&gt;Core Web Vital&lt;/a&gt;
as of March 2024. Introduced as a metric in 2022, INP covers gaps in FID by measuring more of what happens after a user
interacts with a page.&lt;/p&gt;
&lt;p&gt;To help site owners prepare for its introduction as a Core Web Vital, INP is already included in the
&lt;a href="/blog/what-is-the-chrome-ux-report-crux/"&gt;Chrome User Experience Report (CrUX)&lt;/a&gt;.
By analysing the CrUX data, website owners can see their current INP performance and make targeted optimisations ahead
of the March 2024 change.&lt;/p&gt;
&lt;h2&gt;A better metric than First Input Delay&lt;/h2&gt;
&lt;p&gt;First Input Delay, as its name suggests, only measures the delay between an input, such as a keypress or mouse click, and
the point where the browser begins to handle that event. It does not include the time spent processing the input. It only
measures how long the browser was blocked before it could start handling it.&lt;/p&gt;
&lt;p&gt;That leaves two issues: it only considers the FIRST event, and it does not measure how long it takes for the user to see
the result of their input.&lt;/p&gt;
&lt;p&gt;INP is designed to cover both issues. It measures the latency of ALL 'interactions' through to the visual response for
that interaction. As explained by Google, an interaction like a tap on a touch screen device can consist of several input
events.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;"An interaction's latency consists of the single longest duration of a group of event handlers that drives the
interaction, from the time the user begins the interaction to the moment the next frame is presented with visual feedback."&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;After measuring all interactions, the final INP score is the longest interaction observed, ignoring any outliers.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;What Constitutes a Good Score&lt;/h2&gt;
&lt;p&gt;INP is measured in milliseconds (ms), with lower scores indicating better performance:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Good: &amp;lt; 200 ms&lt;/li&gt;
&lt;li&gt;Needs Improvement: 200-500 ms&lt;/li&gt;
&lt;li&gt;Poor: &amp;gt; 500 ms&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="text-center"&gt;
    &lt;img src="/static/images/blog/inp.jpg" alt="Interaction To Next Paint" style="max-width: 700px"/&gt;
&lt;/div&gt;

&lt;h2&gt;How to ensure you have a good INP score&lt;/h2&gt;
&lt;h3&gt;Minimise Main-Thread Work&lt;/h3&gt;
&lt;p&gt;Long-running JavaScript can block the main thread and increase INP times. Break these tasks into smaller parts and run
them asynchronously to reduce delays.&lt;/p&gt;
&lt;h3&gt;Efficiently Use Browser APIs&lt;/h3&gt;
&lt;p&gt;APIs that trigger layout recalculations can be expensive. Use them sparingly and look for alternatives that put less
pressure on the browser.&lt;/p&gt;
&lt;h3&gt;Defer Non-Essential CSS and Scripts&lt;/h3&gt;
&lt;p&gt;Postpone the loading of non-critical CSS and JavaScript. Use techniques like asynchronous loading to improve INP scores.&lt;/p&gt;
&lt;h3&gt;Monitor Third-Party Scripts&lt;/h3&gt;
&lt;p&gt;Heavy third-party scripts can degrade INP performance. Use asynchronous or deferred loading for these scripts to limit
their impact.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Google estimates that 90% of a user's time on a page is after it has finished loading. FID focused on first impressions,
with the assumption that a fast start meant the page would stay responsive. Interaction to Next Paint addresses that gap
and gives a more accurate view of user experience. If you want to know your current INP score, you can use our free
&lt;a href="/pages/website-competitor-speed-test/"&gt;website speed comparison tool&lt;/a&gt; to view it alongside your other Web Vitals, and see
how your website compares to your competitors.&lt;/p&gt;</content><category term="Learning"></category><category term="Core Web Vitals"></category><category term="Web Performance"></category><category term="Analytics"></category><category term="Caching"></category><category term="Browser Fingerprinting"></category><category term="Features"></category></entry><entry><title>Cache Tags/Surrogate Keys</title><link href="https://www.peakhour.io/blog/surrogate-keys-cache-tags/" rel="alternate"></link><published>2023-06-28T13:00:00+10:00</published><updated>2023-06-28T13:00:00+10:00</updated><author><name>Dan</name></author><id>tag:www.peakhour.io,2023-06-28:/blog/surrogate-keys-cache-tags/</id><summary type="html">&lt;p&gt;Surrogate Keys, or cache tags, are a powerful mechanism for targeted flushing of content from a cache, not all CDNs support them though.&lt;/p&gt;</summary><content type="html">&lt;p&gt;Caches are a way of storing information so future requests for the same data can be served more quickly. CDNs, including
Peakhour, run caches on each of their POPs (Points of Presence). At that level these caches are key/value stores, where
the key can be a combination of several request details, as outlined in our previous blog post on
&lt;a href="/blog/cdn-cache-keys/"&gt;cache keys&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;An established way to improve website performance is &lt;a href="/blog/caching-dynamic-content-with-a-cdn/"&gt;full page caching&lt;/a&gt;,
where a copy of a full page generated by a CMS is stored in a CDN. For a cache hit compared with a cache miss, this can
typically cut 1-4s off a page load.&lt;/p&gt;
&lt;div class="text-center" style="padding: 20px 0px"&gt;
&lt;img src="/static/images/savvy-before.jpg" width="100%" alt="Savvysupporter before"/&gt;
&lt;em&gt;Main document load &lt;strong&gt;before&lt;/strong&gt; caching: &lt;strong&gt;2.07s&lt;/strong&gt;&lt;/em&gt;
&lt;/div&gt;

&lt;div class="text-center" style="padding: 20px 0px"&gt;
&lt;img src="/static/images/savvy-after.jpg" width="100%" alt="Savvysupporter after"/&gt;
&lt;em&gt;Main document load &lt;strong&gt;after&lt;/strong&gt; caching: &lt;strong&gt;82ms!!&lt;/strong&gt;&lt;/em&gt;
&lt;/div&gt;

&lt;h2&gt;A Simple Cache Example&lt;/h2&gt;
&lt;p&gt;When a website changes a resource, such as a page or image, it can instruct the CDN to flush the cache entry for that
resource's key. For example, say we have a page:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;/about-us/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If we're doing full page caching, it will be stored in the CDN with the key &lt;strong&gt;"/about-us/"&lt;/strong&gt;. If it changes, we can
issue a flush using the key &lt;strong&gt;"/about-us/"&lt;/strong&gt; and the CDN will fetch a fresh version.&lt;/p&gt;
&lt;h2&gt;A blog example&lt;/h2&gt;
&lt;p&gt;But consider a blog article with the URL &lt;strong&gt;"/caching/caching-explained/"&lt;/strong&gt;. A typical blog has categories, tags, and
authors. A link and summary for the article can exist on many pages: the home page if it's recent, the category pages
that the article belongs to, the author page, and so on.&lt;/p&gt;
&lt;p&gt;When we update the article, flushing only the key &lt;strong&gt;"/caching/caching-explained/"&lt;/strong&gt; is not enough. We also have to find
the other pages it appears on and flush them too, because they may have changed. That means issuing database queries to
find all the pages that our article appears on, gathering them into a list, and issuing a flush for each of them.&lt;/p&gt;
&lt;h2&gt;An eCommerce example&lt;/h2&gt;
&lt;p&gt;Another example is an ecommerce store with lots of products and product categories. A particular product might appear on
100s of pages with its price displayed. When that price changes, the cached site needs to reflect it. You have two
choices: do a lot of work on the server to discover the pages the product is on and flush them, or flush everything.
Neither option is good. The first can slow your website to a crawl with database queries; the second forces the cache to
repopulate.&lt;/p&gt;
&lt;h2&gt;Enter Cache Tags&lt;/h2&gt;
&lt;p&gt;Cache tags, also known as surrogate keys, are a mechanism for adding another way to find content in a cache. Unlike the
primary cache key, these tags are not unique.&lt;/p&gt;
&lt;p&gt;A website utilises cache tags by returning them in an HTTP header with the response. For example, Magento 2 uses the
header &lt;strong&gt;X-Magento-Tags&lt;/strong&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;x-magento-tags: cms_b_site_home_main_banner,store,cms_b,cms_b_site_homepage_bar,cms_p_47,cms_b_header_custom_notice,cms_b_porto_custom_block_for_header_home5,cms_b_site_header_social_links,cms_b_site_home_shopby_category,cms_b_site_home_shopby_brand,cat_c_p_2,cat_p_2508,cat_p,cat_p_2483,cat_p_2387,cat_p_2372,cat_p_1412,cat_p_1388,cat_p_2575,cat_p_2560,cat_p_2557,cat_p_2543,cat_p_2520,cat_p_1262,cat_p_2434,cat_p_2423,cat_p_1660,cat_p_1579,cat_p_1276,cat_p_1217,cms_b_site_footer_social_links,cms_b_site_footer_contact_us,cms_b_site_footer_popular_items,cms_b_site_footer_quick_links,cms_b_site_footer_information
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Magento returns tags for page elements like the navigation, sidebar, and notice, as well as for product categories and
products. Products have tags in the format &lt;strong&gt;cat_p_1234&lt;/strong&gt;, where &lt;strong&gt;1234&lt;/strong&gt; is the product id in the database.&lt;/p&gt;
&lt;p&gt;When someone updates product 1234, a flush is issued for the tag &lt;strong&gt;cat_p_1234&lt;/strong&gt; and all pages that have that tag are
flushed. Magento doesn't have to do any work trying to determine which page the product might be on. The cache can
efficiently find those cached pages and invalidate them.&lt;/p&gt;
&lt;h2&gt;Cache tags in CMSs&lt;/h2&gt;
&lt;p&gt;As mentioned, Magento 2 uses a sophisticated cache tag strategy to maximise the performance of its full page cache. Other
CMSs, including Drupal 8/9/10 and Typo3, also utilise cache tags. Peakhour adds cache tags to &lt;a href="/docs/how-to-guides/integrations/wordpress"&gt;WordPress&lt;/a&gt;,
&lt;a href="/docs/how-to-guides/integrations/prestashop/"&gt;Prestashop&lt;/a&gt;, &lt;a href="/docs/how-to-guides/integrations/magento-1/"&gt;Magento 1&lt;/a&gt;, and &lt;a href="/docs/how-to-guides/integrations/opencart-3/"&gt;Opencart&lt;/a&gt;
via our plugins to enable full page caching.&lt;/p&gt;
&lt;h2&gt;Cache Tag support amongst CDNs&lt;/h2&gt;
&lt;p&gt;If you're looking for maximum full page cache effectiveness for your website, especially if you're using a CMS with
built-in cache tag support, cache tag support matters. The table below outlines support amongst major CDN providers.&lt;/p&gt;
&lt;table class="table table-striped"&gt;
&lt;tr&gt;&lt;th&gt;CDN/Cache&lt;/th&gt;&lt;th&gt;Cache Tag Support&lt;/th&gt;&lt;th&gt;Custom Header&lt;/th&gt;&lt;/tr&gt;
&lt;tr&gt;
    &lt;td&gt;Peakhour&lt;/td&gt;
    &lt;td&gt;&lt;i class="fas fa-check-circle text-green-500 text-xl"&gt;&lt;/i&gt;&lt;/td&gt;
    &lt;td&gt;&lt;i class="fas fa-check-circle text-green-500 text-xl"&gt;&lt;/i&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
    &lt;td&gt;Cloudflare&lt;/td&gt;
    &lt;td&gt;
        &lt;i class="fas fa-exclamation-triangle text-yellow-200 text-xl"&gt;&lt;/i&gt;
        Enterprise Plan Only
    &lt;/td&gt;
    &lt;td&gt;&lt;i class="fas fa-times-circle text-red-700 text-xl"&gt;&lt;/i&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
    &lt;td&gt;Fastly&lt;/td&gt;
    &lt;td&gt;&lt;i class="fas fa-check-circle text-green-500 text-xl"&gt;&lt;/i&gt;&lt;/td&gt;
    &lt;td&gt;&lt;i class="fas fa-check-circle text-green-500 text-xl"&gt;&lt;/i&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
    &lt;td&gt;Self Hosted Varnish&lt;/td&gt;
    &lt;td&gt;&lt;i class="fas fa-check-circle text-green-500 text-xl"&gt;&lt;/i&gt;&lt;/td&gt;
    &lt;td&gt;&lt;i class="fas fa-check-circle text-green-500 text-xl"&gt;&lt;/i&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
    &lt;td&gt;Cloudfront&lt;/td&gt;
    &lt;td&gt;&lt;i class="fas fa-times-circle text-red-700 text-xl"&gt;&lt;/i&gt;&lt;/td&gt;
    &lt;td&gt;&lt;i class="fas fa-times-circle text-red-700 text-xl"&gt;&lt;/i&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;

&lt;h2&gt;Enterprise or essential?&lt;/h2&gt;
&lt;p&gt;In our view, cache tags are an essential feature for any &lt;a href="/learning/cdn/"&gt;CDN&lt;/a&gt; trying to maximise cache performance.
They make cache invalidation targeted and efficient, which protects hit rates and reduces work on the origin server. They
shouldn't be walled off in an Enterprise-level package.&lt;/p&gt;</content><category term="Performance"></category><category term="Caching"></category><category term="CDN"></category><category term="Drupal"></category><category term="Web Performance"></category></entry><entry><title>Maximising Website Speed</title><link href="https://www.peakhour.io/blog/maximising-website-speed-an-essential-strategy/" rel="alternate"></link><published>2023-06-07T12:31:00+10:00</published><updated>2023-10-12T00:00:00+11:00</updated><author><name>AC</name></author><id>tag:www.peakhour.io,2023-06-07:/blog/maximising-website-speed-an-essential-strategy/</id><summary type="html">&lt;p&gt;How can maximising website speed boost your company's revenue, especially during an impending economic recession?&lt;/p&gt;</summary><content type="html">&lt;p&gt;As businesses prepare for a global economic downturn, every source of friction matters. One of the most controllable is
&lt;a href="/blog/wordpress-plugin/"&gt;website speed&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For many customers, the website is where they first test whether a business is worth their time. They learn about the
company, compare products, read content, and, if the experience holds up, buy. Loading time shapes that first
impression, affects engagement, and can change whether a visitor becomes a customer.&lt;/p&gt;
&lt;p&gt;This article looks at why speed deserves attention when trading conditions tighten. It covers search rankings,
conversion impact, and published case studies where faster sites produced measurable gains.&lt;/p&gt;
&lt;h2&gt;The Need for Speed&lt;/h2&gt;
&lt;p&gt;Website speed is not an abstract technical score. It is how quickly users can see and interact with content. A delay
measured in milliseconds can affect engagement, conversion rates, and customer retention.&lt;/p&gt;
&lt;p&gt;Speed matters because user expectations are set by fast services and fast networks. When a page feels slow, people leave
and are less likely to return.&lt;/p&gt;
&lt;p&gt;Speed also affects how search engines, including Google, rank
&lt;a href="/learning/performance/how-to-pass-core-web-vitals/"&gt;your website&lt;/a&gt;. For businesses trying to remain visible in a crowded market, especially
during an economic downturn, performance is a practical lever.&lt;/p&gt;
&lt;h2&gt;Correlation with Search Rankings&lt;/h2&gt;
&lt;p&gt;The relationship between website speed and search rankings is supported by research and by statements from Google. A few
years ago, Google announced that page speed would be a ranking factor. The change reflected Google's focus on relevant,
usable pages.&lt;/p&gt;
&lt;p&gt;Websites that meet all of Google's requirements receive a slight advantage, ranking
&lt;a href="https://www.sistrix.com/support/sistrix-visibility-index-explanation-background-and-calculation/" title="Visibility Index"&gt;one percentage point higher than the average&lt;/a&gt;. These requirements cover several areas, from content relevance and
quality to mobile-friendliness and &lt;a href="/solutions/use-case/improve-web-vitals/"&gt;page speed&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;By contrast, websites that fail to meet at least one of Google's requirements can sit at a measurable disadvantage,
&lt;a href="https://www.sistrix.com/support/sistrix-visibility-index-explanation-background-and-calculation/" title="Visibility Index"&gt;ranking 3.7 percentage points lower&lt;/a&gt;. That matters when search visibility is already under pressure.&lt;/p&gt;
&lt;p&gt;Google's Core Web Vitals have also become a measurable factor in search rankings. These vitals measure aspects of page
speed and user experience, showing how speed and SEO (Search Engine Optimisation) now overlap.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://crystallize.com/blog/this-is-how-much-site-speed-affects-google-seo-ranking-with-data" title="How Site Speed Affects SEO &amp;amp; Google Rankings (With Data)?"&gt;A study by Crystallize&lt;/a&gt; also found a correlation between speed and SEO. In their page speed score experiment, a page
with a high score ranked #1 in Google with a featured snippet for the optimised item. Unoptimised pages with lower speed
scores did not appear in search results.&lt;/p&gt;
&lt;p&gt;The practical point is straightforward: website speed can improve search visibility. In an economic downturn, that extra
visibility can matter.&lt;/p&gt;
&lt;h2&gt;Conversion Impact of Speed&lt;/h2&gt;
&lt;p&gt;Speed also affects conversion rates. Deloitte's 'Milliseconds Make Millions' report shows how small improvements in
loading time can change commercial outcomes.&lt;/p&gt;
&lt;p&gt;The study examined a 0.1 second decrease in loading time across different market sectors. In retail, &lt;a href="https://www2.deloitte.com/content/dam/Deloitte/ie/Documents/Consulting/Milliseconds_Make_Millions_report.pdf" title="Milliseconds Make Millions"&gt;a quicker page
loading time led to an 8.4% rise in conversion rates&lt;/a&gt; and a &lt;a href="https://www2.deloitte.com/content/dam/Deloitte/ie/Documents/Consulting/Milliseconds_Make_Millions_report.pdf" title="Milliseconds Make Millions"&gt;9.2% improvement in average shopping basket size&lt;/a&gt;. The
travel sector saw a &lt;a href="https://www2.deloitte.com/content/dam/Deloitte/ie/Documents/Consulting/Milliseconds_Make_Millions_report.pdf" title="Milliseconds Make Millions"&gt;10.1% increase in conversion rates&lt;/a&gt; and a &lt;a href="https://www2.deloitte.com/content/dam/Deloitte/ie/Documents/Consulting/Milliseconds_Make_Millions_report.pdf" title="Milliseconds Make Millions"&gt;1.9% rise in average basket size&lt;/a&gt;. For luxury
brands, faster loading times resulted in an &lt;a href="https://www2.deloitte.com/content/dam/Deloitte/ie/Documents/Consulting/Milliseconds_Make_Millions_report.pdf" title="Milliseconds Make Millions"&gt;8.6% increase in page views per session&lt;/a&gt; and an &lt;a href="https://www2.deloitte.com/content/dam/Deloitte/ie/Documents/Consulting/Milliseconds_Make_Millions_report.pdf" title="Milliseconds Make Millions"&gt;8.3% decrease in form
bounce rates&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Peakhour clients have seen the same pattern. Pharmacy Direct reported a 30% increase in conversions and order value
after reducing page load time by 90%. Kitchen Warehouse saw a 150% increase in revenue after decreasing page load times
by 70%.&lt;/p&gt;
&lt;p&gt;These numbers show that page speed is tied to business metrics, not just technical scores. The scale varies by site and
sector, but the direction is consistent across the cited examples.&lt;/p&gt;
&lt;h2&gt;Real-Life Success Stories&lt;/h2&gt;
&lt;p&gt;The effects of website speed optimisation are visible in published case studies:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;French linen brand Carré Blanc saw a &lt;a href="https://info.fasterize.com/etude-de-cas-carre-blanc" title="[Success Story] Carré Blanc : des conversions et un CA boostés par un site rapide"&gt;25% increase in conversion rates&lt;/a&gt; after improving web page loading
   speed.&lt;/li&gt;
&lt;li&gt;Renault optimised the Largest Contentful Paint (LCP), leading to a 14 percentage point decrease in bounce
   rate and a &lt;a href="https://web.dev/renault/" title="How Renault improved its bounce and conversion rates by measuring and optimizing Largest Contentful Paint"&gt;13% rise in conversions&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;E-commerce platform eBay found that every 100ms improvement in search page loading time resulted in a &lt;a href="https://www2.deloitte.com/content/dam/Deloitte/ie/Documents/Consulting/Milliseconds_Make_Millions_report.pdf" title="Milliseconds Make Millions"&gt;0.5% increase
   in additions to the shopping cart&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;SnipesUSA.com &lt;a href="https://www.digitalcommerce360.com/2020/10/07/snipesusa-invests-in-site-speed-now-and-for-the-future/" title="Snipes invests in site speed now and for the future"&gt;doubled their average conversion rate&lt;/a&gt; from about 1% to about 2% by decreasing load times by
   30%.&lt;/li&gt;
&lt;li&gt;French toy retailer King Jouet enjoyed a &lt;a href="https://www.fasterize.com/fr/blog/king-jouet-soulage-ses-serveurs-et-maintient-la-fluidite-de-la-navigation-pendant-les-pics-de-charge-grace-a-fasterize/" title="Soldes : comment King Jouet maintient une navigation fluide pendant les pics de charge "&gt;5% increase in conversion rates&lt;/a&gt; within a month through page speed
   optimisation.&lt;/li&gt;
&lt;li&gt;AliExpress, a global online retail marketplace, experienced a 10.5% increase in orders and a 27% increase in
   conversions for new customers by reducing loading time by 36%.&lt;/li&gt;
&lt;li&gt;Boutique designer brand Revelry saw 43% faster page loading, an 8% decrease in bounce rates, and a &lt;a href="https://www.digitalcommerce360.com/2020/09/22/revelrys-bounce-rate-plummets-with-faster-site/" title="Revelry’s bounce rate plummets with faster site"&gt;30% increase in
   conversions&lt;/a&gt; after optimising images on their eCommerce site.&lt;/li&gt;
&lt;li&gt;Zalando, an online fashion platform, reported a &lt;a href="https://engineering.zalando.com/posts/2018/06/loading-time-matters.html" title="Loading Time Matters"&gt;revenue increase of 0.7% per session&lt;/a&gt; by reducing web page loading
   time by 100ms.&lt;/li&gt;
&lt;li&gt;Pinterest observed a &lt;a href="https://medium.com/pinterest-engineering/driving-user-growth-with-performance-improvements-cfc50dafadd7" title="Driving user growth with performance improvements"&gt;15% increase in platform registrations&lt;/a&gt; following an improvement in loading speed.&lt;/li&gt;
&lt;li&gt;Telecommunications company Vodafone saw an &lt;a href="https://web.dev/vodafone/" title="Vodafone: A 31% improvement in LCP increased sales by 8%"&gt;8% sales increase&lt;/a&gt; with a 31% improvement in Largest Contentful Paint (
    LCP).&lt;/li&gt;
&lt;li&gt;Mobile marketplace Swappie achieved a &lt;a href="https://web.dev/swappie/" title="How Swappie increased mobile revenue by 42% by focusing on Core Web Vitals"&gt;42% increase in mobile revenue&lt;/a&gt; by focusing on Core Web Vitals.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;These examples show how improving loading speed can lift conversion rates and revenue.&lt;/p&gt;
&lt;h2&gt;Optimising for Search Performance&lt;/h2&gt;
&lt;p&gt;Speed also affects search performance beyond organic ranking. Several examples point to paid search impact:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Lever Interactive Agency reported that one of their clients improved their Quality Score, resulting in a &lt;a href="https://leverinteractive.com/blog/why-page-speed-is-more-than-just-seo/" title="Why Page Speed is More Than Just SEO"&gt;17% decrease
   in Cost Per Click&lt;/a&gt; (CPC), a &lt;a href="https://leverinteractive.com/blog/why-page-speed-is-more-than-just-seo/" title="Why Page Speed is More Than Just SEO"&gt;31% decrease in Cost Per Acquisition&lt;/a&gt; (CPA), and a &lt;a href="https://leverinteractive.com/blog/why-page-speed-is-more-than-just-seo/" title="Why Page Speed is More Than Just SEO"&gt;20% increase in conversion rate&lt;/a&gt; on
   faster landing pages.&lt;/li&gt;
&lt;li&gt;Crystallize Headless Commerce noted that scoring high in the Quality Score can lead to significant benefits,
   including up to a &lt;a href="https://crystallize.com/blog/site-speed-affects-adwords-pricing" title="Site Speed Affects Adwords Pricing"&gt;50% discount on CPC prices&lt;/a&gt;. Conversely, a low Quality Score can result in paying up to 400% extra,
   severely impacting your marketing budget.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Core Web Vitals have also become a priority for eCommerce platform Shopify. The company continues to optimise speed
performance to improve search rankings.&lt;/p&gt;
&lt;p&gt;These cases show why performance work needs to be ongoing, especially where search traffic and paid acquisition costs
are material to the business.&lt;/p&gt;
&lt;h2&gt;Enhancing Engagement&lt;/h2&gt;
&lt;p&gt;Engagement is not separate from speed. A fast, well-optimised site gives users less reason to leave and more opportunity
to browse, compare, and interact. The data supports this in several ways.&lt;/p&gt;
&lt;p&gt;Take eCommerce for instance. Customers are 10% more likely to recommend an eCommerce website when pages load in 10
seconds instead of 13 seconds. The likelihood of recommendation rises to 26% if loading time is reduced to 3 seconds.
That shows how quickly performance changes user perception.&lt;/p&gt;
&lt;p&gt;Other companies have also seen measurable effects from speed optimisation. Netflix implemented Gzip compression for
resource optimisation, resulting in a 43% reduction in outbound traffic. Yahoo Japan News saw &lt;a href="https://web.dev/yahoo-japan-news/" title="How CLS optimizations increased Yahoo! JAPAN News's page views per session by 15%"&gt;increases in both page
views per session and session times (15% and 13% respectively)&lt;/a&gt;, as well as a 1.72% decrease in bounce rate, by
improving their Cumulative Layout Shift (CLS) by 0.2 points.&lt;/p&gt;
&lt;p&gt;Google has also published data linking Core Web Vitals to engagement. Their data showed that favourable Core Web Vitals
scores can &lt;a href="https://blog.chromium.org/2020/05/the-science-behind-web-vitals.html" title="The Science Behind Web Vitals"&gt;reduce the likelihood of users abandoning a page&lt;/a&gt; before it loads by up to 24%. Meeting Core Web Vitals
thresholds also led to an overall &lt;a href="https://web.dev/economic-times-cwv/" title="How The Economic Times passed Core Web Vitals thresholds and achieved an overall 43% better bounce rate"&gt;43% improvement in bounce rate&lt;/a&gt; for The Economic Times.&lt;/p&gt;
&lt;p&gt;The agriculture e-commerce platform, Agrofy, improved their Core Web Vitals scores by 70% for LCP and 72% for CLS,
resulting in a &lt;a href="https://web.dev/agrofy/" title="Agrofy: A 70% improvement in LCP correlated to a 76% reduction in load abandonment"&gt;76% reduction in abandonment rate&lt;/a&gt;. Again, the useful lesson is not just that the site became faster.
It is that users behaved differently once it did.&lt;/p&gt;
&lt;h2&gt;Key Speed Metrics&lt;/h2&gt;
&lt;p&gt;Website speed is about more than full-page load time. Several metrics help assess how fast and stable a page feels to a
user. Google's &lt;a href="https://developers.google.com/speed/docs/insights/v5/about" title="About PageSpeed Insights"&gt;Pagespeed Insights&lt;/a&gt; lists the following important metrics:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Largest Contentful Paint (LCP)&lt;/strong&gt; measures the time taken to load the largest visible content on the page. The ideal
   target for this is less than 2.5 seconds. This metric matters because it provides a clear indicator of perceived
   load speed for the user.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Cumulative Layout Shift (CLS)&lt;/strong&gt; evaluates the visual stability of a page during loading. The target here is less
   than 0.1. This helps limit content jumping or shifting while the page loads, providing a smoother user experience.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;First Input Delay&lt;/strong&gt; determines how quickly a page responds to user input, with the target being less than 0.1
   seconds. This metric measures the interactivity and responsiveness of a website.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Together, these metrics show whether a website delivers a fast, smooth user experience.&lt;/p&gt;
&lt;h2&gt;User Expectations and Impact on Business&lt;/h2&gt;
&lt;p&gt;Users expect pages to respond quickly. When they do not, speed becomes a business issue rather than only an engineering
issue.&lt;/p&gt;
&lt;p&gt;According to Think with Google, slow-loading pages can affect user experience, resulting in higher bounce rates,
negative brand perception, and an impact on conversions and revenue. When users have to wait too long for a webpage to
load, they are likely to leave and look for a faster experience elsewhere.&lt;/p&gt;
&lt;p&gt;Digital marketing expert Neil Patel highlights that a 1-second delay in page response can lead to a &lt;a href="https://neilpatel.com/blog/loading-time/" title="How Loading Time Effects Your Bottom Line"&gt;7% reduction in
conversions&lt;/a&gt;. To put that into perspective, if an e-commerce site is making $100,000 per day, a 1-second page delay
could cost $2.5 million in lost sales every year.&lt;/p&gt;
&lt;p&gt;Akamai also found that &lt;a href="https://www.akamai.com/newsroom/press-release/akamai-releases-spring-2017-state-of-online-retail-performance-report" title="Akamai Online Retail Performance Report"&gt;53% of mobile site visitors will leave a page&lt;/a&gt; that takes longer than three seconds to load.
This shows the standards modern users have for &lt;a href="/blog/testing-sitespeed-lighthouse/"&gt;website performance&lt;/a&gt; and the revenue
risk for businesses that fail to meet them.&lt;/p&gt;
&lt;h2&gt;Common Culprits&lt;/h2&gt;
&lt;p&gt;If your website is running slowly, a few common issues could be to blame. The usual causes are technical and operational:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Time to First Byte (TTFB)&lt;/strong&gt; is the time it takes for the first byte of data to be received from the server. High
   TTFB can affect loading times and should be minimised.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Large Page Size and Resources&lt;/strong&gt; can also contribute to slow loading times. This includes heavy content, such as
   images, videos, or large files. Optimising these resources can materially improve loading speed.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Third-Party Resources&lt;/strong&gt; like ads, plugins, or widgets can require additional loading time. While these are often
   necessary, they need to be managed carefully to avoid excessive loading delays.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;JavaScript&lt;/strong&gt; can be a double-edged sword. While it enables advanced functionality, complex or poorly optimised
   JavaScript code can also hinder performance.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Single-Page Applications (SPAs)&lt;/strong&gt; may experience slower initial loading due to their extensive scripting
   requirements, but they often offer faster navigation once loaded.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Busy Servers Handling Bot Traffic&lt;/strong&gt; can also cause slowdowns. Bot traffic, in some instances, can account for over
   40% of server load. Managing this effectively can help improve website speed.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Understanding which of these factors applies to your site helps you focus performance work where it will matter.&lt;/p&gt;
&lt;h2&gt;Continuous Monitoring and Performance Optimisation&lt;/h2&gt;
&lt;p&gt;Getting a site fast once is not enough. Speed can regress as content, third-party tags, releases, and traffic patterns
change, so monitoring and performance optimisation need to be continuous.&lt;/p&gt;
&lt;p&gt;Tools such as Google's Pagespeed Insights can help track website performance. Regular checks of key metrics can show
which issues are slowing the site down and which changes need attention.&lt;/p&gt;
&lt;p&gt;It is also important to test improvements on a staging website before deploying them to production. That reduces the
risk of disrupting live performance or user experience. Regular diagnostic testing and iterative improvements help keep
the site aligned with current performance expectations.&lt;/p&gt;
&lt;p&gt;As SEO consulting company Moz highlights, &lt;a href="https://moz.com/"&gt;focusing on continuous performance optimisation can have significant benefits.&lt;/a&gt;
It can help maintain a fast, usable site and support higher search rankings, better engagement, and increased
conversions and revenue.&lt;/p&gt;
&lt;h2&gt;Preparing for the Coming Recession&lt;/h2&gt;
&lt;p&gt;With an economic downturn on the horizon, a fast, well-optimised website becomes more important. Consumers are likely to
be more selective with their spending, and businesses will need to compete harder for each sale.&lt;/p&gt;
&lt;p&gt;A fast website can be a useful differentiator in this environment. It can &lt;a href="/blog/magento-1-plugin/"&gt;boost your&lt;/a&gt; search
rankings, making the site more visible to potential customers. It can improve engagement by giving visitors fewer
reasons to leave. It can also increase conversion rates, which has a direct effect on sales.&lt;/p&gt;
&lt;p&gt;In this context, website speed is not cosmetic. It is an operating requirement. The work is to measure the current
experience, fix the main bottlenecks, and keep monitoring performance as the site changes.&lt;/p&gt;
&lt;p&gt;The data and case studies point in the same direction: speed optimisation is a practical investment. It helps align the
website with user expectations and makes the site a more effective part of the business.&lt;/p&gt;
&lt;p&gt;Website speed is measurable, improvable, and commercially relevant. For businesses preparing for tighter conditions, it
deserves active management rather than occasional clean-up.&lt;/p&gt;</content><category term="Performance"></category><category term="Web Performance"></category><category term="SEO"></category><category term="Analytics"></category><category term="Magento"></category><category term="Core Web Vitals"></category><category term="CDN"></category></entry><entry><title>Understanding HTTP Link Headers</title><link href="https://www.peakhour.io/blog/http-link-headers/" rel="alternate"></link><published>2023-05-24T13:00:00+10:00</published><updated>2023-05-24T13:00:00+10:00</updated><author><name>Dan</name></author><id>tag:www.peakhour.io,2023-05-24:/blog/http-link-headers/</id><summary type="html">&lt;p&gt;HTTP Link headers are a relatively unknown but powerful way to improve page load times.&lt;/p&gt;</summary><content type="html">&lt;p&gt;HTTP headers are part of browser requests and server responses. They carry information about the
connecting client, the requested resource, the server, and other request context.
An HTTP header has a case-insensitive name followed by a colon (:), then its value. Headers are used for
authentication information, content negotiation, and related protocol behaviour. Here are some sample
request headers sent by my browser when requesting a page on the Peakhour website:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="sr"&gt;/html,application/xhtml+xml,application/xml;q=0.9,*/&lt;/span&gt;&lt;span class="o"&gt;*;&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.8&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Encoding&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;gzip&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;deflate&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;br&lt;/span&gt;
&lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Language&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;en&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;AU&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="n"&gt;en&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.9&lt;/span&gt;
&lt;span class="n"&gt;Connection&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;keep&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;alive&lt;/span&gt;
&lt;span class="n"&gt;Cookie&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;_ga_NRWSVE0PSC&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;GS1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;1.1685943893&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;13.0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;1685943893.0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;0.0&lt;/span&gt;
&lt;span class="n"&gt;Host&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;www&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;peakhour&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;io&lt;/span&gt;
&lt;span class="n"&gt;Sec&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Dest&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;document&lt;/span&gt;
&lt;span class="n"&gt;Sec&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Mode&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;navigate&lt;/span&gt;
&lt;span class="n"&gt;Sec&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Fetch&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Site&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;none&lt;/span&gt;
&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Mozilla&lt;/span&gt;&lt;span class="sr"&gt;/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4.1 Safari/&lt;/span&gt;&lt;span class="mf"&gt;605.1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;The HTTP Link header&lt;/h2&gt;
&lt;p&gt;An HTTP Link header lets a server send
context about a document back to a client. It can identify related
resources or the direct location of a specific asset. For page-load optimisation, Link headers can be an alternative to
putting preload/preconnect/prefetch hints in the HTML.&lt;/p&gt;
&lt;h2&gt;History&lt;/h2&gt;
&lt;p&gt;HTTP Link headers were proposed as a standard in the late 1990s, around the same time the
HTTP/1.1 protocol was defined. However, it wasn't until 2010 that HTTP Link headers were officially recognised by
the Internet Engineering Task Force (IETF) in RFC 5988, which described their purpose and functionality.&lt;/p&gt;
&lt;h2&gt;Uses&lt;/h2&gt;
&lt;p&gt;HTTP Link headers have several uses in web development. Some common examples are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Pagination&lt;/strong&gt;: Say we have a blog site with hundreds of posts, and we display 10 posts per page.
  When a user requests a page, we can use Link headers to provide URLs for the next and previous pages.
  This helps navigation through the large list of posts. Here's an example of how it might look:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Link:&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;&lt;/span&gt;/posts?page=2&amp;gt;;&lt;span class="w"&gt; &lt;/span&gt;rel=&amp;quot;next&amp;quot;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;&lt;/span&gt;/posts?page=4&amp;gt;;&lt;span class="w"&gt; &lt;/span&gt;rel=&amp;quot;prev&amp;quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Preloading&lt;/strong&gt;: Suppose we have a heavy image or a large CSS file that we know will be required for a webpage.
  We can use a Link header to tell the browser to start downloading it early, improving the perceived page
  load speed. For instance:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;Link&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;images&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;big&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;picture&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;jpg&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;preload&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Resource Hints&lt;/strong&gt;: Link headers can give the browser hints about resources that might be needed in the
  future, so the browser can decide whether to fetch them ahead of time. For instance:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;Link&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;scripts&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nt"&gt;myscript&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;js&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nt"&gt;prefetch&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Comparison to Link Tags and Why Headers Can Be Better&lt;/h2&gt;
&lt;p&gt;Now you might be wondering, "Why use Link headers when we can use HTML Link tags?" There are several reasons
HTTP Link headers might be a better choice:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Faster Processing&lt;/strong&gt;: Since HTTP Link headers are part of the HTTP response, they arrive before the HTML document.
  This allows browsers to start preloading or prefetching resources sooner, which can improve page load times.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Greater Flexibility&lt;/strong&gt;: HTTP Link headers can be used in situations where HTML Link tags cannot. For instance, they
  can be used with file types that don't support HTML, like JSON or XML. They can also be added by a third party, e.g.,
  &lt;strong&gt;an edge delivery layer such as Peakhour&lt;/strong&gt;, without the need to parse and rewrite the HTML document.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Less Clutter&lt;/strong&gt;: Link headers can make your HTML less cluttered, as you can avoid filling the HTML document with
  numerous Link tags.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;HTTP Link headers are a small part of HTTP, but they are useful for performance and flexibility. An edge delivery layer
can add Link headers without the overhead of parsing or manipulating the main document, which makes them useful for
optimising website performance.&lt;/p&gt;</content><category term="Learning"></category><category term="HTTP"></category><category term="Web Performance"></category><category term="Caching"></category><category term="Rate Limiting"></category><category term="Core Web Vitals"></category><category term="CDN"></category></entry><entry><title>When Bots Break Bad</title><link href="https://www.peakhour.io/blog/when-good-bots-break-bad/" rel="alternate"></link><published>2023-05-16T13:00:00+10:00</published><updated>2023-05-16T13:00:00+10:00</updated><author><name>Dan</name></author><id>tag:www.peakhour.io,2023-05-16:/blog/when-good-bots-break-bad/</id><summary type="html">&lt;p&gt;Even 'good' bots can end up abusing your site and impacting performance, learn why and how to stop it.&lt;/p&gt;</summary><content type="html">&lt;p&gt;Bots account for a large share of web traffic. Recent studies put automated traffic at nearly 50% of all internet
requests. Some bots are useful, such as search engine crawlers that index your site. Some are clearly harmful, such
as scrapers and sneaker bots. Others sit in a grey area, including backlink and marketing bots from services such as
Ahrefs and SEMrush. Even useful bots can create problems when they crawl too hard. This article looks at the main bot
types and how to manage them with robots.txt and &lt;a href="/learning/bots/bot-management/"&gt;bot management&lt;/a&gt; tools.&lt;/p&gt;
&lt;h2&gt;Understanding the Different Types of Bots&lt;/h2&gt;
&lt;h3&gt;'Good Bots'&lt;/h3&gt;
&lt;p&gt;Good bots perform legitimate work. Search engine crawlers like Googlebot and Bingbot index webpages so search results
can stay current and relevant. Other examples include uptime and performance monitoring bots.&lt;/p&gt;
&lt;h3&gt;'Bad Bots'&lt;/h3&gt;
&lt;p&gt;Bad bots harm websites, users, or both. Common examples include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Scraping content&lt;/strong&gt;, copying and repurposing data from websites.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sneaker bots&lt;/strong&gt;, automatically purchasing limited-edition products (like sneakers) before human users can.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Spam bots&lt;/strong&gt;, posting unsolicited messages and advertisements in comment sections or forums.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Vulnerability Scanners&lt;/strong&gt;, trying thousands of website URLs to find security vulnerabilities.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Account Takeover&lt;/strong&gt;, attempting to gain access to existing user/admin
  accounts using either credential stuffing or brute-force
  attacks.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;'Grey Bots'&lt;/h3&gt;
&lt;p&gt;Grey bots sit between good and bad. They often serve a useful purpose and may follow crawling directives in robots.txt,
but they can still cause problems when they crawl too aggressively. Common examples include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AhrefsBot: A backlink analysis bot used by Ahrefs, an SEO tool.&lt;/li&gt;
&lt;li&gt;SEMrushBot: A bot used by SEMrush, another popular SEO and digital marketing tool.&lt;/li&gt;
&lt;li&gt;MJ12bot: A bot used by Majestic, a service that provides backlink data and analysis.&lt;/li&gt;
&lt;li&gt;ScreamingFrog: An SEO analyser run from a local desktop.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;When Grey bots (and even Good Bots) go bad.&lt;/h2&gt;
&lt;p&gt;Left unattended, grey bots can create practical problems:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Slow page loading times, which affect user experience.&lt;/li&gt;
&lt;li&gt;Strain on server resources, potentially causing crashes, downtime, and higher costs.&lt;/li&gt;
&lt;li&gt;Distorted website analytics, when bot traffic is mistaken for human traffic.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Managing Grey Bots with Robots.txt&lt;/h2&gt;
&lt;p&gt;The robots.txt file is a simple text file that tells web crawlers which parts of your site they can or cannot access.
You can use it to manage bot behaviour and protect &lt;a href="/learning/performance/how-to-pass-core-web-vitals/"&gt;your website&lt;/a&gt; from aggressive crawling. Useful controls
include:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Disallowing specific bots:&lt;/strong&gt; You can block specific bots from accessing your site by adding a "User-agent" and
"Disallow" directive to your robots.txt file. For example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;User-agent: AhrefsBot
Disallow: /
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Limiting crawl rate:&lt;/strong&gt; You can ask bots to slow down their crawling by adding a "Crawl-delay" directive:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;User-agent: SEMrushBot
Crawl-delay: 10
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Not all bots will follow robots.txt. ScreamingFrog, for example, can be instructed to ignore robots.txt and crawl a
site as quickly as possible. You would not want a competitor doing this to your site.&lt;/p&gt;
&lt;h2&gt;Bot Management Tools&lt;/h2&gt;
&lt;p&gt;In addition to robots.txt, bot management tools (like those provided by Peakhour) can protect your website from
abusive bots. Good bot management tools automatically block most unwanted traffic using a combination of
&lt;a href="/blog/ip-threat-intelligence/"&gt;Threat Intelligence&lt;/a&gt;, &lt;a href="/blog/tls-fingerprinting/"&gt;Fingerprinting techniques&lt;/a&gt;, Reverse DNS
verification, and Header Inspection.&lt;/p&gt;
&lt;p&gt;Advanced techniques like rate limiting and machine learning can help identify more sophisticated bad bots.&lt;/p&gt;
&lt;h2&gt;Search Bots and Double Crawling&lt;/h2&gt;
&lt;p&gt;Search bots like Bingbot can sometimes blindly follow links and crawl the same page multiple times due to different
URL parameters. This double, triple, or worse crawling can increase server load and make indexing less efficient.
eCommerce sites are especially exposed because product catalogues often have several filtering paths. We've seen Bing
go haywire on a number of sites. Most recently, it was issuing around 50,000 requests per day to the search function
of a Magento 2 store while cycling through parameters. This dropped to 2-3k requests per day when fixed. On another
store, Bing was responsible for nearly half of all page requests (40k page requests) on a busy OpenCart store.
Configuring it to ignore parameters dropped this to around 4k per day.&lt;/p&gt;
&lt;h3&gt;Configuring Search Bots to Ignore Query Parameters&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Note: Since publishing both Google and Bing have removed the ability to ignore parameters when crawling via their
webmaster/search console tools. See &lt;a href="/blog/how-to-exclude-query-string-parameters-from-search-engines-using-robots-txt/"&gt;using robots.txt to instruct search engines to ignore query string parameters&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;To help search bots crawl your site efficiently, you can configure them to ignore specific query parameters. Use these
methods:&lt;/p&gt;
&lt;h4&gt;Configuring Bing Webmaster Tools&lt;/h4&gt;
&lt;p&gt;Bing Webmaster Tools provides an option to specify URL parameters that should be ignored during the crawling process.
To configure this setting, follow these steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Sign in to your Bing Webmaster Tools account and select the website you want to manage.&lt;/li&gt;
&lt;li&gt;Navigate to the "Configure My Site" section and click on "URL Parameters."&lt;/li&gt;
&lt;li&gt;Click on "Add Parameter" and enter the parameter name you want Bingbot to ignore.&lt;/li&gt;
&lt;li&gt;Select "Ignore this parameter" from the dropdown menu and click on "Save."&lt;/li&gt;
&lt;li&gt;Configuring Bing Webmaster Tools this way helps stop Bingbot double crawling pages with specific URL parameters, reducing server load and improving indexing efficiency.&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;Managing Other Search Bots&lt;/h4&gt;
&lt;p&gt;For other search engines like Google, use the relevant webmaster tools to manage URL parameters. In Google Search
Console, follow these steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Sign in to your Google Search Console account and select the property you want to manage.&lt;/li&gt;
&lt;li&gt;Navigate to the "Crawl" section and click on "URL Parameters."&lt;/li&gt;
&lt;li&gt;Click on "Add Parameter" and enter the parameter name you want Googlebot to ignore.&lt;/li&gt;
&lt;li&gt;Choose "No URLs" from the "Does this parameter change page content seen by the user?" dropdown menu.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Click on "Save."&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Specifying the parameters you want search bots to ignore can prevent double crawling and make indexing more efficient.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Final Thoughts&lt;/h2&gt;
&lt;p&gt;When good or grey bots crawl too aggressively, they can cause the same operational problems as malicious bots:
overloaded servers, slower pages, and worse user experience. Monitor website traffic and server load, set clear
robots.txt rules, and use the major search engines' webmaster tools to control inefficient crawling. Done properly,
this improves website performance and can lower infrastructure costs.&lt;/p&gt;</content><category term="Bots"></category><category term="Bot Management"></category><category term="SEO"></category><category term="Residential Proxies"></category><category term="DNS"></category><category term="Web Performance"></category><category term="Anomaly Detection"></category></entry><entry><title>Multi-Origin Load Balancing</title><link href="https://www.peakhour.io/blog/multi-origin-load-balancing/" rel="alternate"></link><published>2023-04-11T13:00:00+10:00</published><updated>2023-04-11T13:00:00+10:00</updated><author><name>Dan</name></author><id>tag:www.peakhour.io,2023-04-11:/blog/multi-origin-load-balancing/</id><summary type="html">&lt;p&gt;Websites with a global audience need more than just a traditional CDN. They need geographic multi origin load balancing.&lt;/p&gt;</summary><content type="html">&lt;p&gt;Websites and applications with global audiences often run into a problem that a standard CDN cannot always hide: not
every request can be served from cache. Traditional Content Delivery Networks (CDNs) reduce latency by distributing
content across multiple points of presence (POPs) around the world. But when content has to be fetched from a distant
origin server, for example dynamic content that cannot be cached, users still wait on that round trip. This post explains
the problem multi-origin &lt;a href="/learning/load-balancing/"&gt;load balancing&lt;/a&gt; solves and how Peakhour handles it.&lt;/p&gt;
&lt;h2&gt;Understanding the Problem&lt;/h2&gt;
&lt;p&gt;Web content usually starts from a single server, called the origin server. As a website's audience grows, that server
takes more traffic, which can slow response times. CDNs reduce the pressure by caching and delivering content from
servers distributed across multiple geographic locations. When the content is already cached, this reduces origin load
and lowers latency for users accessing the content.&lt;/p&gt;
&lt;p&gt;However, traditional CDNs still have limits when serving global audiences. If a user requests content that is not cached
in the CDN, the request has to go back to the origin server. If that origin is far away from the user, latency increases
and pages take longer to load.&lt;/p&gt;
&lt;p&gt;Multi-origin load balancing addresses that remaining gap in &lt;a href="/learning/cdn/"&gt;CDN&lt;/a&gt; performance and further reduces latency.&lt;/p&gt;
&lt;h2&gt;Introducing Multi-Origin Load Balancing&lt;/h2&gt;
&lt;p&gt;Traditional load balancing distributes traffic evenly across two or more servers that
are physically hosted in the same location.&lt;/p&gt;
&lt;p&gt;Multi-origin load balancing extends that approach across origin servers in different geographical locations. The
Peakhour EDGE can select the closest origin server to a user, or choose a different origin based on criteria such as
device type, user preferences, or URL. For requests not stored in the CDN, this reduces the time spent crossing long
network paths.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Real-Time Performance Monitoring:&lt;/strong&gt; Peakhour continuously monitors its global network of servers in real time. This
allows the system to detect potential issues or bottlenecks and adjust routing. If one origin server experiences high
traffic or goes offline, Peakhour can reroute user requests to the next best server to keep the site responsive.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Adaptive Content Caching:&lt;/strong&gt; Peakhour Edge uses adaptive content caching strategies, which dynamically cache both
static and dynamic content based on user behaviour and request patterns. Frequently requested dynamic elements, such as
personalised user data or search results, are cached on edge servers, reducing the need to fetch content from the
origin servers and further minimising latency.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Load Balancing and Failover:&lt;/strong&gt; Peakhour's multi-origin load balancing is complemented by load balancing and failover
mechanisms. These features keep the system resilient and responsive during periods of high traffic or server outages.
By distributing user requests evenly across origin servers and automatically redirecting traffic when a server fails,
Peakhour maintains a stable and reliable content delivery experience for users worldwide.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Multi-origin load balancing addresses the limitations of traditional CDNs by optimising content delivery for a global
audience. Peakhour Edge reduces latency and improves the experience for users who would otherwise wait on a distant
origin server.&lt;/p&gt;
&lt;p&gt;As web content and applications grow in complexity and reach, origin placement and routing become part of performance
planning. Peakhour implements multi-origin load balancing with clients' origin servers so requests can be sent to the
most suitable origin instead of treating a single distant server as the only fallback.&lt;/p&gt;</content><category term="Features"></category><category term="CDN"></category><category term="Web Performance"></category><category term="Drupal"></category><category term="Caching"></category><category term="Rate Limiting"></category></entry><entry><title>Automatic Image Optimisation</title><link href="https://www.peakhour.io/blog/automatic-image-optimisation/" rel="alternate"></link><published>2022-12-06T13:00:00+11:00</published><updated>2022-12-06T13:00:00+11:00</updated><author><name>AC</name></author><id>tag:www.peakhour.io,2022-12-06:/blog/automatic-image-optimisation/</id><summary type="html">&lt;p&gt;Image optimisation saves you bandwidth and designer effort while reduces page load time.&lt;/p&gt;</summary><content type="html">&lt;p&gt;Since releasing our &lt;a href="/image-optimisation/"&gt;automatic image optimisation&lt;/a&gt; capability in 2019, Peakhour optimises
more than 35 million images each month. On average, clients reduce page download time by 35% and image sizes by
91%.&lt;/p&gt;
&lt;p&gt;Automatic image optimisation offers a number of benefits over manual optimisation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Image formats are dynamically chosen based on the content of the image.&lt;/li&gt;
&lt;li&gt;Files are optimised based on client capabilities.&lt;/li&gt;
&lt;li&gt;Designer time is saved by offloading image optimisation work.&lt;/li&gt;
&lt;li&gt;Page load times can be reduced across an entire website.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;What is Image Optimisation?&lt;/h2&gt;
&lt;p&gt;Image optimisation means delivering high quality images in the right format and resolution for the device viewing them.
The aim is to minimise file size without compromising visual quality. Smaller image files generally load faster in a
visitor's browser, which can improve website speed, reduce traffic and support higher page visits and conversions.&lt;/p&gt;
&lt;h2&gt;Why dynamically choose the image format?&lt;/h2&gt;
&lt;p&gt;Using a one size fits all optimisation process does not account for the different types of images used across a typical
website.&lt;/p&gt;
&lt;p&gt;Website images can include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Photographs, such as product images, demonstration photos and title photos.&lt;/li&gt;
&lt;li&gt;Logos, which are typically text and can include animation.&lt;/li&gt;
&lt;li&gt;Illustrations that incorporate custom graphics to support the quick perception of information.&lt;/li&gt;
&lt;li&gt;3D graphics from computer renders including buildings, interior and exterior designs and products.&lt;/li&gt;
&lt;li&gt;Combinations of the above!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Any optimisation process needs to account for the end user's device type, supported file formats, resolution and the
content of the image. For example, a photograph with text needs different optimisation parameters so the text remains
crisp, while images with large areas of colour may need different formats to avoid colours being degraded by lossy
compression.&lt;/p&gt;
&lt;h2&gt;Fine developer control&lt;/h2&gt;
&lt;p&gt;With the &lt;a href="/docs/explanation/image-optimisation/api/"&gt;image optimisation API&lt;/a&gt;, your developers can enable reactive images by
resizing images on the edge. Peakhour serves and caches these optimisations, reducing origin requests and traffic,
cutting costs and making image changes faster to ship. You no longer need to wait for a designer to resize, crop or
re-orient an image for a page.&lt;/p&gt;
&lt;h2&gt;How does image optimisation effect web application performance&lt;/h2&gt;
&lt;p&gt;Large portions of a website are typically built from images. Large images loading over a 4G network in a train can delay
image rendering and create a poor user experience. Layout shifts can occur as the browser attempts to render the page,
and the user's perceived page load time will be affected.&lt;/p&gt;
&lt;p&gt;You can see the benefit of automatic image optimisation with our &lt;a href="/pages/page-weight"&gt;free tool&lt;/a&gt;. It will analyse any
website, calculate its optimisation potential and let you download the optimised images.&lt;/p&gt;
&lt;h2&gt;See how it can help in a real life example below&lt;/h2&gt;
&lt;div class=images&gt;
&lt;div class=image-container style="border: 1px;border-color: lightgrey; border-style: solid;"&gt;&lt;div class="section text-center"&gt;&lt;div class=image-header&gt;&lt;i class="fa-image fas" style="padding-right: 5px;"&gt;&lt;/i&gt; security.png &lt;/div&gt; &lt;div class=image-box&gt;&lt;a href=https://www.peakhour.io/static/images/security.png target=original title="show original"&gt;&lt;img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAAChCAMAAABK+nL1AAAAt1BMVEX///8sOU/yyLr99fL+/f0hLUP9+/rvrUD//v7EjzT0z8MUIzvxwbL88Ozsrpr11cpTfrj55d7onYTvu6ofME7qp5H44Nb66uXttaJZUUPBiy6Eo8y6y+Hb5O/lkXb22tCZstXy9fqnvdvPlTLJ1eX3sj/n7fTbnznT3eyyt79pj8HJlDeRl6F1YT9ESlXrqDqPcT2rgTrhgGD34LjQpFnivHtibHzszJQ7bK7utVfbaEOhprCAh5RYZMzlAAAACXBIWXMAAAsSAAALEgHS3X78AAAWIklEQVR4nO1dCUPiOhAOaYwxtiltt4ccLSAiwgME12Pd/f+/680k5ZRzRReUz4PSFmg/ZiYzk2RCyAknnHDCCSeccMIJJ5xwwgknfBTEGP/6Qo4AYunm98YKIgRx7BxB9D3ZWqpSYslu2JGqIEcaEfYJF3dgYIwwtEECNpAgeEosTjjX9gn+MTjMBNJHrJRoswWnKPrtyGLEU0lGLOCHRDE8cwmzSKZInCQx7GOckTjCDYtospgB/55kubajMiVtRbOMJtImMnRVSNwwi+3EVXbmBRnskipDiUsnr0u+JVlUKN9OwjiwbRkGkoROQiWxoiAJbRUQldAgsTLfDjRZxmkQ/HuSlYUJpcoNHJsmKrQlARmTLnGDhCYBCFqgPDguAxWNJcvYrG9IFty64xAWcyYYF44FxgieCKAhBpPlCDT0cCQWHAyaIN4ojh04aMVWGJDv6JrO3LNWsbEDZXbjf5E3k3KUpv4olWrkp+koJOx7+lrbgIGGwj9uB0EMj1FKHGg7T3QtBfjvqR+GYZKAcQvDVBKeBctd2hPQz3LHyFwPtTMOrG9o5/8OIGzBtwx7toFgM8AdYMLAKTuxtR3A5ToZrh3A4sQ6+RBbAux+4p2Ea0sATSfDpTFjzdfBDT7jYg4cWyqXICfDRcBJN04o33wmGq5PuKKDBSMqDUOllL8xagYDb8svb+bX3Z4gPsTMjuPE1PM8a9MbufbX5spyiJYKk4gxW2KSpWHE94jvhz4G0L4vNgjXlzZcENolgUtizh3GHODNciyL4C+3jBhx6sUUdgoiQ+k7G5gQxnB9TbqArFA6ibK9UAahSiRYp8RLEhrK0MWb5r5BmhH/1Q83kQWxI7FdnUH8eoSB7+3ZSeIoGqggCjxFXQqEUUWtwOaYRk6x35CTJCCZijZKlmbL1a/8egDJUoEMQ2rDgydj240yN0ts6VqBwluOX33MV9FXSjhhW5CFZi5OHOJuc+rRgTvEdgTXFkqYptFCI21xfOKF9ijivgLJ4oynDvjzGzmA1ypH9zJ+NeherXkLk/dT6D/PJ1ma2sROVOqnfn7CJhoEof636ygTJPL1WAcSJAScLZCqSEbcHFqHBBP0K8gSIs8gfrGONBzbMGkNjY7yWNo003ytkRzLWjzIOGD5K/DQ5kD98AFsReC5e5Ezs5M7klIX6RB8pXDMHNA8mc16q1VtNyt3gMpdpdlsV1t1c0isJvOoYAY3TJ7iHTEro1Q6nGzSRxwUgeDtu99/np76/cKZxuXZjx9nZ4VCod9/evrz312lapT7uHshxZJ0FggU/OcRpTTGVnR1C4myIqp3f56ApEv4maIwxg8EPO0//XfXwjfbnN44Omh+uAd8edZklOCCUuI51f+ezi4BZwv4YVCYkoYMPv1uHbt0rYCmBgw+taMY+WILYTYj7A6ZmhB0OSNUV33EWLJy1lAzn5qbXZOjBPCD40UclwYZjn5wZwblwh03n8ZMwUPh6qrXu78fDoelUumidHs+GAxub2+7F8P7+95Vv5AzBnw9VckXVEUD1BphZTJw48yfksXIbyNKl8BT735Y6l4jut3uBQDIAtyc3xicD7rD+6uC4euscHdsDu0uhoNpNyJyJfj6+W0y8p+hqtC7LyFJF/PQZM0AKRsMe32k68fZkbE1jXm2A7aIjvLHesjIneaqD0whT6UFrkqLZOWMDYZ9ZKvQPCq2hIXu+i62QxBXTrd5H8nqXVxfLMdSsrRm9oCts6cjylkwEvs4di0gfKeLZhMlrGiurt+I1FrJMnTdo+GqHphorUmom8iZxOnOpsuAk9/gg/YXDdUWkgUYgCYenNUCJWP5zAk9gyKfRIFIgCx3FHopsf9qig5H8355tUoH10rW+c2VJuuA3AcIkYEP4giIYC20UGikONM5QEaUT9IRV69RNPqrFPFGstZJ1iGS5YRuTENXUTfMklC6ylV2kDgmFROqdEToq53mncw7pp7eJVnnB0gW9+xEWV5o0SQJnNC3A9zUA0VJrNJX5bivI18uCNY4dbeQuVswMF9PspLAxpkTllJ2qChVWWC5oR6rzdMgGgWpPQoyk/HkWeTFjmO99SUYckechf1fTLIIzpKAMBju1HJ4AI8OZ6Z7mpFEERdUkI584qU4xAG8c5dCxExtm1IpZRRFcWxZee6PEanmBXALyfo1pmbwa4Grj5EsMY+/ef3k5sab2mJZzEpp6oUqtIkz1TDMLFiWE8dR5kqXUgqiCeRRV3r+PFtbSJYVjbmKfn0CWYuOyP58XkZcn1A/FG6Yf4owdurNidxyHM+LIt+f27+RrK5HyMNAU+NZnyFZotWuVqvt/Lfd2t87A1khzm4lE7IWPhn9sqmNFyRQ8ydsIqv0gKZRs/VAnI+zWeNB6Jw0XoqzeKnsz+kV3EHTjT2wm88FqYt3ag27F6VHhm//PBg8gO38MMmamb9VxtC8jmi16i1S6/zD4HMnsjD596gt5jNI2BvJ2qMaNmtzaGFE1umUi6SxT7LyzO62rcbiaWvJKj0/lrqlZ0w7c53Z2TNZ2glES0EqL+VyuVMeo1Osw4c2m+3Kfsl6J9aRBTTxn6VbzZbu6XgcfIzNYqRt0mIgTvV2vcnqxfZYxorlwwnU15AFCgj+3M/b85IeDQGGq7RXyRKkUexMUOwUy1xwkLHGS7VebI7lbB9k6f4H3Uv4PiFdTRaYdlQQ59fNoOTid/5cWhSsd5ElSOulUcnRhJ9KsYGzsVqsRVpFzJJVq632PtRQzPim7xq1sZKs0k9uwsv4/Pz2IiKEvuHqfWQBGWCZhHEays1ahXQatbG/UEQnAgz8yyayxEppmelwrtehBSmXq7C107Vua+BLP6087iAesNWN3bdcvc9mjcnSqYJOpdMgnVoVZAzRKLaM/9BaTRaWT8HEHtO8YJJPu5T5o/Et9UHSLneq1U612alXOuXWLoK6MApmBVmlnzGeiX2M4JIiW93bt1z9tWQxjoPNWsUmuukTdBr6ztrlOtiszljIaktsFqvnt8xbdd4af35dj+rj+bF2q9kygldutcq1JiGNRplU9NuJN+NCcow7f/QjtDXbBNIlCHKAK+8C5YuhA3+7hKtFsvALNl+y/tbNn6mPM90hzCn4w4sLznobyeo0Oy1oDdsgYPAHUrEkWmw1CKm20KhVG5VqHR7qvM0aFQK316wxfN4sg7dWb3N4da2BIODulivlXQKCTmeerRWSleFIkbirXVI453mJCr5Hsmo1ptWwxesG4KvXwWbV2wCQtopWw1oNRGGJGmqyqrVaBSio1KB5gBMbVfiDrQbITrtcbdRgE09A/lmjxhlwVyMtsIwo041isVEtFst1kN96uVhsV2Z2tMByNmFHrVV86cxJ31Ky0Lij11DKQ0Pr13KyFmwWXFu9CpddbzSaDG6ENRsN+OobbdhRYXCUj3c0X8rwtlObVX+pFWtAVvllYuDXk1UjICONZhuoamNbCm8K3LRrKFywp90oY/uK14P9V+VavQmMVtqtWrmNCgi2sVWHlzI4i8Eb1FsVEFB4I9hR4bCjhTtY56WyWbKQLMMV1RnGn9fLuVqQLPiKQCaKlfwr6tTzHY3JDvjO2k3Y0XoBniZkIc+tZhUMPKkzMEHadUAVRDFbooZw1UA43FGj3KhWGyiLrTZQ12pUG1VSbzSrqJwooc0atICtDtiscgOpr/FmZzIjZfZxidGHrxAM3WabhWSB794t/cT2ha3iamc1nHg7NdPaFcu1PL5BX71crJCpUzqxZO1lRgYNI9DSmGnb2FsKzCdCk9o0ni2DtrCKG2LWsorcspLxzsmTxUh6JVmPJXxEbXhcxdUKA8/e2vPxk/wP2jBUhnpxGg0iXnS+oVmvQLiD6rMmT6rf2FRZY3mhNRzNrUeMMe0eGscnv+NKw8Qg4Grt1L26cPIKshhyhY/A1WKQs9Jm7QA9Tn1GDZtGDSszgbSYnLnmXba5dYZNrAk0y/V3xU4ryNJcaQl7ExC+Qw2nEMYpbekhv5yhgS+DgR+ThWb4HTf1Fq22xk4e6Vusckpz0ohdur35ALJIThYxSRrSQs3sLPM/9wKxhZhugfX5rJ8PpQ/rNwRF7Mw7pWCo6txg36Ttp7zthrRyd20n63vzWfXmHN6pJB+PgxoYcnBcHVT3PZv9+eiJLiYo3eUFfMF5eEvW7FCt7rENOVqDnUaTGg9N0fm9b8gqDad0de+H4MWviKL3YLM+E5zQRCprg5E3g2nyV1hRGq4LpLvD/tXVsKtdh9LF9dX9denR9EefL6HsICVrkjqen5pJ4hRL+q1xTsQMTV4kqbQjOH9NIH09vLrt9S56V73r+6uri6th6f7ReXge/Hp4eD5/Hjz+On94eFiUrIPpfZlAR1d64JDQfcQ4FCmlQEcql3yzYjqvxnI8V+KQmsizOPH8+bO5HtldmGjhsD+8uu9dDQv3F7gBP4/ZT+/Xw+Nt9PwweHg8j2bSgIPCj8KPPXav7wPcI7GZAxfPTf4ejTLP85LX+amoU+crp0kiTSw/EMeL03aaOAp+2J2oYe++i/NRhr0ekFXoXT8+3D48Zr9uHwxZD4OJPt4MgavCQXlHOMSfJJ4bERpJ6TnSyjLPxQle3H9FuPnVTnVO8NiTktpSZrE19vSXN5tmHPxED0H5brvXIFnDUt9IVg9s1sOv54fH6Bf8gGQtmKzDGgePM3oT37PDgEZ2GiswU5HSZTSDUQo2aJTOlCziVgymiQbSjZxJPZrZIUhvWgNuZqMMr3PJ6qFxB5t1cX/VG94PL3o/0VTdPj/8vH18eP51/jzRQRSsQzNZOACXJEEQKukFaQacKZaFEu5S+amM/TDVmgUWPHNxyFoWWblZEts4YRDE4pzVsdXqatKur69h6xqjne717fnt4PwaH66vB+cTi3VzCzp41j+0Mho8Ip5HpWPLOM48GkciozjCKLWDV3/kpLq8SoQW3JnQtMNcHi1al1fL5g1gAjDPOtzkf3NN4aEJFplzi6YdsKCFIYl9qoiXWjPu6WZpEotP89k7K0KeFR78zaHO3GGmZAMzCVPMMuKwFt8jrop9QnxTnWDJ4MgVbzcvDIy0UREvl7O1ItzR83Z+9A+qKVwNRnzq+GE8cuN0p4koVrbolxlf6+zyfilbS8kyXB3N/DlBsrwIlK92uGJGeODLN4n435erZGupZBmufhycwdon0JzxOEpGi7KVz2a97C2x8m/IGpiZhoWz3wcWFa7DfJ3pTRCYqsUSIrazZGkZTv5otq4uuqUNkjW4GVwdHVc7QcsUMuWBN7us2l/um172h4uquEjWTbef6+CX5ArFCJiSpmoIZ8uqMQiwW6ZYwYKZX5Ssm2FB2/YvyZWRKaplKu9jXe5iQJtY0FPLe93uSskam6t+89i5WjLoS8dBWClkWlllzcvbfWO4ZlVxTrKMCoIv2jrudhAN+Jz3rpVthqnNERAn9SfNFqhid4lk3dzcaxU8+8OPXK4Eseg0lBGmHJSkNELt29K3Z+PiITPCNZWsm9urSZmQQ/fbMd6ZmePC5swPI460X6U07ZweVYNMZZqpHT6Ek2b/Mrfz3TnJysWqcPl0aLUJlkCYXDEXAhe50rsYNmw4llXnvEKVKD8vMSMcl5oSdmu1T/DFYhDQKNb/mAo+V8OZWjRgrbRY/Sj8dwwqyCkVnuWZJ4I4VGL+T5fEwqd+GigntNPQQqZsmXGxWfuW3TUIsGkVL/MqIkjWzSC3VtAKHrwKYk0Qatu+DO3YorFHiQyoHQeWb3vUgptOfH80kqPUTylxgSlGtim7GaglxeNBbFt5hag+6CJI1s2NrjsDjuifel6Y5KDLJDKiYkcpT8kgUYGyiVRJELhBkiWJg2SNQk9yGfkjqm9niypgAlf/GC2pu4mae2eciLOr0vXtzW3vx0Ss2MzLDxUgWbZNAzdxEpW4SURoIBWQZcsoxEjPSvxYStdL7S1KIRJNpuCSusvLCsNRsFy5LnaNYT9DazXuECFRdMiGS4DNIp4EqwVqGDtgs6jlBZYjMcMM37J8xVUGwtetVrjCNGHsJh7L1PLTcQgFNIuaroIRq6e2ESttImOaJOPk+yHaMLGwMXuJjLhpnOAUfC/dvDoFDld1bIoZQ2vligS4tuRvE/4AVZf9u0m7iv6L9KhyiemLPMhcqR5zLPQEgfHqyPpq9TBc5UZpolTqBPYG0cKktAeNAyNLJ6/MfV4LdVFrYH0sQCxGqQSxthPNFBfekVX9BrICkKvE9YNwPVlo/DO41XF7tu42schp8wkk6091XPGVYDFmj7BEkkjXh8hs6ieHbL7eAvwtPwxx8YowjNcQgA2gh+UktxQFlNo7XWFzJoyCj3IiSbIMmwibetSlxyVaCDE7zGHZcdRXSSXOL9n6TXVJm2ldG4GlXpjrKykpyF0m3SBA5sQWPXCHg+lqhquuGfZD+BhZuy78y2ZHDvMIWJIQTYQJlpMQklo0ySYf8DWgfQVpe/ydviTFNRwoCBq3ffTobFwr3cMuIywX/iXowkYrDqSnW9J3vRHFeFRKPa0ugMjKUq6NPbwsTNWXWDwEvY2M2hZ7t/vISBYJy6Uq1p4LRA2uQ2P8LpxQUv9418KYGi/BI3s/K6AI4iUyCaSJvrlFYhVmyCE4XYH0j3XdRDH9zzM7s/YT9oJkBVKadcgY4xCKEi8MI2ghcdkkuunlhwpuuaFnhmlxbKz2liIwJfjxbWWmQtBBEvng2rEsUdlhmCwxSYzMVL4g+qKZmY8452HpxT9Go1E6qT+217sw0bRFfXdEsVq6oYvvS3z3gby+g2ZHF3gYe9U4etmkr4SZR0r0sjJO4FipY+b17RGTL8uiqa+CGCXXIZmf6JIG/54s8JACN98aB60Rj3CwHyeubenMskVdOb0TICv2MXdqf9T1C+LSxMWkRURlIB3pBxYJNqyq+CkIswBcP5lx6keZdGwap67r2XFiRb6bpdSzvMRPbc92pOuiywhkYbk61//A1ZosJ9PzkyCUTlPKuZ3mWZt/CZCakBCpbKUSaSdhAu2OreIkU8p2iAw85SVOQoPAhUOhF+LXi2QFYI3TNP24y9fDchhxAxXa4PASHrz6/5osuCoF4aqUIYT4SaCoTSOaREmSqMCKKXg4WUCVpNQL4bhw0fMxZIH/4/ofZkfyhoXIDKyXxKg6NEV4d52ott+rIg7Ev7FwIyYljzInthwviz3pxRwiWe5kDo0cJ+axdDySuRPJgmuOP46sycVhqhttu+Pkew4gpjYXsS4FM93wRq6PK/fh0nQff+ETt8WUPnOTYOuE2UdczXiE8thv0JUftLSzabUovdOUlCIywQU9PkGyTDf5JOnKHSsYJeEocraoBHooYATiWulmwaeaXGiLRmnqhyH4xOrf6+K2EIJjZ08Yfu5K5IwkeS1F/6+WPfhWYMROCMcOJ/9fmq3dsT7J/EGfiRXUdZidHoIzf9gAf94E71b6ry/l8GFWhiWf0gofPTRLmrPwRNYmgO+A89XZqur0J8xBpJ5lOZjzOJG1CYLYqZ8CPte/O1qcSNoeS0aPnXDCCSeccMIJJ5xwwgnfFP8D+4Qq+JHEZOkAAAAASUVORK5CYII=" style="max-width: 100%; max-height: 300px"&gt;&lt;/a&gt;&lt;/div&gt; &lt;div class=info-box&gt;&lt;div&gt;&lt;div style="width: 40%;display: inline-block"&gt;&lt;h5&gt;Original&lt;/h5&gt;&lt;/div&gt; &lt;div style="width: 50%;display: inline-block"&gt;&lt;strong&gt;2362 x 1266px&lt;/strong&gt;&lt;/div&gt;&lt;/div&gt; &lt;div&gt;&lt;div style=" width: 35%; display: inline-block"&gt;&lt;strong&gt;PNG&lt;/strong&gt;&lt;/div&gt; &lt;div style=" width: 5%;display:inline-block"&gt;&lt;/div&gt; &lt;div style="display: inline-block; width: 25%"&gt;&lt;strong&gt;190.2 kb&lt;/strong&gt;&lt;/div&gt; &lt;div style="width: 30%; display: inline-block; font-size: 17px"&gt;&lt;span class="fa-info-circle fas text-primary" data-content="                    &lt;strong&gt;format:&lt;/strong&gt; PNG&lt;br&gt;                    &lt;strong&gt;is_animated:&lt;/strong&gt; False&lt;br&gt;                    &lt;strong&gt;colour_space:&lt;/strong&gt; RGBA&lt;br&gt;                    &lt;strong&gt;has_transparency:&lt;/strong&gt; False&lt;br&gt;                    &lt;strong&gt;is_photo:&lt;/strong&gt; True&lt;br&gt;                    &lt;strong&gt;width:&lt;/strong&gt; 2362&lt;br&gt;                    &lt;strong&gt;height:&lt;/strong&gt; 1266&lt;br&gt;            " data-title="Image Info" data-toggle=popover&gt;&lt;/span&gt;&amp;nbsp; &lt;a href=https://www.peakhour.io/static/images/security.png target=original title="open original in new window"&gt;&lt;span class="fa-external-link-alt fas text-primary"&gt;&lt;/span&gt;&lt;/a&gt;&amp;nbsp; &lt;/div&gt;&lt;/div&gt;&lt;/div&gt; &lt;div class=info-box&gt;&lt;div&gt;&lt;div style="width: 40%;display: inline-block"&gt;&lt;h5&gt;Optimised&lt;/h5&gt;&lt;/div&gt; &lt;div style="width: 50%;display: inline-block"&gt;&lt;strong&gt;605 x 324px&lt;/strong&gt;&lt;/div&gt;&lt;/div&gt; &lt;div&gt;&lt;div style="width: 35%; display: inline-block; text-transform: uppercase"&gt; png &lt;/div&gt; &lt;div style="width: 5%; display: inline-block"&gt;&lt;br&gt;&lt;/div&gt; &lt;div style="width: 25%; display: inline-block"&gt; 10.8 kb &lt;/div&gt; &lt;div style="width: 30%; display: inline-block;font-size: 17px"&gt;&lt;span class="fa-info-circle fas text-primary" data-content="                    &lt;strong&gt;format:&lt;/strong&gt; PNG&lt;br&gt;                    &lt;strong&gt;optimize:&lt;/strong&gt; True&lt;br&gt;                    &lt;strong&gt;quality:&lt;/strong&gt; 75&lt;br&gt;                    &lt;strong&gt;colour_space:&lt;/strong&gt; RGBA&lt;br&gt;                    &lt;strong&gt;lossless:&lt;/strong&gt; False&lt;br&gt;                    &lt;strong&gt;subsampling:&lt;/strong&gt; None&lt;br&gt;                    &lt;strong&gt;delay_format:&lt;/strong&gt; None&lt;br&gt;                    &lt;strong&gt;strip:&lt;/strong&gt; True&lt;br&gt;                    &lt;strong&gt;compression:&lt;/strong&gt; 6&lt;br&gt;            " data-title="Optimised Info" data-toggle=popover&gt;&lt;/span&gt;&amp;nbsp; &lt;a download=security.png.optimised.png href=/page-weight/result/41377868-5104-4eaf-9776-a9a682a5e8f5/images/6641ec77-2367-4c17-ab27-2447cdc8aceb/img.png title=download&gt;&lt;span class="fa-download fas text-primary"&gt;&lt;/span&gt;&lt;/a&gt;&amp;nbsp; &lt;a href=/page-weight/result/41377868-5104-4eaf-9776-a9a682a5e8f5/images/6641ec77-2367-4c17-ab27-2447cdc8aceb/img.png target=6641ec77-2367-4c17-ab27-2447cdc8aceb title="Open in new window"&gt;&lt;span class="fa-external-link-alt fas text-primary"&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt; &lt;div&gt;&lt;div style="width: 35%; display: inline-block; text-transform: uppercase"&gt; jpeg &lt;/div&gt; &lt;div style="width: 5%; display: inline-block"&gt;&lt;br&gt;&lt;/div&gt; &lt;div style="width: 25%; display: inline-block"&gt; 15.4 kb &lt;/div&gt; &lt;div style="width: 30%; display: inline-block;font-size: 17px"&gt;&lt;span class="fa-info-circle fas text-primary" data-content="                    &lt;strong&gt;format:&lt;/strong&gt; JPEG&lt;br&gt;                    &lt;strong&gt;optimize:&lt;/strong&gt; True&lt;br&gt;                    &lt;strong&gt;quality:&lt;/strong&gt; 75&lt;br&gt;                    &lt;strong&gt;colour_space:&lt;/strong&gt; RGB&lt;br&gt;                    &lt;strong&gt;lossless:&lt;/strong&gt; False&lt;br&gt;                    &lt;strong&gt;subsampling:&lt;/strong&gt; 4:2:0&lt;br&gt;                    &lt;strong&gt;delay_format:&lt;/strong&gt; None&lt;br&gt;                    &lt;strong&gt;strip:&lt;/strong&gt; True&lt;br&gt;                    &lt;strong&gt;progressive:&lt;/strong&gt; False&lt;br&gt;                    &lt;strong&gt;progressive_min_bytes:&lt;/strong&gt; 10240&lt;br&gt;                    &lt;strong&gt;quant_table:&lt;/strong&gt; 3&lt;br&gt;            " data-title="Optimised Info" data-toggle=popover&gt;&lt;/span&gt;&amp;nbsp; &lt;a download=security.png.optimised.jpeg href=/page-weight/result/41377868-5104-4eaf-9776-a9a682a5e8f5/images/796c932f-a4a1-4a4b-890d-d88fba459c29/img.jpeg title=download&gt;&lt;span class="fa-download fas text-primary"&gt;&lt;/span&gt;&lt;/a&gt;&amp;nbsp; &lt;a href=/page-weight/result/41377868-5104-4eaf-9776-a9a682a5e8f5/images/796c932f-a4a1-4a4b-890d-d88fba459c29/img.jpeg target=796c932f-a4a1-4a4b-890d-d88fba459c29 title="Open in new window"&gt;&lt;span class="fa-external-link-alt fas text-primary"&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt; &lt;div&gt;&lt;div style="width: 35%; display: inline-block; text-transform: uppercase"&gt; [webp](/products/image-optimisation-and-transformation/) &lt;/div&gt; &lt;div style="width: 5%; display: inline-block"&gt;&lt;br&gt;&lt;/div&gt; &lt;div style="width: 25%; display: inline-block"&gt; 10.7 kb &lt;/div&gt; &lt;div style="width: 30%; display: inline-block;font-size: 17px"&gt;&lt;span class="fa-info-circle fas text-primary" data-content="                    &lt;strong&gt;save_all:&lt;/strong&gt; False&lt;br&gt;                    &lt;strong&gt;duration:&lt;/strong&gt; None&lt;br&gt;                    &lt;strong&gt;loop:&lt;/strong&gt; None&lt;br&gt;                    &lt;strong&gt;format:&lt;/strong&gt; WEBP&lt;br&gt;                    &lt;strong&gt;optimize:&lt;/strong&gt; False&lt;br&gt;                    &lt;strong&gt;quality:&lt;/strong&gt; 75&lt;br&gt;                    &lt;strong&gt;colour_space:&lt;/strong&gt; None&lt;br&gt;                    &lt;strong&gt;lossless:&lt;/strong&gt; False&lt;br&gt;                    &lt;strong&gt;subsampling:&lt;/strong&gt; None&lt;br&gt;                    &lt;strong&gt;delay_format:&lt;/strong&gt; None&lt;br&gt;                    &lt;strong&gt;strip:&lt;/strong&gt; True&lt;br&gt;                    &lt;strong&gt;method:&lt;/strong&gt; 3&lt;br&gt;                    &lt;strong&gt;kmin:&lt;/strong&gt; None&lt;br&gt;                    &lt;strong&gt;kmax:&lt;/strong&gt; None&lt;br&gt;                    &lt;strong&gt;allow_mixed:&lt;/strong&gt; False&lt;br&gt;                    &lt;strong&gt;minimize_size:&lt;/strong&gt; True&lt;br&gt;            " data-title="Optimised Info" data-toggle=popover&gt;&lt;/span&gt;&amp;nbsp; &lt;a download=security.png.optimised.webp href=/page-weight/result/41377868-5104-4eaf-9776-a9a682a5e8f5/images/72346c2d-1302-40f0-bb38-027890c5c920/img.webp title=download&gt;&lt;span class="fa-download fas text-primary"&gt;&lt;/span&gt;&lt;/a&gt;&amp;nbsp; &lt;a href=/page-weight/result/41377868-5104-4eaf-9776-a9a682a5e8f5/images/72346c2d-1302-40f0-bb38-027890c5c920/img.webp target=72346c2d-1302-40f0-bb38-027890c5c920 title="Open in new window"&gt;&lt;span class="fa-external-link-alt fas text-primary"&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt; &lt;div&gt;&lt;div style="width: 35%;display: inline-block; text-transform: uppercase"&gt;&lt;strong&gt;avif &lt;span class="fa-trophy fas text-primary"&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/div&gt; &lt;div style="width: 5%; display: inline-block"&gt;&lt;br&gt;&lt;/div&gt; &lt;div style="width: 25%; display: inline-block"&gt;&lt;strong&gt;8.2 kb&lt;/strong&gt;&lt;/div&gt; &lt;div style="width: 30%; display: inline-block;font-size: 17px"&gt;&lt;span class="fa-info-circle fas text-primary" data-content="                    &lt;strong&gt;format:&lt;/strong&gt; AVIF&lt;br&gt;                    &lt;strong&gt;optimize:&lt;/strong&gt; True&lt;br&gt;                    &lt;strong&gt;quality:&lt;/strong&gt; 50&lt;br&gt;                    &lt;strong&gt;colour_space:&lt;/strong&gt; RGBA&lt;br&gt;                    &lt;strong&gt;lossless:&lt;/strong&gt; False&lt;br&gt;                    &lt;strong&gt;subsampling:&lt;/strong&gt; None&lt;br&gt;                    &lt;strong&gt;delay_format:&lt;/strong&gt; None&lt;br&gt;                    &lt;strong&gt;strip:&lt;/strong&gt; True&lt;br&gt;                    &lt;strong&gt;compression:&lt;/strong&gt; 6&lt;br&gt;            " data-title="Optimised Info" data-toggle=popover&gt;&lt;/span&gt;&amp;nbsp; &lt;a download=security.png.optimised.avif href=/page-weight/result/41377868-5104-4eaf-9776-a9a682a5e8f5/images/11a20ace-cd35-4f59-91f7-2794c8650815/img.avif title=download&gt;&lt;span class="fa-download fas text-primary"&gt;&lt;/span&gt;&lt;/a&gt;&amp;nbsp; &lt;a href=/page-weight/result/41377868-5104-4eaf-9776-a9a682a5e8f5/images/11a20ace-cd35-4f59-91f7-2794c8650815/img.avif target=11a20ace-cd35-4f59-91f7-2794c8650815 title="Open in new window"&gt;&lt;span class="fa-external-link-alt fas text-primary"&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2&gt;Benefits of Peakhour Automatic Image Optimisation&lt;/h2&gt;
&lt;p&gt;Peakhour image optimisation is integrated into your website so you can reduce traffic, speed up page loads and remove
manual image preparation from the design workflow.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Transforming images on the Peakhour edge enables agility and offloads origin work.&lt;/li&gt;
&lt;li&gt;User experience is improved through faster-loading pages, without a separate workflow for image optimisation.&lt;/li&gt;
&lt;li&gt;Take advantage of new image formats, as supported by end users' browsers, to improve the page load experience.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Final Thoughts&lt;/h2&gt;
&lt;p&gt;Peakhour image optimisation runs on Peakhour Edge. Images are optimised as they pass through the Peakhour network, and
optimised versions are cached for reuse. Peakhour image optimisation also works with &lt;a href="/blog/cdn-origin-shield"&gt;Origin Shield&lt;/a&gt;,
with the original and transformed images cached appropriately. This reduces origin hits and bandwidth while speeding up
image delivery.&lt;/p&gt;</content><category term="Features"></category><category term="Web Performance"></category><category term="Caching"></category><category term="Core Web Vitals"></category><category term="CDN"></category><category term="Drupal"></category><category term="Rate Limiting"></category></entry><entry><title>Prestashop 1.6/1.7 full page caching plugin released!</title><link href="https://www.peakhour.io/blog/prestashop-plugin/" rel="alternate"></link><published>2022-08-04T13:00:00+10:00</published><updated>2022-08-04T13:00:00+10:00</updated><author><name>Dan</name></author><id>tag:www.peakhour.io,2022-08-04:/blog/prestashop-plugin/</id><summary type="html">&lt;p&gt;Prestashop is the latest shopping cart we've made a plugin for, read on for more details.&lt;/p&gt;</summary><content type="html">&lt;p&gt;Prestashop is a popular open source eCommerce platform written in PHP. We're releasing a Prestashop module that enables
full page caching through Peakhour. Pages can stay cached at the Peakhour edge for longer, and the plugin refreshes them
when the underlying content changes in Prestashop.&lt;/p&gt;
&lt;p&gt;&lt;a href="/blog/caching-dynamic-content-with-a-cdn/"&gt;Full Page Caching&lt;/a&gt; reduces load times by removing the time it takes for a
CMS to generate a dynamic page. That is typically around half a second for a quick page, and 3-5 seconds for a slow one.
Here is a cache miss and hit from our client fatburnersonly.com.au:&lt;/p&gt;
&lt;div class="text-center" style="padding: 20px 0px"&gt;
&lt;img src="/static/images/blog/prestashop-cache-miss.jpg" width="100%" alt="Prestashop cache miss"/&gt;
&lt;em&gt;A typical cache miss on a category page. The origin has to generate the page, taking &lt;strong&gt;2.49 seconds&lt;/strong&gt;&lt;/em&gt;
&lt;/div&gt;

&lt;div class="text-center" style="padding: 20px 0px"&gt;
&lt;img src="/static/images/blog/prestashop-cache-hit.jpg" width="100%" alt="Prestashop cache miss"/&gt;
&lt;em&gt;A cache hit: &lt;strong&gt;only 35.7 milliseconds&lt;/strong&gt; to deliver to the client from our edge&lt;/em&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Nearly 2.5 seconds removed from Time to First Byte and Largest Contentful Paint.&lt;/strong&gt; That's without changing
the site itself.&lt;/p&gt;
&lt;h3&gt;Tag Based Flushing&lt;/h3&gt;
&lt;p&gt;Like all our recent plugins, the Prestashop plugin adds a header with tag metadata for each cacheable page. This header is
called X-Prestashop-Tag and contains the IDs of the relevant entities on the page, eg products, categories, brands, pages,
etc. This metadata is stored alongside the cached page. When an entity changes in the Prestashop admin, eg a product price
is updated, the plugin issues a flush-by-tag request to Peakhour. Peakhour finds the pages with the associated tag and
invalidates them in the cache. The next request for the page passes through to origin and is then re-cached.&lt;/p&gt;
&lt;div class="text-center" style="padding: 20px 0px"&gt;
&lt;img src="/static/images/blog/prestashop-tags.jpg" width="100%" alt="Prestashop full page caching headers"/&gt;
&lt;em&gt;Headers returned by the [caching plugin](/blog/opencart/opencart-3-caching-plugin/).&lt;/em&gt;
&lt;/div&gt;

&lt;h3&gt;Custom TTL&lt;/h3&gt;
&lt;p&gt;TTL (Time to live) is the time a resource stays in cache before the cache checks for a new version. You can control this
within the plugin. The plugin then sets the peakhour-cdn-cache-control header, part of the new
&lt;a href="/blog/cdn-cache-control-header/"&gt;cdn-cache-control specification&lt;/a&gt;, so only Peakhour responds to the cache directive.&lt;/p&gt;
&lt;h3&gt;Ajax Mini Cart&lt;/h3&gt;
&lt;p&gt;Mini carts are dynamic sections of eCommerce websites, and they often stop pages from being cacheable. The Peakhour plugin
loads them via Ajax so as many pages as possible remain cacheable.&lt;/p&gt;
&lt;div class="text-center" style="padding: 20px 0px"&gt;
&lt;img src="/static/images/blog/prestashop-mini-cart.jpg" width="100%" alt="Prestashop mini cart"/&gt;
&lt;em&gt;The mini cart is in the top right; it is usually returned as part of the generated page.&lt;/em&gt;
&lt;/div&gt;

&lt;h3&gt;Cache varying&lt;/h3&gt;
&lt;p&gt;The same page can show different information depending on factors such as whether a user is logged in, or whether a
multicurrency store changes currency. The Peakhour Prestashop plugin handles this by changing a cookie value when those
factors change, creating separate cache regions for the different possibilities.&lt;/p&gt;
&lt;h2&gt;The Results&lt;/h2&gt;
&lt;p&gt;The Peakhour Prestashop plugin can improve store performance measurably. Our client fatburnersonly.com.au improved their
'good' web vitals scores by 20% in the two months they've been using Peakhour.&lt;/p&gt;
&lt;div class="text-center" style="padding: 20px 0px"&gt;
&lt;img src="/static/images/blog/prestashop-lcp-improvements.jpg" width="100%" alt="Prestashop web vitals improvement"/&gt;
&lt;em&gt;Full page caching was enabled halfway through May. Note that a significant number of pages, eg checkout and admin, cannot be cached and are included in these stats&lt;/em&gt;
&lt;/div&gt;

&lt;h2&gt;Grabbing the plugin&lt;/h2&gt;
&lt;p&gt;If you have a slow Prestashop store, see our &lt;a href="/docs/how-to-guides/integrations/prestashop/"&gt;plugin page&lt;/a&gt; or
&lt;a href="/contact-us/"&gt;contact us&lt;/a&gt; for more information.&lt;/p&gt;</content><category term="CMS"></category><category term="Caching"></category><category term="Drupal"></category><category term="WordPress"></category><category term="Web Performance"></category><category term="CDN"></category><category term="Core Web Vitals"></category></entry><entry><title>CDN Cache Keys</title><link href="https://www.peakhour.io/blog/cdn-cache-keys/" rel="alternate"></link><published>2022-05-16T13:00:00+10:00</published><updated>2022-05-16T13:00:00+10:00</updated><author><name>AC</name></author><id>tag:www.peakhour.io,2022-05-16:/blog/cdn-cache-keys/</id><summary type="html">&lt;p&gt;Cache keys allows the segmenting of the Peakhour.IO cache by elements of both the request and response, enabling effective and flexible caching of content.&lt;/p&gt;</summary><content type="html">&lt;p&gt;Content Delivery Networks (CDNs) are common on business websites. CDNs speed up websites by storing website content
and assets in caches on servers spread around the world. These caches are typically key/value stores. For example,
let's say we are requesting an image found at:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;https://www.example.com/someimage.jpg
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Depending on how the &lt;a href="/learning/cdn/"&gt;CDN&lt;/a&gt; works internally, it may use &lt;strong&gt;/someimage.jpg&lt;/strong&gt; (the key) to retrieve the image (the value)
from its cache. Most CDNs are fairly rigid in what they use as keys, complicated to configure (eg requiring programming
skills), or charge more for flexibility.&lt;/p&gt;
&lt;p&gt;The Peakhour.io CDN cache keeps configuration flexible while still supporting fine-grained control of caching
behaviour for your application.&lt;/p&gt;
&lt;p&gt;The Peakhour.IO cache key consists of a primary key, sub key, and secondary key. Both the primary and secondary key must
match to constitute a cache hit.&lt;/p&gt;
&lt;h2&gt;Primary key&lt;/h2&gt;
&lt;p&gt;The primary key is the key from the client request that uniquely identifies a resource. It consists of the
scheme, host, path and query string from the request. Within our cache, the primary key may be augmented from other
elements of the request, such as the presence of a particular header, or a header value such as a cookie value. At
Peakhour.IO, we call these augmented keys &lt;a href="/docs/reference/rules/vconf-set/#cache-subkey-vars"&gt;cache subkey vars&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src="/static/images/blog/url-cache-key-composition.png" class="img-responsive"&gt;&lt;/p&gt;
&lt;p&gt;The following options can further manipulate the primary key by specifying how the query string is handled. These
options include &lt;a href="/docs/reference/rules/vconf-set/#cdn-query-mode"&gt;ignore query string&lt;/a&gt; (useful for defeating cache-busting techniques)
or &lt;a href="/docs/reference/rules/vconf-set/#cdn-remove-query-args"&gt;stripping certain tags&lt;/a&gt; (commonly UTM tags).&lt;/p&gt;
&lt;h2&gt;Secondary key&lt;/h2&gt;
&lt;p&gt;The secondary key describes parts of the request message that influenced the content of the response from the origin.
This information is stored in the secondary key and the following headers are used:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Vary&lt;/li&gt;
&lt;li&gt;Content-Encoding&lt;/li&gt;
&lt;li&gt;User-Agent: (browser/mobile)&lt;/li&gt;
&lt;li&gt;Accept-Language&lt;/li&gt;
&lt;li&gt;Variant-06&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Servers are commonly misconfigured and can send back headers that don't match the behaviour of the content.
For example, it is very common for a server to send back a Vary header with &lt;em&gt;Vary: user-agent&lt;/em&gt;. When you check the behaviour
by sending different user agents, though, the content doesn't actually change. This can cause unnecessary cache fragmentation and lower hit rates. Peakhour allows
you to override/ignore origin behaviour to correct this.&lt;/p&gt;
&lt;p&gt;If you prefer a visual view, the diagram below shows all the elements of a request/response that could make up a cache key.&lt;/p&gt;
&lt;p&gt;&lt;img src="/static/images/blog/cache-keys.png" class="img-responsive"&gt;&lt;/p&gt;
&lt;p&gt;For more flexibility, Peakhour.io can use specific Cookie values in the secondary key. This is useful for Content Management
Systems like Magento, which set a special cookie, &lt;em&gt;X-Magento-Vary&lt;/em&gt;, to enable special caching behaviour that wouldn't normally
be achievable; for example, whether the user is logged in, is part of a special group, or has chosen a different currency.&lt;/p&gt;
&lt;h2&gt;How can I see my keys?&lt;/h2&gt;
&lt;p&gt;Cache keys are generated on the fly based on the client's request and the origin's response. To see a cache key,
enable Debug headers in the Peakhour.IO dashboard. As an example, for the given request/response pair:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nf"&gt;GET&lt;/span&gt; &lt;span class="nn"&gt;/&lt;/span&gt; &lt;span class="kr"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt;
&lt;span class="na"&gt;Accept-Encoding&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="l"&gt;gzip, deflate, br&lt;/span&gt;

HTTP/1.1 200
Vary: accept-encoding
content-encoding: br
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Peakhour.IO would generate the following cache-status header:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;cache-status&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;peakhour&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;io&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;fwd&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nt"&gt;uri-miss&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;https://example.com/what-is-new.html&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;secondary-key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;encoding::br&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;stored&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ttl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nt"&gt;31536000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here, the key is the scheme://host/path and the secondary-key is the encoding served by the origin.&lt;/p&gt;
&lt;h2&gt;What's in it for me?&lt;/h2&gt;
&lt;p&gt;By understanding cache keys and how they are constructed, a web application can tailor its responses to better utilise
a cache. The configuration options give you direct control for fine-tuning cache-key handling, improving user experience
and cache hit rates.&lt;/p&gt;</content><category term="Caching"></category><category term="CDN"></category><category term="Caching"></category><category term="Drupal"></category><category term="Web Performance"></category></entry><entry><title>Rate limiting</title><link href="https://www.peakhour.io/blog/rate-limiting-how-it-works/" rel="alternate"></link><published>2022-05-16T13:00:00+10:00</published><updated>2022-05-16T13:00:00+10:00</updated><author><name>AC</name></author><id>tag:www.peakhour.io,2022-05-16:/blog/rate-limiting-how-it-works/</id><summary type="html">&lt;p&gt;How can rate limiting protect your web application and the key items to consider when enabling.&lt;/p&gt;</summary><content type="html">&lt;p&gt;Rate limits are a useful control for protecting a web application from abuse. When setting them for a web application,
the key elements to consider are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What endpoints on the web application require protecting?&lt;/li&gt;
&lt;li&gt;Do different endpoints require separate handling?&lt;/li&gt;
&lt;li&gt;What is the normal request rate for the entire application over a time period?&lt;/li&gt;
&lt;li&gt;How many concurrent connections are typically used by your clients?&lt;/li&gt;
&lt;li&gt;What errors does your API endpoint return in response to requests?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Before setting those policies, it helps to understand how rate limits protect an application from abuse
or misuse, the types of attacks they can reduce, and how the &lt;a href="/learning/api-protection/what-is-api-rate-limiting/"&gt;rate limiting&lt;/a&gt; algorithm makes
decisions.&lt;/p&gt;
&lt;h1&gt;What kinds of attacks are stopped by rate limiting?&lt;/h1&gt;
&lt;p&gt;When protecting an application with rate limiting, common attack scenarios include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Brute force and enumeration attacks&lt;/li&gt;
&lt;li&gt;Denial of Service (DoS) and Distributed Denial of Service (DDoS)&lt;/li&gt;
&lt;li&gt;Site scraping&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;What else can rate limiting protect?&lt;/h2&gt;
&lt;p&gt;Public APIs and authenticated APIs can be subject to both abuse and misuse. Sensible rate limit policies can be applied
on these endpoints to help prevent attacks and maintain service availability. Rate limiting can help protect these endpoints.&lt;/p&gt;
&lt;h1&gt;How does rate limiting work with user logins?&lt;/h1&gt;
&lt;p&gt;A well designed web application should allow only a limited number of failed login attempts
before locking an account and requiring a password reset. This is designed to protect against
&lt;a href="/learning/security/brute-force/"&gt;brute force&lt;/a&gt; attacks against an account. Bots commonly attempt to brute force logins to
WordPress and other popular web applications. Determined attackers can also attempt to brute
force API login endpoints.&lt;/p&gt;
&lt;p&gt;Rate limiting on a login page can be applied to the IP address of a user attempting to log in.
By rate limiting by IP address, you can limit both password brute force attacks and simpler
username enumeration attempts.&lt;/p&gt;
&lt;p&gt;Using Peakhour.IO rate limiting, responses to requests can be monitored and IPs blocked
for administrator-defined periods. This saves origin server resources and stops repeated
attempts before they reach the application.&lt;/p&gt;
&lt;h1&gt;How could API rate limiting work?&lt;/h1&gt;
&lt;p&gt;APIs are ubiquitous across the modern web. Single Page Applications (SPAs) can be built almost
entirely on REST or GraphQL APIs, while legacy applications often use form submits. Even when
browsing this blog, you have consumed a range of APIs.&lt;/p&gt;
&lt;p&gt;Because APIs are often publicly available, rate limits are commonly used to reduce abuse. &lt;a href="/blog/introducing-advanced-rate-limiting/"&gt;Rate limiting for APIs&lt;/a&gt;
can protect against malicious attacks. An attacker could script a bot to perform many API calls and make the service
unavailable for other users, causing unplanned downtime - a layer 7 DoS or DDoS attack.&lt;/p&gt;
&lt;h3&gt;APIs&lt;/h3&gt;
&lt;p&gt;Public and private APIs can be subject to abuse or misuse. Public APIs are discoverable by anyone and can
be scripted for data mining or attacks. Rate limiting these endpoints
based on fair use policies is commonplace. Keeping track of this within an endpoint can be expensive, so handling
it through Peakhour can offload that work from developers.&lt;/p&gt;
&lt;h3&gt;Overzealous 'good bots'&lt;/h3&gt;
&lt;p&gt;Peakhour has seen websites where up to 65% of requests come from automated bots. These bots are typically indiscriminate
when mining information, and they do not carry the operational cost when your site slows down or fails. Rate limiting good
bots separately from your main users helps ensure these crawlers do not stop your site from generating revenue.&lt;/p&gt;
&lt;h1&gt;How is rate limiting implemented?&lt;/h1&gt;
&lt;p&gt;Rate limiting is typically implemented using several common methods:&lt;/p&gt;
&lt;h2&gt;Fixed window&lt;/h2&gt;
&lt;p&gt;Window-based rate limiting is the simplest to understand. Fixed window limits are easy to
define, such as 5,000 requests per 60 minutes. Fixed window rate limiting is subject to
spikes at the edges of the window. For example, 5,000 requests in the first 5 minutes
of the window may overwhelm a service.&lt;/p&gt;
&lt;h2&gt;Sliding window&lt;/h2&gt;
&lt;p&gt;A sliding window keeps much of the simplicity of a fixed window, but
uses a rolling window. This allows bursts to be smoothed.&lt;/p&gt;
&lt;h2&gt;Token bucket&lt;/h2&gt;
&lt;p&gt;A token bucket is an algorithm where tokens are placed into a fixed-capacity bucket. Tokens could be defined as bytes transferred
or hits to an API. When a request is considered for rate limiting, tokens are removed from the bucket. If the bucket has a
sufficient quantity of tokens, the request can proceed. If there are insufficient tokens, the request is considered to be
non-conforming. Non-conforming requests are dropped.&lt;/p&gt;
&lt;h2&gt;Leaky bucket&lt;/h2&gt;
&lt;p&gt;Leaky buckets are a mirror image of token buckets. Instead of removing tokens from a bucket, tokens are added to a bucket.
Tokens are removed from the bucket (leaks) at a fixed rate. When a request is considered for rate limiting, it is compared
to the number of tokens in the bucket. If the bucket is full, the request is considered non-conforming and is dropped.&lt;/p&gt;
&lt;p&gt;If rate limiting is something you need to do to protect and secure your website,
reach out to see how we can help.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Learn how Peakhour's Application Security Platform can improve your application's performance and security. &lt;a href="/contact-sales/"&gt;Contact our team&lt;/a&gt; to get started.&lt;/em&gt;&lt;/p&gt;</content><category term="DDoS"></category><category term="Rate Limiting"></category><category term="API Security"></category><category term="DDoS"></category><category term="Application Security"></category><category term="Web Performance"></category><category term="Bot Management"></category></entry><entry><title>Opencart 3 Full Page Caching Plugin Released</title><link href="https://www.peakhour.io/blog/opencart-3-plugin/" rel="alternate"></link><published>2022-03-25T13:00:00+11:00</published><updated>2022-03-25T13:00:00+11:00</updated><author><name>Dan</name></author><id>tag:www.peakhour.io,2022-03-25:/blog/opencart-3-plugin/</id><summary type="html">&lt;p&gt;Elevate your Opencart 3 store's performance with Peakhour's full page caching plugin. Learn how our features outperform LiteSpeed and Varnish Cache.&lt;/p&gt;</summary><content type="html">&lt;p&gt;Peakhour's Opencart plugin includes features that are usually reserved for enterprise plans with other providers. It follows our 'Enterprise for Everyone' approach in a practical way:&lt;/p&gt;
&lt;h3&gt;Tag-Based Flushing&lt;/h3&gt;
&lt;p&gt;Peakhour's plugin records metadata for each Opencart page in the cache. When you update a product or category, only the relevant pages are refreshed. That keeps cache flushing targeted instead of clearing more content than necessary.&lt;/p&gt;
&lt;div class="text-center" style="padding: 20px 0px"&gt;
&lt;img src="/static/images/blog/opencart-3-full-page-caching-headers.jpg" width="100%" alt="Opencart 3 [full page](/blog/drupal/drupal-purge-module/) caching headers"/&gt;
&lt;em&gt;Headers returned by caching plugin.&lt;/em&gt;
&lt;/div&gt;

&lt;h3&gt;Custom TTL&lt;/h3&gt;
&lt;p&gt;Control how long a resource stays in the cache before it checks for a new version. This gives you a direct way to manage cache freshness.&lt;/p&gt;
&lt;h3&gt;Ajax Mini Cart and Wishlist&lt;/h3&gt;
&lt;p&gt;Dynamic sections like mini carts and wishlists usually prevent caching. The plugin loads these sections via Ajax, which makes more pages cacheable.&lt;/p&gt;
&lt;h3&gt;Cache Vary&lt;/h3&gt;
&lt;p&gt;The plugin adapts to different user states, currencies, and languages. It changes a cookie value to create separate cache regions for these variables.&lt;/p&gt;
&lt;h2&gt;Peakhour vs. LiteSpeed and Varnish Cache&lt;/h2&gt;
&lt;p&gt;LiteSpeed and Varnish Cache are good options, but Peakhour offers a more flexible and efficient caching solution for Opencart. The plugin makes Opencart as cache-friendly as Magento 2 or Drupal 8, if not more so.&lt;/p&gt;
&lt;h2&gt;The Results Speak for Themselves&lt;/h2&gt;
&lt;p&gt;Our client saw a clear improvement in their web vitals scores and website scalability. Full &lt;a href="/blog/prestashop-plugin/"&gt;page caching&lt;/a&gt; was enabled in October, with the gains shown below.&lt;/p&gt;
&lt;div class="text-center" style="padding: 20px 0px"&gt;
&lt;img src="/static/images/blog/opencart-3-web-vitals-lcp-improvement.jpg" width="100%" alt="Opencart 3 web vitals improvement"/&gt;
&lt;em&gt;Full page caching was enabled in October. Note a significant amount of pages, eg checkout, admin etc cannot be cached which affects these stats&lt;/em&gt;
&lt;/div&gt;

&lt;p&gt;&lt;em&gt;For more information, visit our &lt;a href="/docs/how-to-guides/integrations/opencart-3/"&gt;plugin page&lt;/a&gt; or &lt;a href="/contact-us/"&gt;contact us&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;</content><category term="CMS"></category><category term="Caching"></category><category term="CDN"></category><category term="Drupal"></category><category term="Web Performance"></category><category term="WordPress"></category><category term="Magento"></category></entry><entry><title>Cdn-Cache-Control</title><link href="https://www.peakhour.io/blog/cdn-cache-control-header/" rel="alternate"></link><published>2022-02-28T13:00:00+11:00</published><updated>2022-02-28T13:00:00+11:00</updated><author><name>AC</name></author><id>tag:www.peakhour.io,2022-02-28:/blog/cdn-cache-control-header/</id><summary type="html">&lt;p&gt;CDN-Cache-Control is a proposed new header to augment the venerable Cache-Control. Its aim is to make controlling caching easier as CDNs become ubiquitous.&lt;/p&gt;</summary><content type="html">&lt;p&gt;Caching headers are easy to get wrong. Public resources may be cached in one layer, while the server
configuration prevents an otherwise cacheable resource from being stored where you expect.&lt;/p&gt;
&lt;p&gt;Controlling caching without a service like Peakhour usually means working directly with Cache-Control headers.
This header has a wide range of fields and directives. Each one tells downstream clients (e.g., proxies, shared caches, and end browsers)
how to handle caching for a particular resource.&lt;/p&gt;
&lt;p&gt;Getting this right can be complicated, and it can become brittle when web server configuration also affects the response.&lt;/p&gt;
&lt;h2&gt;Enter CDN-Cache-Control&lt;/h2&gt;
&lt;p&gt;CDN-Cache-Control is a recently proposed header specified in
&lt;a href="https://datatracker.ietf.org/doc/html/draft-cdn-control-header-01"&gt;https://datatracker.ietf.org/doc/html/draft-cdn-control-header-01&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The draft RFC states:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;This&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;specification&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;defines&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;convention&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;HTTP&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;response&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;header&lt;/span&gt;
&lt;span class="nv"&gt;fields&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;that&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;allow&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;directives&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;controlling&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;caching&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;be&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;targeted&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;at&lt;/span&gt;
&lt;span class="nv"&gt;specific&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;caches&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;or&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;classes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;caches&lt;/span&gt;.&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nv"&gt;It&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;also&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;defines&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;one&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;such&lt;/span&gt;
&lt;span class="nv"&gt;header&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;field&lt;/span&gt;,&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;targeted&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;at&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;[&lt;span class="nv"&gt;Content&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Delivery&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;Network&lt;/span&gt;]&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;learning&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;cdn&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;CDN&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;caches&lt;/span&gt;.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;What does this mean in practice? Imagine a Magento application where pages should be cacheable by a shared cache
but not by a browser. A Cache-Control header could look like:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Cache-Control: max-age=0, s-max-age=600
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This tells browser caches not to reuse the response, while shared caches may cache it for 600 seconds.&lt;/p&gt;
&lt;p&gt;What if the application does not want every shared cache to store the resource, because the application already sends purges
to the cache when content changes?&lt;/p&gt;
&lt;p&gt;Cache-Control does not give you that separation. The header above enables any shared cache to store the resource
for the specified time. With CDN-Cache-Control, the application could instead send:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Cache-Control: max-age=0, s-max-age=60
CDN-Cache-Control: max-age=3600
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This tells the browser not to cache the page, allows a shared cache to keep the page for 60s,
and allows the CDN to keep it for one hour.&lt;/p&gt;
&lt;h2&gt;Targeted CDN-Cache-Control&lt;/h2&gt;
&lt;p&gt;What if you need to target a specific CDN only? Use the provider's targeted CDN-Cache-Control header.&lt;/p&gt;
&lt;p&gt;For example, Peakhour-CDN-Cache-Control instructs Peakhour only to cache the resource.
Other CDNs in the request path will not honour this header.&lt;/p&gt;
&lt;h2&gt;Header format&lt;/h2&gt;
&lt;h3&gt;Examples&lt;/h3&gt;
&lt;p&gt;The following header fields instruct a CDN cache
to consider the response fresh for 600 seconds, other shared caches
for 120 seconds, and any remaining caches for 60 seconds:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Cache-Control: max-age=60, s-maxage=120
CDN-Cache-Control: max-age=600
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;These header fields instruct a CDN cache to consider the
response fresh for 600 seconds, while all other caches are
prevented from storing it:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Cache-Control: no-store
CDN-Cache-Control: max-age=600
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Because CDN-Cache-Control is not present, this header field
prevent all caches from storing the response:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Cache-Control: no-store
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Whereas these prevent all caches except CDN caches from
storing the response:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Cache-Control: no-store
CDN-Cache-Control: none
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;(note that 'none' is not a registered cache directive; it is used here to
avoid sending a header field with an empty value, because such a
header might not be preserved in all cases).&lt;/p&gt;</content><category term="Learning"></category><category term="Caching"></category><category term="CDN"></category><category term="Rate Limiting"></category><category term="Drupal"></category><category term="Web Performance"></category></entry><entry><title>Cache-Status</title><link href="https://www.peakhour.io/blog/cdn-cache-status-header/" rel="alternate"></link><published>2022-02-25T13:00:00+11:00</published><updated>2022-02-25T13:00:00+11:00</updated><author><name>AC</name></author><id>tag:www.peakhour.io,2022-02-25:/blog/cdn-cache-status-header/</id><summary type="html">&lt;p&gt;Cache-Status is a proposed standard header to provide visibility into how caching providers interact and handle a request.&lt;/p&gt;</summary><content type="html">&lt;p&gt;Diagnosing &lt;a href="/learning/cdn/"&gt;CDN&lt;/a&gt; caching can be complex, with multiple cache layers, Origin Shielding, and local caching.
Understanding how these layers interact can mean spending weeks working through RFCs for the
finer details of ETag, Cache-Control, and Last-Modified headers - before you even account for advanced controls
that override them.&lt;/p&gt;
&lt;p&gt;When you have a problem, or are trying to optimise caching, the first thing you need is visibility into how a request was handled.&lt;/p&gt;
&lt;p&gt;This is where the new Cache-Status header helps. The new draft RFC, RFC draft-ietf-httpbis-cache-header-08, aims to:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;aide&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;debugging&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;by&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;standardising&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;various&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;non&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;standard&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;debug&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;used&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;by&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;major&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CDN&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;providers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;The&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;semantics&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;these&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;are&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;often&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;unclear&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ow"&gt;and&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;vary&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;between&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;implementations&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The draft RFC proposes a new header, Cache-Status, with a uniform format for showing how multiple
caching providers interact and handle a request. The Cache-Status header forms a list. Each member of the list
represents a cache that has handled the request, and the last member belongs to the cache that most recently
served the user. The header is only applicable to responses directly generated
by an origin server. Each member can add a parameter indicating how it handled the request.&lt;/p&gt;
&lt;p&gt;A Cache-Status header looks like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;Cache-Status&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;OriginCache&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hit&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ttl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nt"&gt;1100&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;CDN Company Here&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;fwd&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nt"&gt;uri-miss&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;It is formatted and labelled, with each cache in the line separated in list format by a ','.&lt;/p&gt;
&lt;h6&gt;The format of the Cache-Status header is a list comprising of the following possible parameters:&lt;/h6&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;hit&lt;/strong&gt;          = boolean&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;fwd&lt;/strong&gt;          = (bypass, method, uri-miss, vary-miss, request, stale, partial)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;fwd-status&lt;/strong&gt;   = integer&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ttl&lt;/strong&gt;          = integer&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;stored&lt;/strong&gt;       = boolean&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;collapsed&lt;/strong&gt;    = boolean&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;key&lt;/strong&gt;          = string&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;detail&lt;/strong&gt;       = token / string&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;What the parameters mean&lt;/h2&gt;
&lt;h3&gt;Hit&lt;/h3&gt;
&lt;p&gt;The hit parameter signifies that a request was satisfied by the cache. It is a boolean parameter meaning
that its presence indicates a cache hit.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;Cache-Status&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;Peakhour&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Fwd&lt;/h3&gt;
&lt;p&gt;The Fwd parameter indicates when a response was forwarded to an origin server - and why. The Fwd parameter
contains one of the following arguments:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;bypass&lt;/strong&gt; - The cache was configured to not handle this request&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;method&lt;/strong&gt; - The request method's semantics require the request to be
   forwarded&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;uri-miss&lt;/strong&gt; - The cache did not contain any responses that matched
   the request URI&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;vary-miss&lt;/strong&gt; - The cache contained a response that matched the
   request URI, but could not select a response based upon this
   request's headers and stored Vary headers.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;miss&lt;/strong&gt; - The cache did not contain any responses that could be used
   to satisfy this request (to be used when an implementation cannot
   distinguish between uri-miss and vary-miss)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;request&lt;/strong&gt; - The cache was able to select a fresh response for the
   request, but the request's semantics (e.g., Cache-Control request
   directives) did not allow its use&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;stale&lt;/strong&gt; - The cache was able to select a response for the request,
   but it was stale&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;partial&lt;/strong&gt; - The cache was able to select a partial response for the
   request, but it did not contain all of the requested ranges (or
   the request was for the complete response)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;Cache-Status&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;Peakhour&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;fwd&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nt"&gt;uri-miss&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Fwd-status&lt;/h3&gt;
&lt;p&gt;The fwd-status parameter indicates the status code the next hop returned in response to the request. It is only
meaningful when "fwd" is present. For example, a complete miss would look like &lt;em&gt;fwd=uri-miss&lt;/em&gt;
and the HTTP status code of the downstream response would be supplied in the fwd-status:&lt;/p&gt;
&lt;p&gt;The following example shows that the cache did not satisfy the request and that the downstream server
indicated an HTTP 304 response - HTTP Not Modified.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;Cache-Status&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;Peakhour&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;fwd&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nt"&gt;uri-miss&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;fwd-status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nt"&gt;304&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;ttl&lt;/h3&gt;
&lt;p&gt;Each cache item is associated with a lifetime, referred to as the Time To Live (TTL). A TTL is in seconds
and indicates the remaining  &lt;em&gt;freshness&lt;/em&gt; of the resource. This value is calculated by the cache.&lt;/p&gt;
&lt;p&gt;For example, a cache hit showing that the resource has a &lt;em&gt;freshness&lt;/em&gt; of 376 seconds.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;Cache-Status&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ExampleCache&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hit&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ttl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nt"&gt;376&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Another example shows a cache hit with &lt;em&gt;negative freshness&lt;/em&gt;  - a stale resource.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;Cache-Status&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ExampleCache&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hit&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ttl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nt"&gt;-412&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;stored&lt;/h3&gt;
&lt;p&gt;Indicates whether the received response was stored by the cache. This example shows a cache miss and the
cache storing the response for the next hit.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;Cache-Status&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ExampleCache&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;fwd&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nt"&gt;uri-miss&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;stored&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;collapsed&lt;/h3&gt;
&lt;p&gt;Indicates whether the received response was collapsed with another request.&lt;/p&gt;
&lt;h3&gt;key&lt;/h3&gt;
&lt;p&gt;The key is the lookup index into a cache. Cache keys convey a representation of how the cache will
look up the resource used for the response. The cache key is implementation-specific.&lt;/p&gt;
&lt;p&gt;This example shows a cache hit, the cache key and secondary key, and the remaining TTL of the resource.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;cache-status&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;peakhour&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;io&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hit&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;https://example.com/calendar.css&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;secondary-key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;encoding::gzip&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ttl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nt"&gt;30674859&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;detail&lt;/h3&gt;
&lt;p&gt;Allows additional implementation-specific information not captured by other parameters.&lt;/p&gt;
&lt;h3&gt;Multiple layers of caching&lt;/h3&gt;
&lt;p&gt;The header allows multiple layers of caching. For example, a global CDN may sit in front of a local varnish server.
Each cache appends its cache-status to the header, so the last item is the closest cache
to the actual application and the first item is the closest cache to the accessing user.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;Cache-Status&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;OriginCache&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hit&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ttl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nt"&gt;1100&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;CDN Company Here&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hit&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ttl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nt"&gt;545&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Security&lt;/h2&gt;
&lt;p&gt;There are security implications to consider with this header. Making it public gives an attacker insight
into how the cache is configured, which may help them bypass a cache entirely and access an origin server directly.
Cache header security is provider-specific, but could involve enabling it only when required, restricting access to specific
IP addresses, or requiring a custom request header to trigger the cache-status header.&lt;/p&gt;
&lt;p&gt;Peakhour.IO regularly sees automated scans sending other providers' headers to trigger a cache-status header response.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The Cache-Status header gives clear insight into how cache layers interact
on a website. It provides a standardised format for showing how a cache handled a request and
allows multiple caches to report their part of the request path.&lt;/p&gt;
&lt;p&gt;Peakhour fully supports this new header, and it can be enabled/disabled and secured in the dashboard.&lt;/p&gt;</content><category term="Learning"></category><category term="Caching"></category><category term="CDN"></category><category term="Drupal"></category><category term="HTTP"></category><category term="Rate Limiting"></category><category term="Web Performance"></category></entry><entry><title>Website Optimisation</title><link href="https://www.peakhour.io/blog/eliminating-blocking-resources/" rel="alternate"></link><published>2021-05-17T13:00:00+10:00</published><updated>2021-05-17T13:00:00+10:00</updated><author><name>Dan</name></author><id>tag:www.peakhour.io,2021-05-17:/blog/eliminating-blocking-resources/</id><summary type="html">&lt;p&gt;Even if you have the fastest server in the world, your website might still seem very slow to end users if you have lots of render blocking resources, learn how to deal with them.&lt;/p&gt;</summary><content type="html">&lt;p&gt;We've previously covered ways to find &lt;a href="https://www.peakhour.io/blog/common-issues-that-impact-site-speed/#blocking"&gt;resources that block rendering in a browser&lt;/a&gt;.
Now we'll cover techniques for loading those resources without letting them block rendering. Before making changes,
always run some &lt;a href="/blog/introduction-to-website-performance-testing/"&gt;website performance tests&lt;/a&gt;
using your favourite testing tool to get a baseline so you can measure any improvements. We recommend
&lt;a href="/blog/testing-website-speed-webpagetest/"&gt;testing with webpagetest.org&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Before we get into the techniques, it is worth defining the problem.&lt;/p&gt;
&lt;h2&gt;What is a Blocking Resource?&lt;/h2&gt;
&lt;p&gt;When a browser loads a page from a website it reads the HTML markup from top to bottom. If it
encounters a CSS or JavaScript file while it&amp;apos;s reading, the browser stops while it downloads and parses
that file. While the browser is waiting it can’t process the rest of the HTML or display
content to the user. Rendering is blocked.&lt;/p&gt;
&lt;h2&gt;Why is this a problem?&lt;/h2&gt;
&lt;p&gt;It would not be a problem if every page included only the information required to display it. Most websites do not work that way.
They are typically built using prebuilt themes and third-party libraries that can contain lots of
CSS and JavaScript. Only a tiny fraction of this code might be used on the current page, or it might only be needed for ‘below the fold’
content, or on another page of the site. &lt;strong&gt;Note: Below the fold means the content of a page that
doesn't initially fit on the screen&lt;/strong&gt;. Any unnecessary information keeps the browser blocked for longer than
needed, slowing the load experience for the user.&lt;/p&gt;
&lt;p&gt;CSS and JavaScript files are usually at the very top of the HTML document before any of the content. This means they
have to be downloaded and parsed before the browser can display anything. Even a website that has extremely fast server response
times can still seem very slow if it has blocking resources.&lt;/p&gt;
&lt;p&gt;Take a simple example: a website that includes a live chat widget. The JavaScript for the widget is
included at the very top of the page in the &lt;head&gt; section. The browser has to stop, download, and parse the CSS
and JavaScript for the widget (usually downloaded from a third-party domain) before any content is displayed to the user.
The chat widget could appear after the rest of the content without affecting the user experience.&lt;/p&gt;
&lt;h2&gt;Things you should always be doing&lt;/h2&gt;
&lt;p&gt;Before targeting CSS- or JavaScript-specific techniques, cover the basics for both.&lt;/p&gt;
&lt;h3&gt;1. Minify all files&lt;/h3&gt;
&lt;p&gt;Minification is the removal of all non-essential characters in a file, e.g. irrelevant whitespace and code comments. It
can make a substantial difference to the file size.&lt;/p&gt;
&lt;h3&gt;2. Ensure compression is enabled on your server&lt;/h3&gt;
&lt;p&gt;Make sure your server is configured to use either gzip or Brotli compression when serving CSS and JavaScript.&lt;/p&gt;
&lt;h3&gt;3. Self host files&lt;/h3&gt;
&lt;p&gt;If the CSS or JavaScript is on a third-party domain, i.e. not the domain name your website is on, you should strongly
consider uploading the file to your website and serving it from your domain. This might not always be possible, but if it
is it eliminates the overhead of the browser
opening a connection to another domain, and it removes the possibility that the third party is not compressing, minifying,
or using HTTP/2.&lt;/p&gt;
&lt;p&gt;After the implementation of &lt;a href="https://www.peakhour.io/blog/cache-partitioning-firefox-chrome/"&gt;cache partitioning in the major browsers&lt;/a&gt;,
there is no longer any &lt;em&gt;potential&lt;/em&gt; advantage to using third-party CDNs to serve assets like JavaScript, fonts, or CSS. Make a copy on your server and host
them on your domain.&lt;/p&gt;
&lt;h3&gt;4. If you can't self host then preconnect to third party domains&lt;/h3&gt;
&lt;p&gt;If external assets are on third-party domains, and you absolutely can't self host them, then you can improve
loading by telling the browser to &lt;code&gt;preconnect&lt;/code&gt; to the third-party domain.&lt;/p&gt;
&lt;p&gt;Using &lt;code&gt;preconnect&lt;/code&gt; tells the browser to establish an early connection to the domain before it has discovered the asset
while reading the HTML. Use &lt;code&gt;preconnect&lt;/code&gt; in the head of the HTML, e.g.:&lt;/p&gt;
&lt;p&gt;&lt;link rel="preconnect" href="https://example.com"&gt;&lt;/p&gt;
&lt;p&gt;Establishing early connections can shave 100-500ms off third-party load times, which is worth having. You should only use
&lt;code&gt;preconnect&lt;/code&gt; on critical third-party resources. For all the others you can use &lt;code&gt;dns-prefetch&lt;/code&gt;, e.g.:&lt;/p&gt;
&lt;p&gt;&lt;link rel="dns-prefetch" href="http://example.com"&gt;&lt;/p&gt;
&lt;p&gt;This tells the browser to perform DNS resolution of the domain early, which is similar to looking up a phone number
in the phone book. Pre-resolving DNS can save 20-120ms. That sounds like small numbers, but remember, &lt;a href="/website-performance/"&gt;differences as small
as 100ms can have large measurable impacts on conversion rates&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;5. Select only what you need from frameworks&lt;/h3&gt;
&lt;p&gt;It is common for users of frameworks like Bootstrap or jQuery UI to only use a fraction of the functionality provided.
If this is you, then the first step is to cut out what you're not using. Bootstrap and jQuery UI are modular, you can
either download everything in one bundle, or you can break it up to take just the bits you are using.&lt;/p&gt;
&lt;p&gt;These points will ensure that blocking resources are downloaded as quickly as possible. Now we can discuss some
specific techniques that will help minimise blocking and get your page displaying quickly. Please be aware that
this is not an exhaustive overview, but these techniques will probably get you 90% of the benefit with 10% of the work.
Getting that last 10% requires deeper technical work. If you want to go there, Google’s web.dev
website is a good resource.&lt;/p&gt;
&lt;h2&gt;Techniques for Optimising Blocking Resources&lt;/h2&gt;
&lt;h3&gt;Javascript&lt;/h3&gt;
&lt;p&gt;There are a few different techniques for optimising the loading of JavaScript. First, let's look at the default
loading behaviour. &lt;em&gt;Credit for the images goes to Daniel Imms and his website Growing with the web&lt;/em&gt;. As stated earlier,
the default behaviour is to stop parsing the HTML document when a script is encountered, download the script and execute it.&lt;/p&gt;
&lt;p&gt;&lt;img src="/static/images/blog/javascript-loading-legend.png" alt="Javascript loading legend" width="100%""/&gt;
&lt;img src="/static/images/blog/default-javascript-blocking-behaviour.png" alt="Default Javascript loading behaviour" width="100%"/&gt;&lt;/p&gt;
&lt;p&gt;Now let's look at how we can change this behaviour.&lt;/p&gt;
&lt;h4&gt;1. Moving scripts to the very bottom of the page, right before the closing &lt;/body&gt; tag.&lt;/h4&gt;
&lt;p&gt;This is the original optimisation technique, before defer and async were introduced. It works by moving scripts to
the very end of the HTML document, where they are downloaded and parsed after everything else.&lt;/p&gt;
&lt;p&gt;&lt;img src="/static/images/blog/javascript-loading-end-of-html.png" alt="Javascript end of page load" width="100%""/&gt;&lt;/p&gt;
&lt;p&gt;In our example in the previous section, the chat widget would now load and pop up after the rest of the content has been displayed to the user.&lt;/p&gt;
&lt;h4&gt;2. Defer and Async&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tags that have a &lt;code&gt;src&lt;/code&gt; attribute can be marked as either deferred &lt;code&gt;defer&lt;/code&gt;, or asynchronous &lt;code&gt;async&lt;/code&gt;, or both.
For example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&amp;lt;script src=”https://www.somedomain.com/somescript.js” defer async&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This tells the browser to change the script loading behaviour.&lt;/p&gt;
&lt;h4&gt;Defer&lt;/h4&gt;
&lt;p&gt;Defer was the original browser-based support for improved JavaScript loading. It tells the
browser to download the script asynchronously while it keeps reading the HTML, and then execute it once it has finished reading the whole HTML document. Here's the loading behaviour
with defer enabled.&lt;/p&gt;
&lt;p&gt;&lt;img src="/static/images/blog/javascript-loading-defer.png" alt="Javascript loading defer" width="100%""/&gt;&lt;/p&gt;
&lt;p&gt;As you can see the script no longer blocks the browser from doing anything else while downloading. Defer preserves
script execution order. This can be very important if a script depends on one declared earlier in the page.&lt;/p&gt;
&lt;p&gt;As noted earlier, you can only mark &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tags that have a &lt;code&gt;src&lt;/code&gt; attribute as deferred. Inline scripts, e.g.:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;console.log(&amp;quot;Hi&lt;span class="w"&gt; &lt;/span&gt;I&amp;#39;m&lt;span class="w"&gt; &lt;/span&gt;some&lt;span class="w"&gt; &lt;/span&gt;inline&lt;span class="w"&gt; &lt;/span&gt;script!&amp;quot;);
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Any attempt to defer that inline block will simply be ignored. This can cause problems if you have inline script scattered through your code
and rely on a deferred third-party library, e.g. jQuery. There are two potential solutions if you can't simply move the
code to the bottom of the page:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Move each inline code block into its own file and include it using the &lt;code&gt;src&lt;/code&gt; attribute so you can defer it.&lt;/li&gt;
&lt;li&gt;Or you can try declaring the block as a &lt;code&gt;module&lt;/code&gt;. Test this carefully, as browser support may be limited and it also
   places the script into &lt;code&gt;strict&lt;/code&gt; mode, which may break it.&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;Async&lt;/h4&gt;
&lt;p&gt;The &lt;code&gt;async&lt;/code&gt; attribute tells the browser to download the script now and execute it as soon as it has finished. Like &lt;code&gt;defer&lt;/code&gt;, the
downloading is done asynchronously. Unlike &lt;code&gt;defer&lt;/code&gt;, the script is executed as soon as it is downloaded. Here is the behaviour:&lt;/p&gt;
&lt;p&gt;&lt;img src="/static/images/blog/javascript-loading-async.png" alt="Javascript loading async" width="100%""/&gt;&lt;/p&gt;
&lt;p&gt;As you can see the browser doesn't stop while downloading, but does pause once downloading is finished so it can execute
the script. &lt;strong&gt;&lt;code&gt;async&lt;/code&gt; doesn't preserve script order&lt;/strong&gt;, which can potentially cause issues when there are script dependencies.&lt;/p&gt;
&lt;p&gt;All three methods have pros and cons. &lt;code&gt;Defer&lt;/code&gt; and &lt;code&gt;async&lt;/code&gt; result in faster page loads overall as the scripts are downloaded
while the browser reads the HTML. Moving the script to the bottom of the page shifts the sequence around.&lt;/p&gt;
&lt;p&gt;Your first option should be to &lt;code&gt;defer&lt;/code&gt; all scripts. Then, if some above the fold content is taking too long because it has a
JavaScript dependency, e.g. a carousel in the hero section, you can try making the necessary scripts &lt;code&gt;async&lt;/code&gt; instead.&lt;/p&gt;
&lt;h3&gt;Optimising CSS&lt;/h3&gt;
&lt;p&gt;The key to fast CSS loading is to prioritise the CSS needed for the immediate above the fold content and then defer
the rest. Many articles advocate extracting the precise CSS and then including it inline
in the HTML document in a style block, i.e.:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;style&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;text/css&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;.accordion-btn&lt;span class="w"&gt; &lt;/span&gt;{background-color:&lt;span class="w"&gt; &lt;/span&gt;#ADD8E6;color:&lt;span class="w"&gt; &lt;/span&gt;#444;cursor:&lt;span class="w"&gt; &lt;/span&gt;pointer;padding:&lt;span class="w"&gt; &lt;/span&gt;18px;width:&lt;span class="w"&gt; &lt;/span&gt;100%;border:&lt;span class="w"&gt; &lt;/span&gt;none;text-align:&lt;span class="w"&gt; &lt;/span&gt;left;outline:&lt;span class="w"&gt; &lt;/span&gt;none;font-size:&lt;span class="w"&gt; &lt;/span&gt;15px;transition:&lt;span class="w"&gt; &lt;/span&gt;0.4s;}.container&lt;span class="w"&gt; &lt;/span&gt;{padding:&lt;span class="w"&gt; &lt;/span&gt;0&lt;span class="w"&gt; &lt;/span&gt;18px;display:&lt;span class="w"&gt; &lt;/span&gt;none;background-color:&lt;span class="w"&gt; &lt;/span&gt;white;overflow:&lt;span class="w"&gt; &lt;/span&gt;hidden;}h1&lt;span class="w"&gt; &lt;/span&gt;{word-spacing:&lt;span class="w"&gt; &lt;/span&gt;5px;color:&lt;span class="w"&gt; &lt;/span&gt;blue;font-weight:&lt;span class="w"&gt; &lt;/span&gt;bold;text-align:&lt;span class="w"&gt; &lt;/span&gt;center;}
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;However, you have to do this on every possible landing page where the critical CSS might be different per page. Inlining
CSS also adds to the download size for each page, and forces the browser to reparse the CSS rules for every load rather
than being able to use a cached file for repeat views.&lt;/p&gt;
&lt;p&gt;We advocate for putting the critical CSS into its own file and loading that normally, and then deferring any other non
critical CSS. Identifying the critical CSS is the main task. The first thing to do is to look at the included
CSS on your website and see if you can identify any non-core files. You can defer those files using this pattern:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;as=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;style&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/styles.css&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;onload=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;this.onload=null;this.rel=&amp;#39;stylesheet&amp;#39;&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;noscript&amp;gt;&amp;lt;link&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;stylesheet&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/styles.css&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/noscript&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;as="style"&lt;/code&gt; lets the browser download the file asynchronously. The onload changes the type to stylesheet, telling the
browser to parse the file. Finally, we include a &lt;code&gt;&amp;lt;noscript&amp;gt;&lt;/code&gt; to enable the CSS to load normally if JavaScript is turned off.&lt;/p&gt;
&lt;p&gt;Once you've deferred non-core CSS files you can still check whether your core ones contain lots of unused rules.
Google Chrome's coverage tool can show unused rules, but it
doesn’t let you easily export used and unused rules. You have to go through it yourself, programmatically, or use
a third-party tool to make two files: the critical CSS, and the non-critical CSS which can be deferred.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Eliminating, or at least minimising, blocking resources can be one of the biggest improvements to user experience you can make to your
site. With &lt;a href="/blog/web-vitals/"&gt;Google Web Vitals&lt;/a&gt; being introduced soon as a search signal, it is important
to make sure your website loads as fast as possible so your users stay longer and buy more
from your site.&lt;/p&gt;</content><category term="Performance"></category><category term="Web Performance"></category><category term="Caching"></category><category term="Drupal"></category><category term="Rate Limiting"></category><category term="WordPress"></category><category term="Core Web Vitals"></category></entry><entry><title>What is the Chrome UX Report (CrUX), and why should you care?</title><link href="https://www.peakhour.io/blog/what-is-the-chrome-ux-report-crux/" rel="alternate"></link><published>2021-02-26T13:00:00+11:00</published><updated>2026-07-06T13:00:00+10:00</updated><author><name>Dan</name></author><id>tag:www.peakhour.io,2021-02-26:/blog/what-is-the-chrome-ux-report-crux/</id><summary type="html">&lt;p&gt;Learn what the Chrome UX Report is, how CrUX field data feeds Core Web Vitals reporting, and how to use it alongside lab tools.&lt;/p&gt;</summary><content type="html">&lt;p&gt;A faster website is better for clients: they buy more, and they engage more with your content.
However &lt;strong&gt;there's someone else that rewards fast websites: Google.
Fast websites rank higher in organic search results than slower websites. They will also achieve higher quality scores in Google Ads,
resulting in lower ad spend.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;We've previously written about &lt;a href="/blog/web-vitals/"&gt;Google's Web Vitals&lt;/a&gt;. The practical question is where the real-world data comes from. It is not gathered by Googlebot. Google uses field data from the Chrome User Experience Report, usually shortened to CrUX, to show how eligible Chrome users actually experienced a page or origin.&lt;/p&gt;
&lt;p&gt;That matters because a fast lab score is not the same thing as a fast customer experience. &lt;a href="/blog/testing-website-speed-webpagetest/"&gt;WebPageTest&lt;/a&gt; and Lighthouse help diagnose a controlled test run. CrUX shows the field data behind PageSpeed Insights, Search Console's Core Web Vitals report, and Peakhour's &lt;a href="/pages/website-competitor-speed-test/"&gt;website speed comparison tool&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Introducing the Chrome UX Report (CRuX)&lt;/h2&gt;
&lt;p&gt;The CrUX report is a public data set of real-user measurements (RUM) of &lt;a href="/blog/testing-sitespeed-lighthouse/"&gt;website performance&lt;/a&gt; across millions of sites. The report has been around since 2017 and is updated regularly, but the value is still often missed: it shows what real users experienced, not what a synthetic test predicted.&lt;/p&gt;
&lt;p&gt;The data is collected from real Chrome browser users who have opted in to send browsing information back to Google.
This opt-in requires that the user has:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Opted in to syncing browser history&lt;/li&gt;
&lt;li&gt;Not set up a sync passphrase&lt;/li&gt;
&lt;li&gt;Usage statistic reporting enabled&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Despite these conditions, millions of Chrome users still report statistics back to Google. A given website still needs
to be fairly busy before there are useful statistics in the report.&lt;/p&gt;
&lt;h3&gt;Gathered Metrics&lt;/h3&gt;
&lt;p&gt;The current Core Web Vitals are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Largest Contentful Paint (LCP)&lt;/strong&gt;: how quickly the main content appears.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Interaction to Next Paint (INP)&lt;/strong&gt;: how responsive the page is to real user interactions.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cumulative Layout Shift (CLS)&lt;/strong&gt;: how visually stable the page is while it loads.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;CrUX also exposes supporting performance metrics and dimensions that help explain those headline scores. Older metrics such as First Input Delay (FID) still appear in older reports and tools, but INP is now the responsiveness metric to watch.&lt;/p&gt;
&lt;h3&gt;Dimensions&lt;/h3&gt;
&lt;p&gt;Because performance can vary widely, the metrics are divided into the following dimensions to help segment and understand the user experience.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Country&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Device Type&lt;/strong&gt;: Tablet, Phone, Desktop&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Connection Speed&lt;/strong&gt;: slow 2g, 2g, 3g, 4g, or offline&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Viewing data in the report&lt;/h2&gt;
&lt;p&gt;There are several ways to see how &lt;a href="/learning/performance/how-to-pass-core-web-vitals/"&gt;your website&lt;/a&gt; performs in the report. These include:&lt;/p&gt;
&lt;h4&gt;Pagespeed insights&lt;/h4&gt;
&lt;p&gt;Google's website analysis tool provides summary CRuX data for the analysed URL and, if data is available, for the entire site.&lt;/p&gt;
&lt;p&gt;&lt;img src="/static/images/blog/page-speed-insights-field-data.jpg" alt="&lt;a href="/solutions/use-case/improve-web-vitals/"&gt;Page Speed&lt;/a&gt; Insights Field Data" style="max-width: 100%;margin-bottom: 20px"/&gt;&lt;/p&gt;
&lt;h4&gt;Google BigQuery&lt;/h4&gt;
&lt;p&gt;The most flexible option is to access it directly via &lt;a href="https://console.cloud.google.com/bigquery?project=chrome-ux-report"&gt;BigQuery&lt;/a&gt;.
You query it with SQL (database query language).&lt;/p&gt;
&lt;p&gt;The downside is that you need to understand SQL and have a Google account.&lt;/p&gt;
&lt;h4&gt;Google's Search Console (formerly Webmaster Tools)&lt;/h4&gt;
&lt;p&gt;The search console now has a section 'Core Web Vitals' that shows whether URLs pass the Core Web Vitals,
as well as a historical graph of performance for both mobile and desktop.&lt;/p&gt;
&lt;p&gt;&lt;img src="/static/images/blog/search-console.jpg" alt="Google Search Console Web Vitals" style="max-width: 100%;margin-bottom: 20px"/&gt;&lt;/p&gt;
&lt;h4&gt;Looker Studio&lt;/h4&gt;
&lt;p&gt;Looker Studio, formerly Google Data Studio, can be used to build dashboards on top of CrUX data and other sources. It lets you visualise the performance of your website, or a competitor's website, over time.&lt;/p&gt;
&lt;p&gt;&lt;img src="/static/images/blog/data-studio.jpg" alt="Google data studio" style="max-width: 100%;margin-bottom: 20px"/&gt;&lt;/p&gt;
&lt;h4&gt;Third party tools&lt;/h4&gt;
&lt;p&gt;Like our own &lt;a href="/pages/website-competitor-speed-test/"&gt;website speed comparison tool&lt;/a&gt;. It uses the
&lt;a href="https://developers.google.com/web/tools/chrome-user-experience-report/api/reference"&gt;Chrome UX API&lt;/a&gt; to retrieve the
information.&lt;/p&gt;
&lt;h2&gt;CrUX vs lab tools vs RUM&lt;/h2&gt;
&lt;p&gt;CrUX is field data. It is useful because it reflects real Chrome users, but it only reports where there is enough eligible traffic. It can also be slower to reveal the cause of a problem because it is aggregated.&lt;/p&gt;
&lt;p&gt;Lab tools such as &lt;a href="/blog/testing-website-speed-webpagetest/"&gt;WebPageTest&lt;/a&gt; are better for diagnosis. They show waterfalls, redirects, blocked resources, caching issues, image weight, and third-party requests. Your own real user monitoring can go further again, because it can include business context that CrUX does not know: customer type, template, campaign, cache state, bot pressure, origin load, and release timing.&lt;/p&gt;
&lt;h2&gt;Conclusion - Why you should care&lt;/h2&gt;
&lt;p&gt;The data in the Chrome UX Report is one of the clearest public views of how Google sees the performance of your website. It is also a free source of real-world user measurements that helps you understand how visitors experience your pages.&lt;/p&gt;
&lt;p&gt;Use CrUX to see whether your site is passing Core Web Vitals, use lab tools to find the technical cause, and use traffic visibility to understand whether bots, crawlers, bursts, cache misses, or expensive requests are putting the experience under pressure. If the first question is "how do we compare?", start with the &lt;a href="/pages/website-competitor-speed-test/"&gt;website speed comparison tool&lt;/a&gt;. If the question is "what is slowing us down?", start with &lt;a href="/solutions/use-case/traffic-control/"&gt;Traffic Management&lt;/a&gt;.&lt;/p&gt;</content><category term="Learning"></category><category term="Web Performance"></category><category term="SEO"></category><category term="Core Web Vitals"></category><category term="Analytics"></category><category term="Browser Fingerprinting"></category><category term="Magento"></category></entry><entry><title>The CDN is Dead, Long Live the CDN!</title><link href="https://www.peakhour.io/blog/cache-partitioning-firefox-chrome/" rel="alternate"></link><published>2021-02-17T13:00:00+11:00</published><updated>2021-02-17T13:00:00+11:00</updated><author><name>Dan</name></author><id>tag:www.peakhour.io,2021-02-17:/blog/cache-partitioning-firefox-chrome/</id><summary type="html">&lt;p&gt;Firefox and Chrome are introducing cache partitioning to improve your privacy, from everyone except Google.&lt;/p&gt;</summary><content type="html">&lt;p&gt;It has long been conventional wisdom that if your website uses a third-party library, such as jQuery or Bootstrap,
you should load it from the library's high-performance &lt;a href="/learning/cdn/"&gt;CDN&lt;/a&gt;. For example, jQuery has&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;code.jquery.com
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;from which you can include any version of jQuery on your website, e.g.:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;https://code.jquery.com/jquery-3.3.1.min.js&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="na"&gt;integrity=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="na"&gt;crossorigin=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;anonymous&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This was meant to give you two performance benefits: the browser could load jQuery from a global CDN, &lt;strong&gt;AND&lt;/strong&gt; if another site
the visitor had already opened included the same jQuery file in the same way, the file might already be in their
browser cache. In that case the browser could reuse the cached copy and the page would load faster.&lt;/p&gt;
&lt;p&gt;In practice, website visitors rarely see much benefit. The browser still has to open a separate connection
to the third-party CDN, which can cancel out any latency advantage the CDN provides. There are also so many versions
of major libraries in use that the chance of two websites using the same version,
AND both loading it from the CDN in the same way, is small.&lt;/p&gt;
&lt;h2&gt;Cache Partitioning in Chrome and Firefox&lt;/h2&gt;
&lt;p&gt;Until recently, Chrome and Firefox used a shared browser cache for all websites that a user visited. This means that if
you visited a website and it loaded this resource:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;https://www.somesite.com/foo.js
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;and you then visited a second website that included the same resource, the resource would be loaded from the
shared cache rather than being downloaded from the internet a second time. Cookies set by these resources would also be shared.&lt;/p&gt;
&lt;p&gt;As of Firefox v85 and Chrome v86, the browser cache will be partitioned. This means that the same resource included
on two sites will have to be downloaded from the internet twice and stored separately.&lt;/p&gt;
&lt;h2&gt;Why are they doing this?&lt;/h2&gt;
&lt;p&gt;The main reason is privacy. Shared browser caches have been used by unscrupulous operators
to track users across different websites without consent. They do this by utilising cache
side-channel attacks.&lt;/p&gt;
&lt;h2&gt;What Are Side Channel Attacks?&lt;/h2&gt;
&lt;p&gt;In computer systems, a program or algorithm can be correct and secure in itself, while its interaction with the computer still leaves
information that an attacker can exploit. A useful analogy from the spy world is using a laser beam to measure the vibrations
on a pane of glass, so you can hear a conversation inside a room that you otherwise could not hear.&lt;/p&gt;
&lt;p&gt;Side-channel attacks can be ingenious, utilising techniques such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;observing power consumption/electromagnetic radiation;&lt;/li&gt;
&lt;li&gt;timing data moving in and out of memory;&lt;/li&gt;
&lt;li&gt;timing how long a CPU takes to execute an instruction;&lt;/li&gt;
&lt;li&gt;measuring sounds emitted by a hard drive.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For the browser cache, a simple attack starts with the user opening a malicious website. That website
then requests resources (e.g., an image) from another site. By timing how long the browser takes to load that image,
it can determine whether it was fetched from the browser cache or had to be downloaded
over the internet. According to Google, this technique can be used to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Detect if a user has visited a specific site.&lt;/li&gt;
&lt;li&gt;Detect if an arbitrary string is in the user's search results by checking for 'no search result' images used by particular
  sites.&lt;/li&gt;
&lt;li&gt;Track users across sites using the cache.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;GitHub user terjanq has published a &lt;a href="https://terjanq.github.io/Bug-Bounty/Google/cache-attack-06jd2d2mz2r0/index.html_"&gt;cache side channel attack&lt;/a&gt;
that can gather all sorts of information from Google services. He states that a regular Google user could have the following
information leaked:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;search history&lt;/li&gt;
&lt;li&gt;videos watched&lt;/li&gt;
&lt;li&gt;the exact URLs visited&lt;/li&gt;
&lt;li&gt;time frames of the activities&lt;/li&gt;
&lt;li&gt;private book collection&lt;/li&gt;
&lt;li&gt;books read / purchased / bookmarked / favourite / etc.&lt;/li&gt;
&lt;li&gt;private emails&lt;/li&gt;
&lt;li&gt;tokens / credit card numbers / phone numbers / etc.&lt;/li&gt;
&lt;li&gt;contacts (including email addresses, names, phone numbers)&lt;/li&gt;
&lt;li&gt;bookmarked websites&lt;/li&gt;
&lt;li&gt;and more.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Perhaps it was simpler to implement cache partitioning in Chrome than to keep patching these vulnerabilities...&lt;/p&gt;
&lt;h2&gt;What you should do&lt;/h2&gt;
&lt;p&gt;Google estimates that the changes in browser caching will have minimal impact, as little as a 0.3% difference in
FCP (First Contentful Paint). However, since there will no longer be any shared-cache benefit from hosting on a third-party CDN, you should:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Host all third-party libraries on your own domain&lt;/strong&gt; to eliminate the need for the browser to establish a second connection.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use a delivery layer such as Peakhour Edge,&lt;/strong&gt; which transparently caches and serves your website assets close to users.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Some third-party resources really are shared across millions of websites. Google Fonts is the obvious example.
Under the new cache partitioning implementations, these fonts will have to be downloaded for every site
that uses them. That has a cost for site speed and data usage. It also has the side effect of
&lt;strong&gt;improving&lt;/strong&gt; Google's ability to track users, because each font request tells Google another site the user has visited.&lt;/p&gt;
&lt;p&gt;Safari has been partitioning the HTTP cache since 2013, leaving Microsoft's Edge as the last major browser with global HTTP caches.
However, future versions will be based on Chromium (the open-source version of Chrome) so should get cache partitioning by default.&lt;/p&gt;</content><category term="Learning"></category><category term="CDN"></category><category term="Caching"></category><category term="Drupal"></category><category term="Web Performance"></category></entry><entry><title>Secure Dynamic Content Caching</title><link href="https://www.peakhour.io/blog/caching-dynamic-content-with-a-cdn/" rel="alternate"></link><published>2021-02-09T13:00:00+11:00</published><updated>2021-02-09T13:00:00+11:00</updated><author><name>Dan</name></author><id>tag:www.peakhour.io,2021-02-09:/blog/caching-dynamic-content-with-a-cdn/</id><summary type="html">&lt;p&gt;Comprehensive guide to secure dynamic content caching that improves server performance whilst maintaining security controls. Learn how modern application security platforms integrate caching with threat protection for optimal performance-security balance.&lt;/p&gt;</summary><content type="html">&lt;p&gt;Last time we covered how &lt;a href="/blog/common-issues-that-impact-site-speed/#slow" target="issues"&gt;slow server performance&lt;/a&gt; can
have a negative, sometimes &lt;strong&gt;very&lt;/strong&gt; negative, effect on your website load times. The causes of slow server responses
are many and varied, and not necessarily tied to the server specification. Diagnosing and dealing with them can be difficult,
time-consuming, and costly. One practical way to reduce the impact is to look for opportunities to cache
&lt;a href="/learning/dynamic-content-caching/"&gt;dynamic content&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;What is Dynamic Content?&lt;/h2&gt;
&lt;p&gt;Content delivered by a web server is categorised as either static or dynamic. Static content is the same for every user
and is delivered without being generated or processed by the server. Static content is fast to deliver
and does not tax a server's resources.&lt;/p&gt;
&lt;p&gt;Dynamic content is generated by the server for every request. That can involve querying a database several times and executing
a large amount of code. Depending on the work required to generate the result, dynamic content can be resource-heavy.&lt;/p&gt;
&lt;p&gt;Traditionally CDNs have only cached and served the static content of websites, usually the images, CSS files,
Javascript files, etc. They required the webmaster to upload these resources to the CDN's servers and to modify their website
source HTML to access the resources from the CDN. For example,&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;https://www.yourdomain.com/image1.jpg
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;would be changed to be something like&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;https://cdn.yourdomain.com/image1.jpg
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Modern CDNs, like Peakhour, act as a reverse proxy{:target="learning"}, which means they sit between the
end user and the website's origin server. This enables them to &lt;em&gt;transparently&lt;/em&gt; cache a copy of &lt;em&gt;anything cacheable&lt;/em&gt; being returned by the
origin server. By transparently caching, we mean the caching happens without changes to the original website.&lt;/p&gt;
&lt;h3&gt;Full Page Caching&lt;/h3&gt;
&lt;p&gt;Full Page Caching (FPC) is where the actual HTML document of a web page is cached.&lt;/p&gt;
&lt;p&gt;Most websites are built using a Content Management System (CMS). Widely used CMS platforms are Wordpress,
Drupal, Magento, etc. By default, every time a page is viewed the CMS has to generate the content
from its database. Most of the time this generation is unnecessary. The content is either the
same for every user, changes very rarely, or only differs by a small amount of personalisation. In each case it
is possible to perform Full Page Caching to improve page load times and to cut server load. Let's have a look at the
difference full page caching makes to one of our clients, Magento 2 store &lt;a href="/case-studies/savvysupporter/"&gt;savvysupporter.com.au&lt;/a&gt;.&lt;/p&gt;
&lt;div class="text-center" style="padding: 20px 0px"&gt;
&lt;img src="/static/images/savvy-before.jpg" width="100%" alt="Savvysupporter before"/&gt;
&lt;em&gt;Main document load &lt;strong&gt;before&lt;/strong&gt; caching: &lt;strong&gt;2.07s&lt;/strong&gt;&lt;/em&gt;
&lt;/div&gt;

&lt;div class="text-center" style="padding: 20px 0px"&gt;
&lt;img src="/static/images/savvy-after.jpg" width="100%" alt="Savvysupporter after"/&gt;
&lt;em&gt;Main document load &lt;strong&gt;after&lt;/strong&gt; caching: &lt;strong&gt;82ms!!&lt;/strong&gt;&lt;/em&gt;
&lt;/div&gt;

&lt;p&gt;Caching the page has cut nearly &lt;strong&gt;2 whole seconds&lt;/strong&gt; from the download time. That matters: load differences
as small as 100 milliseconds have measurable impacts on website conversion rates. With a Magento 2
website, it's possible to cache all full pages outside the checkout process and the customer/admin area. This can reduce load
on the origin in the order of &lt;strong&gt;60-70%&lt;/strong&gt; and make the customer experience much better.&lt;/p&gt;
&lt;h3&gt;API (Application Programming Interface) Caching&lt;/h3&gt;
&lt;p&gt;Many API calls used by web applications are for the retrieval of information to be displayed to the end user. Examples
 include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pricing and product information&lt;/li&gt;
&lt;li&gt;Form auto completion&lt;/li&gt;
&lt;li&gt;Product catalogue searches&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These are all strong candidates for caching, reducing load on your server and making websites faster.&lt;/p&gt;
&lt;h2&gt;Handling Stale Information&lt;/h2&gt;
&lt;p&gt;The one potential drawback of caching dynamic content is the possibility of returning out of date information to the
end user. There are two strategies to deal with this risk.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Setting a short Time To Live (TTL) with the caching provider&lt;/strong&gt;. By only keeping content cached for a short time, e.g. 5
   minutes, the cache will never be without up to date information for very long. Cached content will expire and the new
   version fetched from the origin server. The drawback with this method is that, unless your site is very busy, cache hit
   rates can be low, users can frequently get slow loading pages, and stale content is still possible. However, for very
   busy sites this can be an effective, low-overhead strategy.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Flushing content when it changes&lt;/strong&gt;. This strategy sets very long time to live in the cache, months or even years. When
   content is updated the cache is informed and the new version fetched. This notification of new content could happen
   manually or, in the case of some CMSs, automatically. For example, Magento 2 and Drupal 8 have a built in framework
   for integrating caching providers to handle flushing when content/stock changes. This strategy ensures very high hit
   rates, but unless the flushing is accurate and fast it can result in stale content.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Security-Performance Integration&lt;/h2&gt;
&lt;p&gt;Modern &lt;a href="/learning/application-security/what-is-application-security-platform/"&gt;Application Security&lt;/a&gt; platforms like Peakhour combine caching with comprehensive security controls so performance optimisation does not weaken application protection:&lt;/p&gt;
&lt;h3&gt;Edge Security Processing&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;WAF/WAAP Integration&lt;/strong&gt;: Security rules are processed at the edge before content is cached, ensuring malicious requests never reach your origin&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bot Management&lt;/strong&gt;: Caching adapts based on traffic classification - legitimate users benefit from cached content whilst malicious bots are filtered out&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;API Protection&lt;/strong&gt;: Secure caching of API responses with appropriate security headers and access controls&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Cache Security Controls&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Secure Purging&lt;/strong&gt;: Authorised cache invalidation through secure API endpoints with proper authentication&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Content Classification&lt;/strong&gt;: Different caching policies for public, authenticated, and sensitive content&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Header Security&lt;/strong&gt;: Automatic injection of security headers (CSP, HSTS, etc.) into cached responses&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Secure dynamic &lt;a href="/products/advanced-caching/"&gt;content caching&lt;/a&gt; works best when performance optimisation and application security are handled together. By implementing caching within an Application Security Platform, organisations can achieve:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Superior Performance&lt;/strong&gt;: Dramatic improvements in load times and server capacity&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enhanced Security&lt;/strong&gt;: Protection against threats at the edge before they impact cached content&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Operational Efficiency&lt;/strong&gt;: Reduced origin server load whilst maintaining security posture&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cost Optimisation&lt;/strong&gt;: Lower infrastructure costs through intelligent caching and edge processing&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For modern applications and APIs, secure dynamic caching should form part of the performance and security strategy, improving the user experience whilst maintaining threat protection.&lt;/p&gt;</content><category term="Performance"></category><category term="Drupal"></category><category term="Caching"></category><category term="WordPress"></category><category term="Web Performance"></category><category term="CDN"></category><category term="Rate Limiting"></category></entry><entry><title>Common Issues That Affect Website Performance</title><link href="https://www.peakhour.io/blog/common-issues-that-impact-site-speed/" rel="alternate"></link><published>2020-11-30T13:00:00+11:00</published><updated>2020-11-30T13:00:00+11:00</updated><author><name>Dan</name></author><id>tag:www.peakhour.io,2020-11-30:/blog/common-issues-that-impact-site-speed/</id><summary type="html">&lt;p&gt;After covering testing we're going to get an overview of the common issues that impact website load times and how to check for them.&lt;/p&gt;</summary><content type="html">&lt;p&gt;Our last three website performance articles covered the why and how of
&lt;a href="/blog/introduction-to-website-performance-testing/"&gt;testing website performance&lt;/a&gt;,
and introduced our two favourite performance testing tools, &lt;a href="/blog/testing-website-speed-webpagetest/"&gt;WebPageTest.org&lt;/a&gt;, and
&lt;a href="https://www.peakhour.io/blog/testing-sitespeed-lighthouse/"&gt;Lighthouse&lt;/a&gt;. This article covers the common causes of slow
loading times, and how to spot them using the same testing tools.&lt;/p&gt;
&lt;h2&gt;1. Latency&lt;/h2&gt;
&lt;p&gt;Latency is the time it takes for a request from a client's browser to traverse the internet to reach the website server.
A number of factors affect latency, with physical distance usually the main one.
Data on the internet travels at the speed of light, so distance may not sound like a major concern.
In practice, small delays compound quickly. Here are some realistic examples of request
latency:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sydney to Melbourne: 5ms&lt;/li&gt;
&lt;li&gt;Sydney to Perth: 25ms&lt;/li&gt;
&lt;li&gt;Sydney to San Francisco: 75ms&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: Common tools used to determine latency between servers are Ping and Traceroute, they will provide you with
&lt;strong&gt;Request Round Trip (RTT)&lt;/strong&gt; latency, ie the time it takes for a request to get to the server and back. So 2 times the numbers above.&lt;/p&gt;
&lt;p&gt;Here is an example of latency during a webpage load. We'll ignore internet speed and any potential
network congestion, and focus only on latency. We'll request a website hosted in San Francisco from a
browser located in Sydney.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Browser establishes a TLS (Secure) connection with server, &lt;em&gt;6 * 75ms&lt;/em&gt; = &lt;strong&gt;450ms&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Browser sends HTTP Request for the main page = &lt;strong&gt;75ms&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Server sends HTTP Response containing page which specifies 10 assets = &lt;strong&gt;75ms&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Browser requests the 10 additional assets = &lt;strong&gt;75ms&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Server responds with 10 assets &lt;em&gt;10 * 75&lt;/em&gt; = &lt;strong&gt;750ms&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In this example, a website with 10 assets, which is a fairly simple page, has nearly &lt;strong&gt;1.5s&lt;/strong&gt; added to
the page load time through latency alone. If the same site was hosted in Melbourne, the time due to latency would be just
&lt;strong&gt;95ms&lt;/strong&gt;. To solve this problem you would either move your website server closer to your customers, or use Peakhour Edge caching.&lt;/p&gt;
&lt;h3&gt;How do I check for latency problems?&lt;/h3&gt;
&lt;p&gt;If there is a long distance between your server and your customers, eg your website is hosted in the US and your customers
are in Australia, page load times will be significantly affected by latency. A good tool for indicative RTT times between cities is
provided by &lt;a href="https://wondernetwork.com/pings"&gt;wonder network&lt;/a&gt;. Webpagetest.org also provides a Traceroute tool which
can give you indicative RTT times between its testing locations and your website.&lt;/p&gt;
&lt;h2&gt;2. Old version of HTTP&lt;/h2&gt;
&lt;p&gt;Browsers communicate with websites using a protocol called HTTP. The protocol formalises the steps needed to connect a
browser and server so a webpage can be downloaded. Since the introduction of the web, HTTP has gone through
a number of revisions. The currently widely adopted version is HTTP/2.&lt;/p&gt;
&lt;p&gt;Even though HTTP/2 was introduced over 5 years ago, over &lt;a href="https://w3techs.com/technologies/details/ce-http2" target="trends"&gt;50% of websites&lt;/a&gt;
are still only served over HTTP/1.1. Without getting too technical, HTTP/2 has significant advantages over older versions
because it reduces the number of connections between a browser and server, and transfers information more efficiently.&lt;/p&gt;
&lt;p&gt;Serving your website over HTTP/2 can improve page load times by &lt;strong&gt;10-15%&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;How do I identify the version of HTTP my website is served over?&lt;/h3&gt;
&lt;p&gt;&lt;a href="/blog/testing-website-speed-webpagetest/" target="testing"&gt;Run a performance test of your website&lt;/a&gt; using WebPageTest.org, once complete
click on the 'Details' link in the report navigation. You will see the Waterfall View. Click on the first request, circled
below in this image:&lt;/p&gt;
&lt;p&gt;&lt;img src="/static/images/blog/http2-waterfall.jpg" alt="Webpagetest waterfall view" style="width: 100%;margin-bottom: 20px"/&gt;&lt;/p&gt;
&lt;p&gt;It will bring up the request details including the Protocol used, circled below:&lt;/p&gt;
&lt;p&gt;&lt;img src="/static/images/blog/request-detail-http2.jpg" alt="HTTP Request Detail" style="width: 100%;margin-top: 20px"/&gt;&lt;/p&gt;
&lt;h2&gt;3. &lt;a name="slow"&gt;&lt;/a&gt; Slow Server Performance&lt;/h2&gt;
&lt;p&gt;A slow initial response from the server is a common cause of poor page load
performance. The majority of websites are built using some sort of Content Management System (CMS), eg Wordpress, Magento,
Drupal, Shopify, to name a few. By default, a CMS has to construct a page each time a browser requests it, even when the
content has not changed. That process can involve executing a lot of code and querying a database several times
before returning the HTML that forms the page.&lt;/p&gt;
&lt;p&gt;The specification of your server, the number of CMS plugins, the state of your database, and the number of simultaneous
users can all affect the response time. A slow server may take 10s or more to respond, while even a fast server can still take over
a second to generate a page. That is enough to pretty much make you fail the new Core Web Vitals guidelines before you even
get started.&lt;/p&gt;
&lt;h3&gt;How do I check for slow server performance?&lt;/h3&gt;
&lt;p&gt;Server performance can be checked from the waterfall view in WebPageTest.org. The time taken to download the main document
indicates whether server performance is affecting your page load. Here's an example:&lt;/p&gt;
&lt;p&gt;&lt;img src="/static/images/blog/server-performance-waterfall.jpg" alt="Server Performance Waterfall" style="width: 100%"/&gt;&lt;/p&gt;
&lt;p&gt;The total time taken to download the main document here is over 1.3s. That is not too bad, but it has already used up over half
the 2.5s required to achieve 'Good' for the Largest Contentful Paint (LCP) metric in &lt;a href="/blog/web-vitals/" target="webvitals"&gt;web vitals&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;4. Page Weight&lt;/h2&gt;
&lt;p&gt;Even though internet speeds are getting faster, they are still a limiting factor to how fast a browser can download a page.
If the requested page and the associated resources, eg images, javascript, CSS, are large files, it will take longer
for the browser to download all the required information to display a page. Unoptimised images are a common culprit
for inflating page weight. Unoptimised CMS themes and third party javascript libraries are another.&lt;/p&gt;
&lt;h3&gt;How do I check my page weight?&lt;/h3&gt;
&lt;p&gt;WebPageTest.org reports the page weight in the far right of its summary, circled here:&lt;/p&gt;
&lt;p&gt;&lt;img src="/static/images/blog/page-weight.jpg" alt="Page Weight" style="width: 100%"/&gt;&lt;/p&gt;
&lt;p&gt;You should be aiming for 2mb or less. This particular website is more than a little obese, coming in at around 30mb...
WebPageTest also has a section called 'Content Breakdown' which shows where the weight is, ie in images, javascript, etc.&lt;/p&gt;
&lt;p&gt;&lt;img src="/static/images/blog/content-breakdown.jpg" alt="Content Breakdown" style="width: 100%"/&gt;&lt;/p&gt;
&lt;p&gt;Over 27mb in images is what's weighing down this page.&lt;/p&gt;
&lt;p&gt;Peakhour also has a &lt;a href="https://www.peakhour.io/pages/page-weight" target="pageweight:"&gt;pageweight tool&lt;/a&gt; that you
can run for a page on your website and receive a full optimisation report for the images on the page, along with downloadable
optimised images.&lt;/p&gt;
&lt;h2&gt;5. &lt;a name="blocking"&gt;&lt;/a&gt;Blocking Resources&lt;/h2&gt;
&lt;p&gt;Resources that can block a page include CSS and javascript. When the main HTML page is downloaded and parsed, the browser
will not render anything to the screen until the CSS and javascript files that are referenced are downloaded and parsed.
If your website includes a lot of CSS and javascript, which is not uncommon for pre built themes for CMS's like Wordpress
and Magento, the downloading and parsing of these files can delay the browser from showing any content for several
seconds.&lt;/p&gt;
&lt;h3&gt;How do I identify blocking resources?&lt;/h3&gt;
&lt;p&gt;The easiest way to check is to use &lt;a href="/blog/testing-sitespeed-lighthouse/"&gt;Google Lighthouse&lt;/a&gt;) to identify them for you.
After running the report, go to the opportunities section and expand the 'Eliminate render-blocking resources' section
to see what it finds.&lt;/p&gt;
&lt;p&gt;&lt;img src="/static/images/blog/lighthouse-opportunities.jpg" alt="Lighthouse Opportunities" style="max-width: 100%"/&gt;&lt;/p&gt;
&lt;h2&gt;6. Third Party Resources&lt;/h2&gt;
&lt;p&gt;It is very common for websites to include third party resources. These are files that have to be fetched
from a domain/url other than the one that the page is being requested on. Eg if you are requesting www.domain.com.au,
it might include a resource from a third party, eg www.anotherdomain.com.au. Common third party resources might be
analytics scripts (eg Google analytics), marketing tools (eg Mailchimp)&lt;/p&gt;
&lt;p&gt;This forces the browser to open another connection to the third party. The time taken to do this, combined with the possibility
that the third party might be slow to respond (see latency and server performance above), can often ruin load times. If the
resource in question is also a blocking resource the problem is compounded.&lt;/p&gt;
&lt;h3&gt;Spotting a problem with third party resources&lt;/h3&gt;
&lt;p&gt;WebPageTest has a section 'Domains' which displays all the individual domains that the browser connected to when loading
the page:&lt;/p&gt;
&lt;p&gt;&lt;img src="/static/images/blog/third-party.jpg" alt="Lighthouse Opportunities" style="max-width: 100%"/&gt;&lt;/p&gt;
&lt;p&gt;If your website is requesting resources from more than 10 separate domains then you should consider why that is happening
and whether they are necessary. If you are using external CDNs to load javascript or CSS then you should probably
move them onto your domain.&lt;/p&gt;
&lt;p&gt;Social sharing plugins are notorious for pulling in a lot of resources from external domains. You should replace any share
buttons using external scripts with simple static buttons. It is simple to do, and your website will be much smaller and
faster. By using the javascript shares that social sites prescribe, you are slowing down your website
and allowing third parties to track your clients across the internet.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;There are many factors that can slow down your website, drive away customers, and cost you money. You have to regularly
&lt;a href="/blog/introduction-to-website-performance-testing/"&gt;test your website&lt;/a&gt; to check for issues and address them when you find
them. Next we'll cover what you can do to fix the issues we've mentioned here.&lt;/p&gt;</content><category term="Performance"></category><category term="Web Performance"></category><category term="CDN"></category><category term="Caching"></category><category term="Core Web Vitals"></category><category term="WordPress"></category><category term="Rate Limiting"></category></entry><entry><title>Are Australian Magento Stores Ready For Web Vitals?</title><link href="https://www.peakhour.io/blog/web-vitals-magento-australia/" rel="alternate"></link><published>2020-11-19T13:00:00+11:00</published><updated>2020-11-19T13:00:00+11:00</updated><author><name>AC</name></author><id>tag:www.peakhour.io,2020-11-19:/blog/web-vitals-magento-australia/</id><summary type="html">&lt;p&gt;Are Australian Magento stores prepared for the introduction of Core Web Vitals as a search signal? Read on to find out.&lt;/p&gt;</summary><content type="html">&lt;p&gt;Google recently confirmed that the &lt;a href="/blog/web-vitals/"&gt;Core Web Vitals&lt;/a&gt; will be included as search signals from May 2021. This
means that, all else being equal, sites that score well on the Core Web Vitals are likely to rank ahead of those that don&amp;apos;t.&lt;/p&gt;
&lt;h2&gt;A quick refresher of Web Vitals&lt;/h2&gt;
&lt;p&gt;The Core Web Vitals consist of three metrics, chosen to measure the experience of browsing a website. Here they are, along
with the current thresholds for a 'Good', 'Needs Improvement', or 'Poor' rating:&lt;/p&gt;
&lt;div class="row" style="margin-bottom: 30px"&gt;
    &lt;div class="col-sm-4 text-center"&gt;
        &lt;img src="/static/images/blog/lcp.svg" alt="Largest Contenful Paint" style="max-width: 300px"/&gt;
    &lt;/div&gt;
    &lt;div class="col-sm-4 text-center"&gt;
        &lt;img src="/static/images/blog/fid.svg" alt="[First Input Delay](/solutions/use-case/improve-web-vitals/)" style="max-width: 300px"/&gt;
    &lt;/div&gt;
    &lt;div class="col-sm-4 text-center"&gt;
        &lt;img src="/static/images/blog/cls.svg" alt="Cumulative Layout Shift" style="max-width: 300px"/&gt;
    &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Web Vitals also defines several other metrics, including Time to First Byte (TTFB), and First Contentful Paint (FCP). While these
aren't 'core' metrics, they are useful for diagnosing where performance problems come from. The target TTFB
in the current version of &lt;a href="/blog/testing-sitespeed-lighthouse/"&gt;Google Lighthouse&lt;/a&gt; is listed as 100ms, while poor is 600ms.
FCP is good under 2s and poor over 4s.&lt;/p&gt;
&lt;h2&gt;How will Australian sites fare?&lt;/h2&gt;
&lt;p&gt;We asked a simple question: what percentage of Australian websites are ready for
Web Vitals as a search signal, and what percentage could lose ground? To answer it, we ran them through
our recently released &lt;a href="/pages/website-competitor-speed-test/"&gt;Website Speed Comparison&lt;/a&gt; tool, which gathers Web Vitals metrics
as part of its report.&lt;/p&gt;
&lt;h2&gt;Methodology&lt;/h2&gt;
&lt;p&gt;There are a lot of Australian websites, so we broke the analysis down by technology platform. We started with
online stores running Magento.&lt;/p&gt;
&lt;p&gt;We started with an initial list from BuiltWith of around 4000 domains. We then trimmed it down by removing development
and demo sites, and sites returning an error, leaving a total of 2998. The list includes some of the largest retailers in Australia,
including Harvey Norman, Sportsgirl, Philips and Dyson.&lt;/p&gt;
&lt;p&gt;We then ran our competitor report for &lt;strong&gt;&lt;em&gt;every one of them&lt;/em&gt;&lt;/strong&gt;. The report was run from our Sydney office over a business-class
internet connection. The test throttles the connection to simulate typical 4G mobile phone
speeds, and uses a mobile phone user agent/screen size to view the mobile version of the site. We did not throttle
CPU performance like Lighthouse does.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt; We're excluding First Input Delay in our results as Google defines First Input Delay (FID)
as a real user measurement (RUM). FID measures the time taken for the website to respond to the first
user interaction, such as clicking a link or button. Technically this interaction can happen any time after the first content
appears in the browser; in practice, most people won't click something until after a page is visually complete,
and this timing is highly variable. We do measure First Input Delay by simulating a click, but our interaction
happens soon after the FCP, while content is still loading. That would cause more sites to fail the metric
than would fail in real life, so we're excluding it from our calculations.&lt;/p&gt;
&lt;p&gt;On to the results. We did not expect strong numbers, but the results were still worse than expected.&lt;/p&gt;
&lt;h2&gt;The results&lt;/h2&gt;
&lt;p&gt;The first check was for the number of websites that achieve a good rating in any of the Web Vitals metrics.&lt;/p&gt;
&lt;table class="table"&gt;
    &lt;td colspan="5" style="text-align: center"&gt;
        &lt;em&gt;Percentage of sites that are 'Good'&lt;/em&gt;
    &lt;/td&gt;
&lt;tr&gt;
    &lt;th&gt;&lt;/th&gt;
    &lt;th&gt;TTFB (&lt; 0.1s)&lt;/th&gt;
    &lt;th&gt;FCP (&lt; 1s)&lt;/th&gt;
    &lt;th&gt;LCP (&lt; 2.5s)&lt;/th&gt;
    &lt;th&gt;CLS (&lt;.1)&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
    &lt;th&gt;Result&lt;/th&gt;
    &lt;td&gt;99 (3.3%)&lt;/td&gt;
    &lt;td&gt;71 (2.37%)&lt;/td&gt;
    &lt;td&gt;254 (8.47%)&lt;/td&gt;
    &lt;td&gt;1074 (35.8%)&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;CLS was the strongest result, which isn't a surprise. The remaining results are not encouraging: only 8.5% pass LCP. Let's
see how many need improvement.&lt;/p&gt;
&lt;table class="table"&gt;
&lt;tr&gt;
    &lt;td colspan="5" style="text-align: center;"&gt;
        &lt;em&gt;Percentage of sites that 'Needs Improvement'&lt;/em&gt;
    &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
    &lt;th&gt;&lt;/th&gt;
    &lt;th&gt;TTFB (&lt; 0.6s)&lt;/th&gt;
    &lt;th&gt;FCP (&lt; 2s)&lt;/th&gt;
    &lt;th&gt;LCP (&lt; 4s)&lt;/th&gt;
    &lt;th&gt;CLS (&lt; .25)&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
    &lt;th&gt;Result&lt;/th&gt;
    &lt;td&gt;383 (12.7%)&lt;/td&gt;
    &lt;td&gt;728 (24.3%)&lt;/td&gt;
    &lt;td&gt;470 (15.7%)&lt;/td&gt;
    &lt;td&gt;625 (20.8%)&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;An additional 15.7% beat the 4s cut-off for LCP. That still means that 3/4 of Australian Magento
stores take longer than 4s to visually load on a mobile device. Visualised, the numbers are not pretty.&lt;/p&gt;
&lt;p&gt;&lt;img src="/static/images/blog/magento-web-vitals.svg" style="width: 100%"/&gt;&lt;/p&gt;
&lt;p&gt;Australian Magento sites are likely missing potential sales. Recent performance studies show:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The probability of a customer bouncing increases 90% if the page load time increases from 1s to 5s. &lt;em&gt;(source Google)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;A 100 millisecond delay in load time can hurt conversion rates by 7%. &lt;em&gt;(source Akamai)&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The experience of our own &lt;a href="/case-studies/ecsso/"&gt;Magento 1 clients&lt;/a&gt; and &lt;a href="/case-studies/savvysupporter/"&gt;Magento 2 clients&lt;/a&gt;
backs this up: improving website speed affects conversions and revenue.&lt;/p&gt;
&lt;h2&gt;Sites that pass all criteria&lt;/h2&gt;
&lt;p&gt;Of our 2998 websites, we only found &lt;strong&gt;163&lt;/strong&gt; that &lt;a href="/learning/performance/how-to-pass-core-web-vitals/"&gt;pass Core&lt;/a&gt; Web Vital &lt;em&gt;'good'&lt;/em&gt; criteria. That's only &lt;strong&gt;5.5%&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;If we again relax to include &lt;em&gt;'needs improvement'&lt;/em&gt; that list grows to &lt;strong&gt;520&lt;/strong&gt;, or &lt;strong&gt;17.3%&lt;/strong&gt; of sites tested.&lt;/p&gt;
&lt;h2&gt;How you can test your site&lt;/h2&gt;
&lt;p&gt;Google provides online analytics that you can query via BigQuery. If you want to reproduce the report this analysis
is based on and compare your website to your competitors, you can use the Peakhour.IO &lt;a href="/pages/website-competitor-speed-test/"&gt;Website Speed Comparison report&lt;/a&gt;.
We automatically discover your competitors, run them through Web Vitals, and graph the results.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;If nothing changes, quite a few Australian Magento stores could lose search visibility in May 2021. The majority of sites don't
use Magento 2's ability to &lt;a href="/dynamic-content-caching/"&gt;cache dynamic pages&lt;/a&gt;, and if they do, they're often not
&lt;a href="/image-optimisation/"&gt;serving optimal images&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Core Web Vitals becomes a search signal next year. For Magento teams, it is time to get ready.&lt;/p&gt;</content><category term="Performance"></category><category term="Core Web Vitals"></category><category term="Magento"></category><category term="Web Performance"></category><category term="CDN"></category><category term="Drupal"></category></entry><entry><title>Test Your Website Performance With Google Lighthouse</title><link href="https://www.peakhour.io/blog/testing-sitespeed-lighthouse/" rel="alternate"></link><published>2020-09-14T13:00:00+10:00</published><updated>2020-09-14T13:00:00+10:00</updated><author><name>Dan</name></author><id>tag:www.peakhour.io,2020-09-14:/blog/testing-sitespeed-lighthouse/</id><summary type="html">&lt;p&gt;This installment on website performance introduces Google Lighthouse as a measuring tool. Read on to see how we use it here at Peakhour.&lt;/p&gt;</summary><content type="html">&lt;p&gt;Today we're introducing our other favourite tool for testing website performance: Google Lighthouse &lt;em&gt;(from here we'll just
call it Lighthouse)&lt;/em&gt;. Lighthouse measures page experience across accessibility, performance, SEO, and
Progressive Web Apps for desktop and mobile devices.&lt;/p&gt;
&lt;p&gt;Lighthouse is the engine behind web.dev/measure and PageSpeed Insights. It is also available in Chrome DevTools,
via npm, or as a browser extension in Chrome and Firefox. At time of writing Lighthouse is up to version 6, which introduced
&lt;a href="/blog/web-vitals/"&gt;Web Vitals&lt;/a&gt; as the basis for &lt;a href="https://googlechrome.github.io/lighthouse/scorecalc/"&gt;scoring&lt;/a&gt;.
If you are unsure which version of the tool you are using, then scroll right to the bottom of the report it generates
where it will state the version.&lt;/p&gt;
&lt;p&gt;Lighthouse generates its report by simulating a specific device and network speed, rather than running at the full speed
of your computer. That matters because speed issues are more noticeable on slower devices, and users are not all on newer
devices or fast internet connections. You should test for a good load experience across that range.
The current simulated mobile device is a Moto G4 on a ~1.5 megabit connection. For reference, it would take over 5s to
download 1mb of data at this speed. If your page weight is typical, ie over 2.5mb, you should not expect a strong score.&lt;/p&gt;
&lt;h2&gt;How to use Google Lighthouse&lt;/h2&gt;
&lt;p&gt;There are two ways you can run a Google Lighthouse report:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;In your local browser;&lt;/li&gt;
&lt;li&gt;Online via web.dev/measure or PageSpeed Insights.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;We recommend running Google Lighthouse in your local browser because the online versions operate out of the US. If your website
and customers are elsewhere, that extra network latency can pull the score down.&lt;/p&gt;
&lt;p&gt;Here we'll focus on running Lighthouse from within Chrome DevTools.
To do this, click on the three vertical dots in the top right-hand corner, then select 'More Tools', then 'Developer Tools'.&lt;/p&gt;
&lt;p&gt;&lt;img src="/static/images/blog/dev-tools.jpg" alt="open dev tools" style="max-width: 100%"/&gt;&lt;/p&gt;
&lt;p&gt;The developer tools will then be displayed. Along the top of the tools window are a number of tabs. Select the 'Lighthouse'
tab.&lt;/p&gt;
&lt;p&gt;&lt;img src="/static/images/blog/dev-tools-2.jpg" alt="open lighthouse tab" style="max-width: 100%"/&gt;&lt;/p&gt;
&lt;p&gt;Since we're only interested in performance, make sure only the Performance category is ticked. You also want to make sure
'Clear storage' is ticked &lt;em&gt;(in the top left)&lt;/em&gt; to simulate a first load of your site. Finally, choose the device you want
to report on, mobile or desktop, and click 'Generate report'.&lt;/p&gt;
&lt;p&gt;While the report is being generated, avoid doing anything else on your computer, and don't leave it busy with background
tasks. Otherwise, the score can be affected.&lt;/p&gt;
&lt;h2&gt;Understanding the Score&lt;/h2&gt;
&lt;p&gt;Once the report has finished you'll see a performance summary, like this mobile one we ran on Peakhour.io while we
were developing the website:&lt;/p&gt;
&lt;p&gt;&lt;img src="/static/images/blog/lighthouse-score-summary.jpg" alt="open lighthouse tab" style="max-width: 100%"//&gt;&lt;/p&gt;
&lt;p&gt;Scoring in version 6 is based on Google's &lt;a href="/blog/web-vitals/"&gt;web vitals&lt;/a&gt;, which are metrics that indicate a good user
experience, and Webpagetest's speed index, which measures visual loading performance.
Each metric is colour coded as good, ok, or bad. If the measurement is good you get a green
circle to the left, if it's ok you get an orange square, if it is bad you get a red triangle.&lt;/p&gt;
&lt;p&gt;Each raw metric &lt;em&gt;(the number listed in the report)&lt;/em&gt; is compared to real website performance data sourced from the
&lt;a href="https://httparchive.org/"&gt;HTTP archive&lt;/a&gt; and converted into a score out of 100. This is done by grading the reference data
on a curve, so if your website performs in the top 8% of websites, it gets a score of 90. Similarly, if it scores in the top 25%, it
gets a score of 50. If you are interested in the technical details, Google has in-depth explanations of the scoring at
&lt;a href="https://web.dev/performance-scoring/"&gt;web.dev&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Each metric is assigned a weight, and the scores are tallied into one overall number based on the weighting. Here is a
breakdown of the test we just ran &lt;em&gt;(in the screen shot above)&lt;/em&gt;, obtained by clicking on the 'See Calculator' link between
the Metrics section and the screen shots:&lt;/p&gt;
&lt;p&gt;&lt;img src="/static/images/blog/lighthouse-calculator.jpg" alt="open lighthouse tab" style="max-width: 100%"//&gt;&lt;/p&gt;
&lt;h3&gt;Score Variability&lt;/h3&gt;
&lt;p&gt;79 is a good result for a mobile device. However, we ran it several times and obtained scores between 60 on the low end
and 85 on the high end. Scores can fluctuate widely, even when testing on the same device repeatedly. Reasons for this
include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Small differences in internet performance.&lt;/li&gt;
&lt;li&gt;Your computer CPU load when performing the test.&lt;/li&gt;
&lt;li&gt;Web server variability.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Again, Google has &lt;a href="https://github.com/GoogleChrome/lighthouse/blob/master/docs/variability.md"&gt;in-depth documentation&lt;/a&gt; around what
might be causing this.&lt;/p&gt;
&lt;h2&gt;Opportunities&lt;/h2&gt;
&lt;p&gt;If your site loads slowly then Lighthouse will list addressable reasons in the opportunities section of the report.&lt;/p&gt;
&lt;p&gt;&lt;img src="/static/images/blog/lighthouse-opportunities.jpg" alt="Lighthouse Opportunities" style="max-width: 100%"/&gt;&lt;/p&gt;
&lt;p&gt;This is the part we generally find most useful. It identifies items that slow the initial load and items that
affect the rendering of a website once it is downloaded. A page can be downloaded very quickly, but the end user still sees a slow site
because CSS and Javascript are blocking rendering. This is a common problem in Wordpress and Magento themes.
These themes include large amounts of third party code that ultimately never gets used for a particular site, but which
the browser still has to download and parse before it can display anything.&lt;/p&gt;
&lt;p&gt;In this case, the main bottleneck appears to be a font loaded from Google Fonts. This is delaying the rendering of our
page by 1.3s.&lt;/p&gt;
&lt;h2&gt;Diagnostics&lt;/h2&gt;
&lt;p&gt;The diagnostics section provides additional information you can use to improve load times.&lt;/p&gt;
&lt;p&gt;&lt;img src="/static/images/blog/lighthouse-diagnostics.jpg" alt="Lighthouse Diagnostics" style="max-width: 100%"/&gt;&lt;/p&gt;
&lt;p&gt;Here we have a few small problems, mainly associated with the development status of our site.&lt;/p&gt;
&lt;h2&gt;web.dev and PageSpeed Insights&lt;/h2&gt;
&lt;p&gt;If you do choose to run your report online, we recommend using &lt;a href="https://developers.google.com/speed/pagespeed/insights/"&gt;PageSpeed Insights&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In addition to the generated report, PageSpeed Insights also shows you &lt;strong&gt;Field Data&lt;/strong&gt; for the page you are testing,
and an &lt;strong&gt;Origin Summary&lt;/strong&gt; for all pages on the website.&lt;/p&gt;
&lt;p&gt;&lt;img src="/static/images/blog/page-speed-insights-field-data.jpg" alt="Page Speed Insights Field Data" style="max-width: 100%"/&gt;&lt;/p&gt;
&lt;p&gt;This is real-world data gathered from Chrome users who have
opted in to allowing Google to gather their data. If your site isn't very busy then Google might not have any data to
share. It is not truly representative, but it is useful information and can often tell a very different story
to your Lighthouse score.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;Regular measurement matters because performance issues are often specific and easy to miss. Lighthouse is useful for
identifying issues that affect website performance, and when used in conjunction with
&lt;a href="/blog/testing-website-speed-webpagetest/"&gt;Webpagetest.org&lt;/a&gt;, you'll be in a better position to provide a good experience
for your users. Next we'll cover &lt;a href="/blog/common-issues-that-impact-site-speed/"&gt;common issues that can impact site speed&lt;/a&gt;,
so read on.&lt;/p&gt;</content><category term="Performance"></category><category term="Web Performance"></category><category term="Analytics"></category><category term="Core Web Vitals"></category><category term="Caching"></category><category term="Rate Limiting"></category><category term="Browser Fingerprinting"></category></entry><entry><title>Website Performance testing with WebPageTest.org</title><link href="https://www.peakhour.io/blog/testing-website-speed-webpagetest/" rel="alternate"></link><published>2020-09-13T13:00:00+10:00</published><updated>2026-07-06T13:00:00+10:00</updated><author><name>Dan</name></author><id>tag:www.peakhour.io,2020-09-13:/blog/testing-website-speed-webpagetest/</id><summary type="html">&lt;p&gt;In this installment of our website performance series we're taking a look at webpagetest.org, one of the best tools you can use to analyse real world performance of your website.&lt;/p&gt;</summary><content type="html">&lt;p&gt;WebPageTest is one of our favourite tools for measuring website performance:
&lt;a href="https://www.webpagetest.org"&gt;webpagetest.org&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;WebPageTest is a web page performance testing tool developed by AOL and open-sourced in 2008. It produces its metrics
using real-world browsers to load the web page being tested. It's actively maintained by Google on GitHub, so you can download
and install it on your own server if you prefer. It is also free.&lt;/p&gt;
&lt;p&gt;The key advantage of WebPageTest is that tests can be run from locations around the world, using real browsers at actual
connection speeds. That lets you test performance where your users are, and see real load times rather than arbitrary
scores out of 100. You can run simple tests, advanced multi-step tests, video capture, content blocking, multi-site visual
comparisons, and traceroute testing.
While this is still a synthetic test, it is about as close to real-world performance measurement as you can get without using
RUM.&lt;/p&gt;
&lt;p&gt;Use WebPageTest when you need to understand why a page is slow. Use the &lt;a href="/blog/what-is-the-chrome-ux-report-crux/"&gt;Chrome UX Report&lt;/a&gt; when you need to know how real Chrome users experienced the page over time. Use Peakhour's &lt;a href="/pages/website-competitor-speed-test/"&gt;website speed comparison tool&lt;/a&gt; when you want a fast comparison between your domain and competitor domains using CrUX field data.&lt;/p&gt;
&lt;h2&gt;Running a Simple Test&lt;/h2&gt;
&lt;p&gt;&lt;img src="/static/images/blog/webpagetest.jpg" alt="webpagetest home" width="100%"/&gt;&lt;/p&gt;
&lt;p&gt;To run a simple test:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Visit &lt;a href="https://www.webpagetest.org"&gt;webpagetest.org&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Enter the URL of the page that you want to test in the 'Enter a Website URL' field. We usually enter only the domain
    name, with no www and no https:// at the front. This simulates someone typing your domain into a browser address bar
    and captures how much time any redirects add to the page load. Sometimes redirects can be very slow.&lt;/li&gt;
&lt;li&gt;Select the location of the test from the 'Test Location' drop down. Choose locations that reflect where your users
    are. &lt;em&gt;Note Australian locations are at the very bottom.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Choose the browser to run the test from. Chrome is the default.&lt;/li&gt;
&lt;li&gt;Press 'Start Test'&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;em&gt;Note there are advanced options but for simple testing you don't need to change these.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The test will perform three visits to the specified page, with the browser cache cleared in between each visit. This simulates
someone visiting your site for the first time, including the parts of the page load that only happen on an uncached visit.&lt;/p&gt;
&lt;h2&gt;Interpreting the results.&lt;/h2&gt;
&lt;h3&gt;A,B,C's&lt;/h3&gt;
&lt;p&gt;The results page has a summary section at the top giving you summary grades for several categories. Here's a sample report
using our website, peakhour.io. Take note of the sections at the bottom, because we'll refer to them later.&lt;/p&gt;
&lt;p&gt;&lt;img src="/static/images/blog/webpagetest-abc.jpg" alt="webpagetest performance grades" width="100%"/&gt;&lt;/p&gt;
&lt;p&gt;While this section isn't representative of performance it can still give you actionable information. Here's a summary of
the information (ignoring security since we're concerned with speed):&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;First Byte Time&lt;/strong&gt;: How long it takes the server to respond to the browser request with the first byte of information.
This is the same as the Web Vital Time To First Byte (TTFB).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Keep Alive Enabled&lt;/strong&gt;: A server option that leaves the connection from the browser to the server open for a short time,
usually a few seconds, after the server has finished transmitting a request. This allows the browser to reuse a connection
and saves time because it does not need to reconnect as often.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Compress Transfer&lt;/strong&gt;: When files are transferred from the server they are compressed, usually via gzip, to make sure
transfer sizes are as small as possible. &lt;em&gt;It looks like we have a problem here.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Compress Images&lt;/strong&gt;: Images are usually the largest part of a web page by transfer size. Making sure they're well
compressed is important for fast sites.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cache Static Content&lt;/strong&gt;: Checks that static files, e.g. JavaScript, CSS, and images, have appropriate cache headers so your
browser doesn't re-fetch them every time it views a page. &lt;em&gt;We're developing our site so have caching turned off at the
moment, hence the bad score&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Effective Use of CDN&lt;/strong&gt;: Detects whether your website is using a CDN known by WebPageTest.&lt;/p&gt;
&lt;p&gt;This report points to problems with transfer compression and static content caching.&lt;/p&gt;
&lt;h3&gt;Performance Metrics (The Important Stuff)&lt;/h3&gt;
&lt;p&gt;The next section summarises the key performance metrics of the page load. Google's
&lt;a href="/blog/web-vitals/"&gt;web vitals&lt;/a&gt; are represented alongside lab metrics such as speed index, total blocking time, and
page weight.&lt;/p&gt;
&lt;p&gt;&lt;img src="/static/images/blog/webpagetest-summary.jpg" alt="webpagetest summary" width="100%"/&gt;&lt;/p&gt;
&lt;p&gt;Despite some poor marks in the grading section, the peakhour.io website loads very quickly. Its Largest
Contentful Paint (LCP) is less than 1s, well below Google's 2.5s target for a good result.
We've already covered them in our &lt;a href="/blog/web-vitals/"&gt;web vitals&lt;/a&gt;, which also defines ideal
values for each metric, so we won't cover them again here. One detail worth noting is that &lt;strong&gt;Total Blocking Time&lt;/strong&gt; is still a useful lab signal for main-thread blocking. It is not the same as &lt;strong&gt;Interaction to Next Paint&lt;/strong&gt;, because INP is measured from real user interactions in the field, but it helps identify JavaScript and third-party work that can harm responsiveness.&lt;/p&gt;
&lt;h3&gt;The Detail Section&lt;/h3&gt;
&lt;p&gt;Remember the sections immediately below the grade summaries? Now we're going to click on the &lt;strong&gt;'Details'&lt;/strong&gt; section. The
part we want to highlight here is the &lt;strong&gt;Waterfall&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src="/static/images/blog/webpagetest-waterfall-key.jpg" alt="webpagetest waterfall key" width="100%"/&gt;&lt;/p&gt;
&lt;p&gt;At the top of the waterfall chart is a colour key for reading the diagram. The key concepts are:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;dns (Dark Green)&lt;/strong&gt;: This measures the time it takes for the browser to look up the location of your server.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;connect (Orange)&lt;/strong&gt;: This measures the time taken to establish the TCP connection to download a resource. It should only
appear on the first resource for a given host. Remember the keep-alives grade: if that is turned off, there will be
more connections here.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ssl (Dark Purple)&lt;/strong&gt;: Any resources that are loading from a secure website will need to be processed as such – the
purple will signify how long it is taking to connect to that SSL item.&lt;/p&gt;
&lt;h4&gt;The Waterfall View&lt;/h4&gt;
&lt;p&gt;The waterfall is an easy-to-read view of how your website loads, with all
the resources listed in the order they're requested, along with the time taken to load each resource. You can click on
any resource to view the request/response headers, file size, protocol and more.&lt;/p&gt;
&lt;p&gt;&lt;img src="/static/images/blog/webpagetest-waterfall.jpg" alt="webpagetest waterfall" width="100%"/&gt;&lt;/p&gt;
&lt;p&gt;In the example above the first line has a yellow background, which signifies a redirect. The three lines towards the bottom
with red backgrounds signify 404 not found errors, which need to be fixed. The colourful vertical lines indicate
where major load events, like first paint and document loaded, happen.&lt;/p&gt;
&lt;p&gt;The other thing to look for is any resource that takes a long time to load. In our example the 2nd row, which
is the main HTML document, only took 149ms, which is fast. A lot of websites take 2-5s to load the main document,
putting the user experience under pressure before the rest of the page has started. The main concerns here are
rows 27 and 28: two SVG images that took around three quarters of a second to load.&lt;/p&gt;
&lt;h3&gt;The Performance Review Section&lt;/h3&gt;
&lt;p&gt;The final section we're going to cover is the &lt;strong&gt;Performance Review&lt;/strong&gt; section.&lt;/p&gt;
&lt;p&gt;&lt;img src="/static/images/blog/webpagetest-details.jpg" alt="webpagetest details" width="100%"/&gt;&lt;/p&gt;
&lt;p&gt;This section gives more detail for the performance grades at the top of the report. In the earlier example Peakhour.io
scored poorly for &lt;strong&gt;Compress Transfer&lt;/strong&gt; and now we can see why: we're not compressing SVG images, something that can
save 234kb of file downloads.&lt;/p&gt;
&lt;h2&gt;Summary&lt;/h2&gt;
&lt;p&gt;WebPageTest gives you enough detail to see where a page is losing time, not just whether it passed a headline score.
There is more in the tool than we've covered here, but this is enough to test a website, read the main report sections,
and identify practical issues to fix. If you are starting with a market view rather than a single waterfall, compare your field data first with the &lt;a href="/pages/website-competitor-speed-test/"&gt;website speed comparison tool&lt;/a&gt;, then come back to WebPageTest for the diagnostic pass.&lt;/p&gt;</content><category term="Performance"></category><category term="Web Performance"></category><category term="Core Web Vitals"></category><category term="Analytics"></category><category term="Caching"></category><category term="Bot Management"></category><category term="Drupal"></category></entry><entry><title>Core Web Vitals Optimisation</title><link href="https://www.peakhour.io/blog/web-vitals/" rel="alternate"></link><published>2020-09-11T13:00:00+10:00</published><updated>2020-09-11T13:00:00+10:00</updated><author><name>Dan</name></author><id>tag:www.peakhour.io,2020-09-11:/blog/web-vitals/</id><summary type="html">&lt;p&gt;Comprehensive guide to Core Web Vitals optimisation with integrated security. Learn how modern application security platforms improve both performance metrics and protection whilst boosting search rankings and user experience.&lt;/p&gt;</summary><content type="html">&lt;p&gt;A good &lt;a href="/learning/crux-chrome-user-experience/"&gt;user experience&lt;/a&gt; matters for any website.
It matters to users, and Google also
measures aspects of the user experience when ranking your website in its organic results.&lt;/p&gt;
&lt;p&gt;Google ranks websites and pages in its search results using 'search signals'.
These signals include the quality of content on a page, the number of sites linking to that page, and the
experience of the user browsing the site. Factors that make up a great experience include ease of use,
accessibility, speed and responsiveness.&lt;/p&gt;
&lt;p&gt;The set of search signals that Google uses to measure user experience beyond a page's content value is called
&lt;a href="https://developers.google.com/search/docs/guides/page-experience"&gt;'Page experience'&lt;/a&gt;. Google updated
the Page Experience signals with metrics called Web Vitals.&lt;/p&gt;
&lt;p&gt;For years, performance testing used different proxies to determine whether a website was fast. Browser events like
'Page Load' or 'Dom Load' were used before it was realised that these do not necessarily reflect what an end user
experiences. Testing then fragmented, with different teams focusing on the measures they considered important. Web Vitals is
Google's performance testing initiative to provide &lt;strong&gt;&lt;em&gt;"unified guidance for quality signals
that they believe are essential to delivering a great user experience on the web."&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The 'Core' Web Vitals join the existing search signals: mobile-friendliness, safe-browsing, HTTPS, and no intrusive
interstitials as seen in the graphic below from Google.&lt;/p&gt;
&lt;p&gt;&lt;img src="/static/images/blog/page-experience-signals.jpg" width="100%" alt="Page Experience Signals"/&gt;&lt;/p&gt;
&lt;h2&gt;Understanding the Core Web Vitals&lt;/h2&gt;
&lt;div class="mb-10 sm:grid sm:grid-cols-3"&gt;
    &lt;div class="text-center"&gt;
        &lt;img src="/static/images/blog/lcp.svg" alt="Largest Contenful Paint" style="max-width: 300px"/&gt;
    &lt;/div&gt;
    &lt;div class="text-center"&gt;
        &lt;img src="/static/images/blog/fid.svg" alt="First Input Delay" style="max-width: 300px"/&gt;
    &lt;/div&gt;
    &lt;div class="text-center"&gt;
        &lt;img src="/static/images/blog/cls.svg" alt="Cumulative Layout Shift" style="max-width: 300px"/&gt;
    &lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Before diving in, it is worth noting that the metrics that make up Core Web Vitals are expected to
&lt;a href="https://web.dev/vitals/#evolving-web-vitals"&gt;evolve&lt;/a&gt; over time. Google states that
&lt;strong&gt;&lt;em&gt;"these signals are not perfect and future improvements or additions should be expected."&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;Largest Contentful Paint (LCP)&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://web.dev/lcp/"&gt;Largest Contentful Paint (LCP)&lt;/a&gt; measures when the "largest", or "main" piece of content has completely
loaded and is visible, usually a hero image. Content refers to text, foreground images, background images, and elements. LCP
complements First Contentful Paint (FCP), a metric that marks the initial web page loading experience. LCP calculates
how quickly a user can see page content. Scores below 2.5 seconds are considered in the 'Good' range.&lt;/p&gt;
&lt;h3&gt;First Input Delay (FID) (Due to be replaced March 2024 by &lt;a href="/blog/interaction-to-next-paint/"&gt;Interaction to Next Paint (INP)&lt;/a&gt;)&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://web.dev/lcp/"&gt;First Input Delay (FID)&lt;/a&gt; measures page interactivity: how long it takes for a page
to respond to input from the user, such as a key press or a mouse click. Low FID
scores ensure pages are usable. FID is a real-world metric that cannot be measured in the lab. The Total Blocking
Time (TBT) metric found in Lighthouse is lab-measurable and correlates with FID to simulate real-world interactivity.&lt;/p&gt;
&lt;h3&gt;Cumulative Layout Shift (CLS)&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://web.dev/cls/"&gt;Cumulative Layout Shift (CLS)&lt;/a&gt; measures visual stability while the page is loading. This means
that once displayed, a piece of content stays where it is; it does not jump around the screen as other content
loads. Lower CLS scores mean that users are not experiencing unnecessary
content shifts. CLS scores below 0.10 are 'Good'.&lt;/p&gt;
&lt;h2&gt;Understanding the rest of the Web Vitals&lt;/h2&gt;
&lt;p&gt;The Web Vitals metrics that are not part of the Core Web Vitals are &lt;strong&gt;&lt;em&gt;Time to First Byte
(TTFB)&lt;/em&gt;&lt;/strong&gt;, and &lt;strong&gt;&lt;em&gt;First Contentful Paint (FCP)&lt;/em&gt;&lt;/strong&gt;. They provide additional ways to
improve a web user’s experience, and help diagnose specific issues, either in the lab or in the field.&lt;/p&gt;
&lt;h3&gt;Time to First Byte (TTFB)&lt;/h3&gt;
&lt;p&gt;Time to First Byte is the time it takes for a user's browser to receive the first byte of page content.&lt;/p&gt;
&lt;h3&gt;First Contentful Paint (FCP)&lt;/h3&gt;
&lt;p&gt;First Contentful Paint (FCP) &lt;strong&gt;&lt;em&gt;"measures the point from when a web page starts loading to when ANY
content starts rendering on screen."&lt;/em&gt;&lt;/strong&gt; The term 'Content' means text, images, &amp;lt;svg&amp;gt; elements,
or non-white &amp;lt;canvas&amp;gt; elements. Just remember that FCP can be triggered
very early in the page load, but may not necessarily deliver any visible content or information to the user.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Web Vitals are Google's attempt to unify the metrics webmasters use to measure the Page Experience of their
site. With Core Vitals included in the ranking signals, site owners can see which performance measures Google treats as
important. Measuring performance is the topic of our next few posts.&lt;/p&gt;</content><category term="Performance"></category><category term="Core Web Vitals"></category><category term="SEO"></category><category term="Web Performance"></category><category term="Analytics"></category><category term="Drupal"></category><category term="Caching"></category></entry><entry><title>Is your website obese?</title><link href="https://www.peakhour.io/blog/website-obesity-reducing-page-weight/" rel="alternate"></link><published>2020-03-19T13:00:00+11:00</published><updated>2020-03-19T13:00:00+11:00</updated><author><name>Dan</name></author><id>tag:www.peakhour.io,2020-03-19:/blog/website-obesity-reducing-page-weight/</id><summary type="html">&lt;p&gt;An introduction to page weight, what it is and how you can reduce it.&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;a href="/learning/page-weight/"&gt;Page weight&lt;/a&gt; has increased steadily since the early web, as connection speeds improved and sites became more interactive
and visually rich. The HTTP Archive shows over a &lt;strong&gt;300% increase&lt;/strong&gt; over the last 10 years.&lt;/p&gt;
&lt;div style="width: 100%;text-align: center"&gt;
    &lt;div style="display: inline-block; padding: 20px"&gt;
        &lt;strong&gt;MEDIAN DESKTOP&lt;/strong&gt;&lt;br/&gt;
        1957.8 KB&lt;br/&gt;
        ▲318.6%
    &lt;/div&gt;
    &lt;div style="display: inline-block; padding: 20px"&gt;
        &lt;strong&gt;MEDIAN MOBILE&lt;/strong&gt;&lt;br/&gt;
        1791.9 KB&lt;br/&gt;
        ▲1137.5%
    &lt;/div&gt;
    &lt;div markdown="1"&gt;
        &lt;img src="/static/images/blog/page-weight.jpg" alt="Page weight historical"/&gt;
    &lt;/div&gt;
&lt;/div&gt;

&lt;h2&gt;Why should I care?&lt;/h2&gt;
&lt;h3&gt;Smaller page weight = Faster page load&lt;/h3&gt;
&lt;p&gt;Page weight directly affects page load times. The smaller the page, the faster your site can load. The slower the connection, the more
obvious the effect. Faster page loads are associated with higher conversion rates, fewer bounces, and higher engagement with your
site.&lt;/p&gt;
&lt;h3&gt;Smaller page weight = Less bandwidth = Savings&lt;/h3&gt;
&lt;p&gt;Your hosting provider or CDN may charge for data transfer. Reducing page size can reduce those costs.&lt;/p&gt;
&lt;h2&gt;How big is too big?&lt;/h2&gt;
&lt;p&gt;Google says that, to meet its best practice guidelines, you should aim for a page weight of 500 KB on mobile devices and a request count of
fewer than 50.&lt;/p&gt;
&lt;h2&gt;What can I do to shrink my page weight?&lt;/h2&gt;
&lt;p&gt;Start with the bytes that browsers have to download, parse, and render.&lt;/p&gt;
&lt;h3&gt;1. Optimise Images&lt;/h3&gt;
&lt;p&gt;Images are often the biggest contributors to page weight. Careful optimisation can reduce their size without a noticeable loss in quality.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Compression:&lt;/strong&gt; Use image compression tools to reduce file sizes. For JPEGs, a quality setting of 75-85% is often a practical balance.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use Next-Gen Formats:&lt;/strong&gt; Formats like WebP and AVIF compress better than older formats like JPEG and PNG. Modern browsers have wide support for them.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Responsive Images:&lt;/strong&gt; Use the &lt;code&gt;&amp;lt;picture&amp;gt;&lt;/code&gt; element or &lt;code&gt;srcset&lt;/code&gt; attribute to serve different image sizes for different screen resolutions. There is no reason to send a large desktop image to a mobile phone.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Lazy Loading:&lt;/strong&gt; Load images only when they are about to enter the viewport. This does not reduce total page weight, but it improves the initial load time.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. Minify CSS, JavaScript, and HTML&lt;/h3&gt;
&lt;p&gt;Minification removes unnecessary characters from source code without changing its functionality. That includes white space, comments, and line breaks. Many build tools, including Webpack, and CMS plugins can automate this process.&lt;/p&gt;
&lt;h3&gt;3. Enable Server-Side Compression&lt;/h3&gt;
&lt;p&gt;Enabling compression like Gzip or Brotli on your web server can reduce the size of the HTML, CSS, and JavaScript files sent to the browser. Brotli offers better compression than Gzip and is supported by all modern browsers.&lt;/p&gt;
&lt;h3&gt;4. Leverage Browser Caching&lt;/h3&gt;
&lt;p&gt;Set appropriate &lt;code&gt;Cache-Control&lt;/code&gt; and &lt;code&gt;Expires&lt;/code&gt; headers so the browser can store files locally. On later visits, the user's browser can load those files from its local cache instead of downloading them again, making return visits much faster.&lt;/p&gt;
&lt;h3&gt;5. Remove Unused Code&lt;/h3&gt;
&lt;p&gt;Many websites, especially those built on complex themes or frameworks, load large CSS and JavaScript files with code that is never used. Use browser developer tools, such as the Coverage tab in Chrome DevTools, to identify and remove unused code. For JavaScript builds, this process is often called "tree-shaking," and it can significantly shrink your file sizes.&lt;/p&gt;
&lt;h3&gt;6. Use a Content Delivery Network (CDN)&lt;/h3&gt;
&lt;p&gt;A CDN stores copies of your assets on servers around the world. When a user visits your site, those assets are served from the server closest to them, reducing latency. Many CDNs also provide automatic optimisation features such as image compression and minification.&lt;/p&gt;
&lt;h2&gt;Final Thoughts&lt;/h2&gt;
&lt;p&gt;Reducing page weight is ongoing work. A lighter, faster website gives users less to wait for, improves search engine rankings and conversion rates, and reduces the amount of data you have to serve. Start with images, compression, caching, and unused code; those changes usually give you the clearest wins.&lt;/p&gt;</content><category term="Learning"></category><category term="Web Performance"></category><category term="Core Web Vitals"></category><category term="Caching"></category></entry><entry><title>Instant Alerts</title><link href="https://www.peakhour.io/blog/instant-alerts/" rel="alternate"></link><published>2019-05-31T13:00:00+10:00</published><updated>2019-05-31T13:00:00+10:00</updated><author><name>Dan</name></author><id>tag:www.peakhour.io,2019-05-31:/blog/instant-alerts/</id><summary type="html">&lt;p&gt;Introducing Instant Alerts, a new feature for receiving emails or SMS alerts when events happen on your site.&lt;/p&gt;</summary><content type="html">&lt;p&gt;We've introduced Instant Alerts, an optional service that notifies you when there is a problem with your site. You can specify the email addresses and/or mobile numbers that should receive the alerts.&lt;/p&gt;
&lt;p&gt;At the moment you can receive alerts when your origin server:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Times out&lt;/li&gt;
&lt;li&gt;Cannot be reached at all&lt;/li&gt;
&lt;li&gt;Returns an error&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;To avoid repeated messages, each alert has a cooldown limit you can set from 30 minutes to 24 hours.&lt;/p&gt;
&lt;p&gt;If you're using a service like Pingdom to check that your site is up, you probably will want to enable Instant Alerts.
Services like Pingdom might be served pages from our cache while your origin server is actually down.&lt;/p&gt;</content><category term="Features"></category><category term="DDoS"></category><category term="Threat Detection"></category><category term="DNS"></category><category term="CDN"></category><category term="Web Performance"></category></entry><entry><title>WordPress Performance Optimisation</title><link href="https://www.peakhour.io/blog/wordpress-performance-optimisation-security-cdn/" rel="alternate"></link><published>2019-05-27T13:00:00+10:00</published><updated>2019-05-27T13:00:00+10:00</updated><author><name>Dan</name></author><id>tag:www.peakhour.io,2019-05-27:/blog/wordpress-performance-optimisation-security-cdn/</id><summary type="html">&lt;p&gt;How to speed up WordPress by separating public cacheable pages from private, expensive, and abused request paths.&lt;/p&gt;</summary><content type="html">&lt;p&gt;WordPress speed problems are usually request-path problems. A public article, product page, or campaign landing page should not make PHP, plugins, and the database rebuild the same HTML for every visitor. A login attempt, checkout session, admin request, or private API call should not be treated like public content just because the site is under load.&lt;/p&gt;
&lt;p&gt;The job is to separate those paths clearly. Cache what can be reused, protect the routes that are expensive or abused, and keep enough evidence to prove that the change improved the visitor experience without hiding origin risk.&lt;/p&gt;
&lt;h2&gt;Start With Public Page Caching&lt;/h2&gt;
&lt;p&gt;Most WordPress sites have a large set of pages that are dynamic only because WordPress generated them. The content itself is public and often identical for many visitors: posts, pages, category archives, product listings, campaign pages, media assets, CSS, and JavaScript. These are the paths where full-page caching and edge delivery can change the result quickly.&lt;/p&gt;
&lt;p&gt;When a public page is served from cache, the browser avoids the long trip to origin and the origin avoids running WordPress for a repeat response. That can move Time to First Byte and Largest Contentful Paint in the right direction before anyone touches the theme. Peakhour's older full-page caching examples showed the practical size of this change: a Magento main document fell from 2.07 seconds before caching to 82 ms after caching. WordPress sites have different internals, but the same pattern applies when anonymous pages are safe to reuse.&lt;/p&gt;
&lt;p&gt;The cache policy should be route-aware, not blanket. A simple operating model looks like this:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;WordPress path&lt;/th&gt;
&lt;th&gt;Delivery stance&lt;/th&gt;
&lt;th&gt;What to check&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Posts, pages, category pages, campaign pages&lt;/td&gt;
&lt;td&gt;Cache publicly with tags and purge controls&lt;/td&gt;
&lt;td&gt;Confirm logged-out content is shared and fresh after publishing.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Featured images, media library files, theme assets&lt;/td&gt;
&lt;td&gt;Cache and optimise variants&lt;/td&gt;
&lt;td&gt;Track image weight, format, dimensions, and cache hit state.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WooCommerce product and category pages&lt;/td&gt;
&lt;td&gt;Cache when no cart/session dependency changes the response&lt;/td&gt;
&lt;td&gt;Keep stock, price, and promotion purges tied to content changes.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cart, checkout, account, previews, admin&lt;/td&gt;
&lt;td&gt;Bypass shared cache&lt;/td&gt;
&lt;td&gt;Preserve session privacy and correctness.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;wp-login.php&lt;/code&gt;, &lt;code&gt;/wp-admin/&lt;/code&gt;, &lt;code&gt;xmlrpc.php&lt;/code&gt;, sensitive plugin endpoints&lt;/td&gt;
&lt;td&gt;Protect and rate-limit before origin&lt;/td&gt;
&lt;td&gt;Keep noisy automation away from PHP workers and admin paths.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;Publishing Should Not Clear the Whole Site&lt;/h2&gt;
&lt;p&gt;Caching WordPress is easy until someone edits content. Clearing the whole cache after every post update is safe in the narrow sense, but it damages hit ratio and pushes avoidable traffic back to origin. During a busy publishing period or campaign, that can make the site slower exactly when fresh content is being promoted.&lt;/p&gt;
&lt;p&gt;Cache tags are a better fit. Tags label cached responses by the content or template they depend on, so a post update can purge the post, related archives, and affected modules without invalidating unrelated pages. The updated Peakhour WordPress plugin generates cache tags automatically and sends purge requests when content changes in the WordPress admin. That lets teams set longer cache lifetimes for public content while still publishing with confidence.&lt;/p&gt;
&lt;p&gt;This is where &lt;a href="/products/advanced-caching/"&gt;advanced caching&lt;/a&gt; becomes operational rather than theoretical. The site team can review which tags were purged, which routes stayed cached, and whether the next request was a hit, miss, or stored response.&lt;/p&gt;
&lt;h2&gt;Images and Browser Work Still Matter&lt;/h2&gt;
&lt;p&gt;Page caching improves the start of the request path. It does not fix a 3 MB hero image, missing image dimensions, unused CSS, or a third-party script that blocks rendering. WordPress themes and plugin stacks often ship CSS and JavaScript for features that are not used on the current page. The browser still has to download and parse that code before it can paint useful content.&lt;/p&gt;
&lt;p&gt;Use Lighthouse to find render-blocking resources and main-thread pressure. Use WebPageTest to see whether the main HTML arrived quickly but the filmstrip still stayed blank while CSS, fonts, scripts, or images loaded. Those are different failures, and they need different fixes.&lt;/p&gt;
&lt;p&gt;For images, the best results usually come from serving the right variant rather than only compressing the original. &lt;a href="/products/image-optimisation-and-transformation/"&gt;Peakhour image optimisation&lt;/a&gt; can generate AVIF or WebP outputs, choose responsive sizes, and cache the resulting variants. That helps LCP when the largest visible element is an image, and it helps CLS when dimensions are kept stable.&lt;/p&gt;
&lt;p&gt;For CSS and JavaScript, remove unused files where possible, defer non-critical scripts, self-host critical third-party assets when practical, and reserve &lt;code&gt;preconnect&lt;/code&gt; for third-party domains that genuinely affect the first view. Moving every script later can break dependencies, so test the actual page type rather than applying a generic rule across the whole theme.&lt;/p&gt;
&lt;h2&gt;Protect Expensive WordPress Paths&lt;/h2&gt;
&lt;p&gt;Performance and security meet at origin capacity. Login floods, XML-RPC abuse, aggressive crawlers, scraper traffic, and noisy plugin endpoints can consume PHP workers and database connections that should be serving real visitors. If those requests are filtered only after WordPress has loaded, the site can look like it has a speed problem when it really has an unsorted traffic problem.&lt;/p&gt;
&lt;p&gt;For WordPress, protection should be specific. &lt;code&gt;wp-login.php&lt;/code&gt;, &lt;code&gt;/wp-admin/&lt;/code&gt;, &lt;code&gt;xmlrpc.php&lt;/code&gt;, the REST API, and plugin-specific endpoints should have their own bot, WAAP, and rate-limit policy. WooCommerce needs separate handling again: public catalogue pages can often be cached, but cart, checkout, account, and payment paths must stay dynamic and private.&lt;/p&gt;
&lt;p&gt;This does not mean putting heavy checks in front of every visitor. It means making edge decisions before origin work: allow clean public page requests, serve cache hits, challenge or rate-limit suspicious login traffic, bypass cache for private sessions, and log what happened.&lt;/p&gt;
&lt;h2&gt;Measure the Outcome&lt;/h2&gt;
&lt;p&gt;The evidence should line up across tools. WebPageTest should show a faster main document on cache hits, fewer slow origin fetches, and a waterfall where critical resources are visible early. Lighthouse should show fewer render-blocking opportunities and less main-thread pressure. Core Web Vitals should move where the page had the relevant bottleneck: LCP for slow HTML or heavy hero media, CLS for unstable layout, and INP for JavaScript and interaction work.&lt;/p&gt;
&lt;p&gt;Peakhour evidence should add the delivery side: cache hit ratio, miss causes, purge state, &lt;code&gt;Cache-Status&lt;/code&gt;, image savings, shielded misses, blocked login or XML-RPC abuse, and origin request volume. That combination tells the site team whether WordPress is faster because visitors received lighter pages from the edge, because abusive traffic stopped draining origin, or because browser work was reduced.&lt;/p&gt;
&lt;p&gt;Fast WordPress is not a plugin list. It is a set of clear route decisions backed by before-and-after measurements.&lt;/p&gt;</content><category term="Performance"></category><category term="WordPress"></category><category term="Drupal"></category><category term="Core Web Vitals"></category><category term="Rate Limiting"></category><category term="Web Performance"></category><category term="Application Security"></category></entry><entry><title>Boost Your Website Speed with Full Page Caching</title><link href="https://www.peakhour.io/blog/magento-1-plugin/" rel="alternate"></link><published>2019-05-10T13:00:00+10:00</published><updated>2023-11-02T13:00:00+11:00</updated><author><name>Dan</name></author><id>tag:www.peakhour.io,2019-05-10:/blog/magento-1-plugin/</id><summary type="html">&lt;p&gt;Our Magento 1 plugin is now available in the Magento Store. Discover how it improves website performance and capability.&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;a href="/blog/opencart/opencart-3-caching-plugin/"&gt;Full page&lt;/a&gt; caching is not a cosmetic optimisation. Users expect quick load times, and search engines reward fast websites with higher rankings. Full page caching supports both by storing fully rendered HTML pages, so the server does not have to rebuild the page from scratch for each visitor.&lt;/p&gt;
&lt;h2&gt;How Full Page Caching Enhances Performance and Capability&lt;/h2&gt;
&lt;p&gt;By caching full HTML pages, you create a snapshot of a page at a particular moment. When a user requests that page, the server can deliver the snapshot instead of generating the page again. This saves compute and database resources, allowing your server to handle more users simultaneously. The result is straightforward: faster load times for users and less strain on the server.&lt;/p&gt;
&lt;h3&gt;Real-World Impact&lt;/h3&gt;
&lt;p&gt;Our early adopters have reported clear improvements in &lt;a href="/blog/wordpress-plugin/"&gt;website speed&lt;/a&gt; and server performance. One client saw a 40% reduction in server load and a 20% increase in page load speed. Those results point to a better user experience and potentially higher conversion rates.&lt;/p&gt;
&lt;h2&gt;Challenges with Magento 1 and How We Solved Them&lt;/h2&gt;
&lt;p&gt;Magento 1 presents specific challenges for full &lt;a href="/blog/opencart-3-plugin/"&gt;page caching&lt;/a&gt;, and our plugin handles them directly.&lt;/p&gt;
&lt;h3&gt;Mini Cart Issue&lt;/h3&gt;
&lt;p&gt;The mini cart needs to show real-time data, which makes it a barrier to full page caching. Our plugin uses targeted AJAX calls to fetch this data only when required, reducing unnecessary load on the server.&lt;/p&gt;
&lt;h3&gt;Form Key Problem&lt;/h3&gt;
&lt;p&gt;Magento 1 uses form keys to prevent CSRF attacks, but those keys make caching difficult. Our plugin replaces form keys with a strict referrer check, which is secure and cache-friendly.&lt;/p&gt;
&lt;h3&gt;Additional Features&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Automatic Expires Headers&lt;/strong&gt;: You do not need to manually set expiration times for your cache; our plugin does it for you.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cache Tagging&lt;/strong&gt;: This allows for precise cache management. When you update a product, only the relevant cached pages are flushed, keeping the process efficient.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The plugin is available for download, with the aim of improving performance and increasing server capability on Magento 1 stores.&lt;/p&gt;</content><category term="CMS"></category><category term="Caching"></category><category term="Web Performance"></category><category term="Drupal"></category><category term="WordPress"></category><category term="CDN"></category><category term="Core Web Vitals"></category></entry><entry><title>Boost Your Website Speed with Peakhour's Full Page Caching</title><link href="https://www.peakhour.io/blog/wordpress-plugin/" rel="alternate"></link><published>2019-04-02T13:00:00+11:00</published><updated>2019-04-02T13:00:00+11:00</updated><author><name>Dan</name></author><id>tag:www.peakhour.io,2019-04-02:/blog/wordpress-plugin/</id><summary type="html">&lt;p&gt;Experience a significant boost in website speed and performance with Peakhour's Full Page Caching feature, now easily accessible through our Wordpress plugin.&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Why Full Page Caching Matters&lt;/h2&gt;
&lt;p&gt;Site speed affects user experience, conversion, and server load. Slow pages can increase bounce rates and cost revenue. &lt;a href="/blog/opencart/opencart-3-caching-plugin/"&gt;Full Page&lt;/a&gt; Caching improves response times by storing and serving static versions of dynamic pages. This reduces load on your server and gives visitors quicker page loads.&lt;/p&gt;
&lt;h2&gt;How Peakhour Optimises Your Site&lt;/h2&gt;
&lt;p&gt;Peakhour helps speed up and secure your website with a DNS change. Unlike basic caching solutions, Peakhour serves these static pages from its global ANYCast network. Your site's visitors download content from a server close to them, reducing latency and speeding up downloads.&lt;/p&gt;
&lt;h2&gt;Peakhour's Transparent Caching and Delivery&lt;/h2&gt;
&lt;p&gt;In addition to Full Page Caching, Peakhour can act as a transparent delivery and cache layer. It caches and optimises static assets like CSS, JavaScript, and images. You don't need to make any other changes to your site; a DNS change is all it takes.&lt;/p&gt;
&lt;h2&gt;Wordpress Plugin for Easy Integration&lt;/h2&gt;
&lt;p&gt;During our beta phase, many clients used early versions of our WordPress plugin. The plugin integrates with Peakhour's API to automate content flushing when you make edits in the WordPress admin panel. This simplifies publishing and allows you to set longer lifetimes for your dynamic content in our global cache.&lt;/p&gt;
&lt;h2&gt;Improved Performance Metrics&lt;/h2&gt;
&lt;p&gt;With Peakhour, sites can see faster download times, a higher cache hit rate, and reduced load on the origin server. Site owners get lower origin demand; visitors get faster pages.&lt;/p&gt;</content><category term="CMS"></category><category term="Caching"></category><category term="Web Performance"></category><category term="WordPress"></category><category term="Drupal"></category><category term="CDN"></category><category term="Rate Limiting"></category></entry></feed>