Implement a Content Delivery Network and Caching
After completing this unit, you’ll be able to:
- Explain how the edge ensures the fastest content delivery possible.
- List two storefront design strategies that make shoppers want to stay.
- List three things you can do to optimize storefront performance and reliability.
- Explain caching.
- Outline three steps you can take to determine which resources to cache.
Storefront Implementation Strategies
Vijay wants a storefront design that’s appealing enough to make shoppers want to stay. Part of his strategy is to insist on a speedy page load. Busy shoppers want something to happen when they click a button… and that means instantly. You’ve heard the phrase, time is money. Well, page load time is the most important technical factor in achieving optimal conversion rates. Page load time not only impacts how long shoppers stay on the storefront, but also how they reach the site in the first place. Major search engines such as Google use page load time as a factor when ranking pages in their search results.
Another part of Vijay’s strategy is to maximize site reliability. When the system’s down, conversions can’t happen at all.
Here are some things you can do to optimize storefront performance and reliability.
- Use a content delivery network (CDN).
- Implement multiple caching strategies.
- Use scaling techniques.
- Plan for resilience.
- Tune middleware components.
- Monitor performance.
- Monitor and alert for trouble.
In this unit, Vijay takes a look at CDNs and caching.
Content Delivery Network
Vijay is glad to know that his content delivery network (CDN) can serve cached content from a custom head directly to the shopper. Serving directly from a PoP server (also called the edge) ensures the fastest content delivery possible. Serving content from the edge prevents unnecessary requests to the back-end application and infrastructure. The application only processes requests that require real-time processing, which improves the overall performance and scalability of a custom head.
Vijay partners with a CDN provider for his headless implementation, and is glad to know that his CDN, like many others, provides additional performance-optimization features such as these.
- Bot detection/mitigation
- Firewall security
- Advanced routing capabilities
Without the CDN in place, every request to every file required to load your site must be served from within the application stack each time a shopper loads your website. This is sure to overwhelm your application much sooner.
With a CDN, you have full control over which resources are cached, where they can be cached, and how long they are cached (commonly referred to as time to live, or TTL) before a request to the resource must be reissued to the application.
Considering the many layers involved in a headless architecture, it’s important to return data to the shopper at the closest layer possible. Caching content at every layer greatly improves overall application response time, while also taking the strain off of back-end applications. For a single image, this can mean the difference between a 30 millisecond response time and a 500ms+ response time.
Vijay starts by determining which resources he can cache. Here are the steps to take.
- Build a resource directory based on application endpoints.
- Determine which resources are public (to be cached) and which are private (not cached). Cacheable content is the same between shopper A and shopper B, while non-cacheable content can change between users. HTML base pages are non-cacheable because they display things like logged in user names at the top right or the number of items in a cart.
- Determine the frequency the data changes (< 1 minute, >= 10 minutes, >= 1 hour, >= 1 day).
- Research caching headers and directives (for example, Cache-Control, max-age, and ETag) before implementing cache in the application.
Vijay starts by determining the types of requests he can cache throughout the infrastructure to ensure the fastest possible page-load times, and the duration for which resources are cached.
Here are some of the caching methods he can use.
- API: Ensures that a request already processed by one shopper doesn’t need to be recalculated for another—as long as the requested data isn’t unique across shoppers.
- Distributed: Is shared across application nodes to reduce the load on the underlying storage systems. Each application in a cluster issues fewer requests.
- In-memory: Lives in the application’s physical memory to avoid calculations within the application. In-memory caching is provided by an application runtime SDK or as supplemental libraries.
Caching at the API layer prevents the application from calculating and serving requests that have already been processed for other shoppers. The Apollo Server, for example, can cache and serve cached GraphQL queries to shoppers via the same concepts as a CDN. Because data comes from a range of data sources, however, it’s possible that only certain fields involved in a query are cached.
This diagram shows an example of a cached image request served by a CDN versus an uncached request traveling through the infrastructure to retrieve an image.
Vijay plans to use the NodeJS SDK and implement a Redis cache that checks for a cached response prior to initiating an API call. This reduces the number of API calls made by the SDK, which improves the performance of Vijay’s application. The SDK has built-in support for caching with Redis and is Salesforce-recommended.
A distributed cache has the same advantages of an in-memory cache, with a few key differences.
- The cache is persisted to storage.
- The cache can be shared among application nodes in your cluster, eliminating the need for cache warming at each application node.
B2C Commerce APIs return a cache-control header that dictates the time to live (TTL) for an API request to be cached.
For requests to the application that aren’t cached by the CDN or Apollo server, Vijay can implement an in-memory cache so his application can cache and serve requests that are expensive to calculate.
The NodeJS SDK has built-in support for in-memory caching using key/value pairs. The key contains a unique string, and the value contains the data associated with the key. In a cache containing category results, for example, the key contains a category ID and the value contains the JSON representation of the list of products assigned to the category. When the application receives a request to return products in a category, the application first checks the cache to see if it contains the data. If it doesn’t, it issues a request to the back end that contains it, such as the B2C Commerce API.
Vijay can define a maximum number of cached entries allowed in the cache to ensure the cache doesn’t consume too much application memory. Monitoring the size of the cache during load tests helps him determine a safe threshold, if he needs one.
In-memory cache is unique for each application node in the cluster. As shoppers and SEO robots browse the storefront, the cache can warm quickly across an application cluster. Cache warming is when website traffic has filled the cache so that visitors always get a cache hit. You should allow the cache warming process to complete naturally rather than building cache warming scripts that don’t reflect real traffic.
You learned how the edge ensures the fastest content delivery possible, how two storefront design strategies can make shoppers want to stay. You also learned some steps you can take to determine which resources to cache, and the types of caching you can implement.
Next, you explore some other ways to optimize storefront performance and reliability.
- External Link: Caching—Apollo Server
- External Link: Automatic Persisted Queries (APQ)
- External Link: node-cache
- External Link: Speed is now a landing page factor for Google Search and Ads
- External Link: Redis
- GitHub Documentation: commerce-sdk
- GitHub Documentation: Salesforce Commerce Cloud / commerce-sdk