Achieving search within AEM the Bridgestone way - a case study
Having a website or web application with a search feature is nearly a requirement now-a-days for the optimum user experience that we are all trying achieve/want. Why spend all that time looking for that one item through layers upon layers of navigation and menus when you can simply type it or even speak it using your mobile device? As rudimentary as a search feature may appear to the normal "joe," the decisions made during the experience, design, and development processes have a drastic effect on your website. Sometimes these decisions can be made on the simple question of: do you want your search fast, or extensive and intelligent? Either way, each option can supply their own list pros and cons that either the developer or the user will have to endure.
Searching within AEM
When building a search function within AEM, extra considerations need to be taken into account in regards to the application's dispatcher. Do we want to by-pass the dispatcher and risk the extra load on the application server to completely load the entire view over and over during the search and filtering process? Or do we want to risk some potential in-page performance issues if we load everything into the page via API service, create a complicated Javascript application to digest the service's content, and even sacrifice SEO for the page?
The Bridgestone development team at VML Kansas City has implemented multiple solutions to the "search problem" with mixed results in all facets. As I continue to explain what we did to execute these tasks, here's one thing to keep in mind as you read on: each website had a different audience as well as content types/amounts to consider.
Party in the back with Firestone Commercial
The Firestone Commercial website was a gigantic undertaking for the entire team involved and I'm sure these people can not emphasize this enough. The task of effectively combining three separate business units, or BU's, into a single cohesive environment was not easy. As you would expect, each BU wanted equal exposure as well as representation through out the site. These expectations had to be implemented within the product catalogs and site searches as well.
Products
If you look at the Agriculture product search page, you will notice a slight flicker during the load the page's initial load. That is because the list of products is being retrieved from an API endpoint supplied by an AEM service and then is parsed using AngularJS. The array of results is rendered within the DOM using a stereo typical AngularJS ng-repeat.
I do want to point out that if you regard the "Network" tab in your Developer Tools, a new API call is made every single time you filter/search your content. Once the new call is made, you will see your content change beneath it. Additionally, you will also see that the "Off-the-Road" and "Truck & Bus" buttons take you to a completely different page. This is because the available filters change from BU to BU.
Site Search
Other than the autocomplete function that is available within the search overlay that appears upon click the "Search" button within the navigation, the full site search is done "the old fashioned" way. This consists of taking the query string, passing it to a class that then runs it through a series of X-Path queries and then returns the results. We currently do have a few additional methods in place to apply weighting to the results that improve the accuracy of the search. Because of the lack of front-end API calls, this does mean that each returned result does in fact hit the application server and cannot be cached by the dispatcher.
Bringing it to the front with Bridgestone Commercial
The functionality of both the product filtering and site search for the Bridgestone Commercial website took a bit of technological evolutionary turn when it came to implement these features. While both of these components still made use of the API endpoints much like that of Firestone's product catalog, the view was not required to reload; allowing for a more immediate and optimized experience.
Products
Initially when the Bridgestone Commercial product catalog was constructed, all of the product data for the Bridgestone product catalog was loaded into the page at once. Just to clarify, when I say all of the product data, I mean all of it. So the opening page load included the products for both the construction and truck business units, as well as all of the data necessary for the filters. We then used a pretty complex AngularJS application to parse and sort the data. The major difference with this implementation versus Firestone was the ability to serve product data all on the same page for all of the business units, as well as dynamically modify the available filters based on the visible products.
Version 1.1
Soon after the website's launch we started to receive some internal requests regarding the product catalog. The creative team was not happy with the animations, or lack thereof, when a filter was changed. The organic search team was also complaining about the lack of SEO on the page. This was because none of the product data till after the javascript had rendered the app. Unfortunately Google does not effectively crawl single page javascript applications. As if that wasn't enough, we were receiving reports of some performance issues within the page. The web page was being forced to store a massive amount of information on load. This was causing users with a lesser machine or mobile device some interaction delays when filtering the product information. Obviously these detriments to the user experience were unacceptable.
After some brainstorming, my solution was to render all of the products and their respective data within the AEM Sightly template outside of Javascript. This provided a number of solutions and optimizations. First, because the product data would be rendered even without Javascript, the production information would be available for Google to crawl. Second, since this cut down on the volume of data the page had to hold in memory, our Javascript performance improved significantly. Finally and most importantly, our creatives were satisfied with the introduction of filtering animations. The recently achieved optimizations allowed us to add CSS3 animations to all of the products to polish up the filtering process and experience.
Site Search
The site search was highly simplified due to the fact that we moved all of the functionality to a servlet with an API endpoint that would allows to utilize GET requests and receive results based on the query parameter. These results would then be rendered using a simple AngularJS application. Much like that of Firestone, we used additional methods to add weighting to the returned search results.
The pros and cons
Firestone Commercial
Using the server to render the results
The Pros
- Limited Javascript/AngularJS needed
- Results can be easily optimized for search
- Allows for large amounts of data
The Cons
- The search must by-pass the AEM dispatcher
- Large amounts of traffic can be hard on an application server without the proper load balancing
- Requires multiple pages for customized experiences
Bridgestone Commercial
Using Javascript/AngularJS to render and filter the results
The Pros
- Appropriate SEO can be achieved if data is rendered correctly
- Can dynamically change the filtering experience based on user interaction
- All but eliminates impact on the application server; the dispatcher does the heavy lifting
The Cons
- Extremely complex Javascript/AngularJS applications
- Can result in "chunky" animations and user experience
- If not treated correctly, content will not be SEO-friendly
Wrapping Up
Each implementation that we have used yielded their own unique results; both good and bad. Like I said above, each team and project will need to weigh these pros and cons based on the project's needs, the talent and time available, and the acceptable user experience debt. In the end, the decision is up to you!