Implement Caching in the Application-Server and Storage Layers
Learning Objectives
After completing this unit, you’ll be able to:
- Explain the caching options for the application-server layer.
- List two types of content for which B2C Commerce uses caching.
- Explain the caching options for the storage layer.
- Explain how Page Designer and content slots use remote includes.
Application-Server Layer
The application server, which forms the middle layer, handles the endpoints (entire pages or remote includes) that serve dynamic information, such as consumer data or cart information, data that can’t use page caching. The application, however, can still perform expensive calculations on those pages, with the results cached to reduce the overall processing time of the dynamic request. Vijay Lahiri, Cloud Kicks developer, wonders, “Which caching option should I use to keep my app-server layer super speedy?”
Configuration As Code
Smart and globally minded, Vijay uses configuration as code to support multiple brands in multiple countries. Nice one, Vijay! The configuration is stored in JSON files and can be extended through brand- and country-specific overrides. Reading a JSON file and merging JavaScript objects isn’t an expensive operation, but it’s frequent enough to consume lots of processing time. By caching the configuration for each brand and country combination, Vijay avoids recalculating for every request and remote include.
Request Caching
Vijay uses request caching to store data inside a module in a single request. If the data is required later, this approach keeps its state. Caching saves the data in the request with the additional logic attached. He uses this approach when, for example, marketing wants to save a shopper’s selected store, but they don’t want Vijay and other developers to access the data. The module saves the store ID internally and exposes methods only to return the store object or perform actions with the store, while hiding the implementation details and keeping them in a single, central place.
Use request.custom
to save and read when you want to store a small piece of data.
Custom Cache
Vijay uses the custom cache to store a limited amount of information. Because the info isn’t shared across application servers, it isn’t synchronized. He uses this caching method to save the intermediate results of expensive operations that need to happen within dynamic requests, or operations that happen frequently.
File Cache
He uses the file cache for build-time optimizations to:
- Generate templates in scenarios where template languages other than ISML are used.
- Optimize development code.
- Create environment-specific configurations.
Sessions
Vijay uses sessions to cache small pieces of shopper information, such as address and phone number.
- Use
session.custom
when you’re collecting data to build dynamic customer groups. Use this option sparingly, because it can consume a lot of system resources. - Use
session.privacy
when you’re not collecting data to build dynamic customer groups. This option doesn’t trigger customer-group updates and consumes fewer resources, with the data cleared when the shopper logs out of their account.
Static Content Caching
He uses static content caching for image, style-sheet, and client-side JavaScript files that the browser downloads and consumes. B2C Commerce uses two caches for different kinds of content, each of which is configured and invalidated separately.
- Page cache, covered in the previous unit
- Static content cache
Static content is delivered by the origin server and cached within the enterprise content delivery network (eCDN). This content is managed directly in the environment or included in the code. If managed directly, static content is often generated during the build process. Once this content resides on the server, it is served as-is and cannot contain dynamically calculated information.
Manage the static content cache in Business Manager: Administration > Sites > Manage Sites > Global Static Cache (or the Cache tab for site settings).
Storage Layer
This is the bottom layer where custom objects live. Vijay uses custom objects in this layer when cached data must be retained, or when custom objects act as intermediate storage for data that’s processed later.
- You can import and export custom objects.
- You can write to and read custom objects.
- Custom objects are persistent and consistent across all application servers.
Vijay uses custom objects sparingly. Because custom objects are stored in the database, they must traverse all architectural layers, which negatively impacts performance.
Take a Holistic View with Control Endpoints
Shoppers spend most of their time on these pages, each of which translates into a controller endpoint.
Page |
Endpoint |
Home |
Default-Start and Home-Show |
Product list (search and category navigation) |
Search-Show |
Product detail |
Product-Show |
Content |
Page-Show |
Ensuring that these pages have high cache-hit rates and fast response times can be a challenge, because many factors come into play. Sometimes, Vijay’s head spins. Moreover, the numbers don’t always indicate a positive shopper experience.
The storefront application generates links to product variants on product-list pages (PLPs), which are search results pages, while the product-detail page (PDP) redirects to the primary product data as a best practice. This leads to fast PDP metrics, because each call is effectively two requests, including:
- A request to the variant that responds with a fast redirect
- A request to the PDP
The duration of each request is included in the average, not the average of the combination of the two requests. Thus, the reported PDP average response time appears twice as fast as it actually is, and the shopper experience is not as good as it could be. Not only is the PDP slow, but it uses an additional costly redirect. Other situations can also adversely impact average response time, so it’s important that Vijay reviews performance holistically instead of focusing on a single indicator.
The percentage of processing time value, for example, is a good indicator that Vijay can use to improve page caching or optimize processing times.
Common Pitfalls
Here are some common pitfalls and how to handle them.
Pitfall |
Solution |
Missing cache directives |
Cache directives are missing, because they’ve been removed from the code by developers or not added when someone created new endpoints. Use the Reports & Dashboards tool to identify endpoints that have a 100 percent cache-miss rate. As a best practice, review all endpoints a few days after site launch to ensure they are being cached as expected. |
Key pages and includes |
Pay attention to these key pages and includes.
|
Here are the current guidelines for primary storefront controllers. For the cache-hit ratio, even a few percentage points lower can slow the loading of search result pages and reduce scalability. Use the Reports & Dashboards tool to identify endpoints with a 100 percent cache-miss rate. See if there’s a way they can use cache, too.
Storefront Experience |
Controller* |
Recommended Average Response Time (ms) |
Recommended Cache-Hit Ratio |
Product Search/Category List |
Search-Show |
≤500 |
>75% |
Product Search/Category List & Recommendations |
Product-HitTile |
≤10 |
>95% |
Product Detail |
Product-Show |
≤500 |
>75% |
Home Page |
Home-Show |
≤90 |
>90% |
Content Page |
Page-Show |
≤100 |
>90% |
Cart Page |
Cart-Show |
≤650 |
- |
OCAPI-Requests |
≤300 |
- |
*Primary controller names can vary by customization.
Content Display
Here’s how Page Designer and content slots, which are key content display methods, use remote includes.
Page Designer
When PageMgr.renderPage() renders a Page Designer page, the rendering process uses two nested remote includes.
- __SYSTEM__Page-Include: Determines the visibility fingerprint of the page and its components based on schedules, customer groups, or other visibility settings. It passes the visibility fingerprint to the second-level remote include.
- __SYSTEM__Page-Render: Invokes the render function to render the page. Based on different visibility settings, each page variation is cached separately.
Content Slots
The storefront application serves content slots within remote includes to allow independent cache control. Vijay uses directives in the rendering template, which control the caching for the slot content. The application automatically recalculates the slot configuration to display, regardless of the cache settings in the rendering template, through an additional dynamic include. Directives alter the appearance or behavior of an existing HTML element by taking advantage of internal browser functionality. When you include directives in templates, the directives look like regular HTML attributes.
Next Steps
In this unit, you learned how to maximize application performance using caching in the application-server and storage layers. Next, learn how to troubleshoot common performance issues.
Resources
- Salesforce Help: Content Cache
- Trailhead: Headless Implementation Strategies for Salesforce B2C Commerce (the Implement a Content Delivery Network and Caching unit)
- Trailhead: Salesforce B2C Commerce Page Designer for Developers