article

Attributes vs. Jetboost Comparison

This article compares the two most popular filtering solutions for Webflow:

  • Jetboost offers real-time search, dynamic filtering, and more for Webflow — without writing code.
  • Attributes is a Finsweet-backed no-code product that offers a number of solutions for Webflow.

At the time of this writing, Jetboost offers several paid plan options across their product line. Attributes is free for personal and commercial use.

Index

IntroDisclaimerFeatures Comparison Filtering Sorting Pagination SetupPerformance Comparison Setup basics API authentication Filtering and sorting itemsCost comparison Server vs. frontend Free vs. PaidConclusion
This is some text inside of a div block.

Disclaimer

We are Finsweet, the sole creators of Attributes. We wrote this article because many in the community have asked us how our Attributes based filtering solution stacks up against Jetboost.

This article is as objective as we could make it. The comparisons between both products were conducted in good faith and based on industry standards for web development. The benchmarks used were based on best practices for performance, accessibility and security.

While it may seem obvious for us to think our solution is the best when it comes to filtering, we want to provide factual evidence for why you should pick one over the other.

For more details about why we are making these comparisons, click here.

Features comparison

This chart compares functionalities offered by both products and the accessibility practices around them.

Filtering

Allowed filter elements:

Jetboost
Attributes
Radios
✅ Supported.

❌ Doesn't ensure unique name and id when using radios inside a Collection List.
✅ Supported.

✅ Ensures unique name and id when using radios inside a Collection List.
Checkboxes
✅ Supported.

❌ Doesn't ensure unique name and id when using checkboxes inside a Collection List.
✅ Supported.

✅ Ensures unique name and id when using checkboxes inside a Collection List.
Select
✅ Supported.
✅ Supported.

✅ Integrates with other Attributes solutions like Select Custom.
Link elements (Button, Link Block, Text Link)
✅ Supported.

❌ Doesn't define aria attributes for screen readers.

❌ Can't be used with the keyboard arrows.

❌ Doesn’t follow any a11y specs.
❌ Not supported.

This is a conscious decision.

Read below to learn more about why we do not support Button, Link Block, Text Link s default filter elements.
Other types - (range, date, color)
❌ Not suported.
✅ Supported.

✅ Integrates with other Attributes solutions like Range Slider and with any third party solution that wraps around form fields, like Flatpickr, Coloris.js, jQuery Datepicker, etc.

Supported features:

Jetboost
Attributes
CMS Filter UI Elements
✅ Supported.
✅ Supported.
Static Filter UI Elements
❌ Not supported.
✅ Supported.
Initial State
❌ Not supported.
✅ Supported.

✅ Ability to set custom initial state when no filters are applied.
Results Count
✅ Supported.
✅ Supported.
Active Tags
✅ Supported.

✅ Supports removing tags (and the correspondent applied filter).

❌ Requires an additional CMS Collection List to manage the active tags.
✅ Supported.

✅ Supports adding selected filter values as tags with static template.

✅ Supports adding a custom tag category name per filter.

✅ Supports removing tags (and the correspondent applied filter).
Scroll Anchor
❌ Not supported.
✅ Supported.

✅ Supports defining an element to scroll into view when the list is filtered.
Reset
✅ Supported.

❌ Requires stacking multiple CSS classes for “Reset All”.
✅ Supported.
Match (matching all or any values in a filter group.)
✅ Supported.
✅ Supported.
Range
❌ Not supported.
✅ Supported.

✅ Supports filtering by a defined range in the filters.

✅ Supports filtering by a defined range in the items.
Date Fields
❌ Not supported.
✅ Supported.
Filters Query Params
✅ Supported.
✅ Supported.
Highlight
✅ Supported just for text inputs.

Applies a Jetboost defined CSS class that can't be renamed.
✅ Supported for all filter inputs.

Applies a CSS class that can be renamed by the user.
Filters Active State
✅ Supported.

❌ Applies a Jetboost defined CSS class that can't be renamed.
✅ Supported.

✅ Applies a CSS class that can be renamed by the user.
Debouncing
✅ Supported.

❌ Users can't modify the debouncing.
✅ Supported.

Users can granularly choose the amount of debouncing for each single filter.
Filter on Click
❌ Not supported.
✅ Supported.

Users can optionally require the user to press a button, for example a “Filter Results” button, to start the filter process.
Toggle Filter
❌ Partially supported through sorting booster.

It is possible to create a filter toggle with Jetboost. Since it uses a sorting booster, it is not possible to use an active toggle together with active sorting. Only one can be applied at once — sorting or toggle.
✅ Supported.

Users can set up a standalone toggle that works together with any filter or sort UI element.
List Animation
❌ No controls.
✅ Allows full control on the list animation's duration and easing.


Sorting

Allowed sort elements:

Jetboost
Attributes
Select
✅ Supported.
✅ Supported.
Buttons
✅ Supported.

❌ Doesn't define aria attributes for screen readers.
✅ Supported.

✅ Applies role and aria-sort attributes to communicate the current sorting state to screen readers.
Dropdowns
✅ Supported.

❌ Doesn't define aria attributes for screen readers.

❌ Can't be used with the keyboard arrows.

❌ Doesn’t follow any a11y specs.
✅ Supported.

✅ Converts the component into an accessible listbox that supports keyboard navigation.
Item Limit
❌ Item limit.

From Jetboost’s dashboard: “For performance, sorting is limited to 2000 items. We cannot increase the limit at this time.”
✅ No item limit.

Any amount of items can be sorted on the page without significant impacts on performance.

Setup configuration

Quick view into the configuration of both products:

Jetboost
Attributes
Webflow API authentication
Requires Webflow CMS API authentication.
No Webflow account or API access required.
Location for setup and updates
Defined in Jeboost dashboard.
Defined inside Webflow Designer.
Configuration
"Boosters" are created for each feature.

Custom classes are created for each Booster. Classes are stacked on the Collection List to define the configuration.
Custom attributes are applied to elements on the page.
Code Installation
Code can be installed in any page for an optimal perfomance.
Code can be installed in any page for an optimal perfomance.
Method to identify elements
Classes
Attributes
Toggle (Filter)
❌ Not Available
✅ Available
Search on click
❌ Not Available
✅ Available
Active Tags
Needs CMS
CMS not required
- Search (exact vs flexible)
✅ Available
✅ Available
Filter button
CMS is mandatory, static buttons, checkboxes cannot work as filter buttons
CMS or Static buttons can be created

Performance Comparison

Equal Tests

For the purpose of this article, both products were set up and tested using the exact same Webflow project with the exact same amount of Collection List Items.

The only difference between the two tests is the available filtering options (explained in Features). This is because several of the Attribute filter types are not supported by Jetboost so they were removed from the interface.

Setup Basics

Let’s understand how each product integrates with your website.

Jetboost

Jetboost sets an inline JavaScript snippet on the page that stores the project ID (used later to communicate with their API), which then loads the following script:

<script id="jetboost-script" type="text/javascript">
  window.JETBOOST_SITE_ID = "ckwg7xwxp0i9l0nrm3sdu6j3r";
  (function(d) {
    var s = d.createElement("script");
    s.src = "https://cdn.jetboost.io/jetboost.js";
    s.async = 1;
    d.getElementsByTagName("head")[0].appendChild(s);
  })(document);
</script>

This creates and then loads the Jetboost base script. Below is the base script created from the example above:

<script src="https://cdn.jetboost.io/jetboost.js" async ></script>

The base script is used to initialize the project setup by:

  • Setting CSS styles.
  • Validating the API key and fetching user settings from the Jetboost servers.
  • Loading additional scripts to handle the main logic.
  • ~The main Jetboost script is added to the page. Jetboost doesn’t directly load its main library with the inline script you add to the page. It is dynamically added to the page after the base script.
  • ~Jetboost is not modular. It loads all Jetboost functionalities (filter, sort, load, etc) to the page, even if they are not used in the project.

After this initial setup finishes, the <span class="article_code">&#60;head></span> of the website looks like this:

<!-- This is the inline javascript from the above snippet -->
<script id="jetboost-script" type="text/javascript">
  window.JETBOOST_SITE_ID = 'ckwg7xwxp0i9l0nrm3sdu6j3r';
  (function (d) {
    var s = d.createElement('script');
    s.src = 'https://cdn.jetboost.io/jetboost.js';
    s.async = 1;
    d.getElementsByTagName('head')[0].appendChild(s);
  })(document);
</script>

<!-- These are the css styles that are added from the 'base' script -->
<style id="jetboost-list-search-styles" type="text/css">
  .jetboost-list-item-hide {
    display: none !important;
  }
  
  .jetboost-hidden {
    visibility: hidden !important;
  }
  
  @keyframes jetboost-fadeout-animation {
    0% {
      opacity: 1;
    }
    100% {
      opacity: 0.5;
    }
  }
  
  @keyframes jetboost-fadein-animation {
    0% {
      opacity: 0.5;
    }
    100% {
      opacity: 1;
    }
  }
</style>

<!-- This is the 'base' script that is loaded from the inline JavaScript -->
<script src="https://cdn.jetboost.io/jetboost.js" async ></script>

<!-- This is the 'main' script that is loaded from the 'base' script -->
<script src="https://cdn.jetboost.io/v1.4.2/jetboost-main.js" async ></script>

<!-- This is a third party highlight functionality script -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/mark.js/8.11.1/mark.min.js" async ></script>

Attributes

For each Attribute solution, a solution-specific script is added to the page. Below is an example of three Attributes solutions added to a page — Filter, Load, and Sort.

<!-- Functionality for CMS Filter -->
<script async src="https://cdn.jsdelivr.net/npm/@finsweet/attributescmsfilter@1/cmsfilter.js"></script>

<!-- Functionality for CMS Load -->
<script async src="https://cdn.jsdelivr.net/npm/@finsweet/attributescmsload@1/cmsload.js"></script>

<!-- Functionality for CMS Sort -->
<script async src="https://cdn.jsdelivr.net/npm/@finsweet/attributescmssort@1/cmssort.js"></script>


Each Attributes solution is split into its own package (separate scripts) to keep the setup modular. This means Attributes only loads the minimum required JavaScript to make the desired functionality work.

When using CMS Attributes, an additional <span class="article_code">cmscore</span> script is dynamically downloaded in the background, which contains a set of global functionalities that are used across all CMS packages.

Instead of adding those global functionalities in every CMS script, Attributes uses a single core package that can be accessed by all CMS solutions. This avoids downloading the same global functionality code when using multiple of them. The CMS core package enhancement is our <span class="article_code">cmscore.js</span> file.

Each attribute functionality is contained into its own package that is only loaded when required.
🛈 For example, if you wanted to only use CMS Filter, you would only need to add the CMS Filter script to the page. CMS Load and CMS Sort do not need to be added to the page since they are not being used. We will only load the JavaScript for the required functionality.

Jetboost loads all functionalities on the page, even if the setup doesn’t require them:

Jetboost loads the same Javascript files in all projects.


With the exception of a third party highlighting library for the Search Highlighting Power Up:

mark.js is only imported when the Search Highlighting Power Up is activated.

Each Attributes solution is loaded asynchronously in the background and remains completely independent of any other attribute. This means that no functionality will be paused or interrupted while waiting for another to load.

For example, if a project uses Attributes <span class="article_code">cmsfilter</span>, <span class="article_code">cmssort</span> and <span class="article_code">cmsload</span>:

  • Whenever the first package is loaded (<span class="article_code">cmsfilter</span> for example), the CMS Filter functionality is immediately available and the user can start filtering the list.
  • Even if the other packages take longer to load (or even if they don’t load at all), the already loaded packages will always work correctly. Users do not need to wait for all packages to load to start using CMS Filter.
  • As soon as any other package is loaded (<span class="article_code">cmsload</span> for example), it automatically couples with the previously loaded packages and starts running its task.
  • Everything happens seamlessly in the background regardless of the load time for each package, without affecting UX.
  • ~Know that each Attribute takes an average of <span class="article_code">30ms</span> to load and all packages are loaded simultaneously.

API Authentication

This section reviews the requirements for Webflow API access. In short — Jetboost requires your Webflow account's API access and Attributes does not.

Jetboost

Jetboost requires authentication of your Webflow account. You must sign in to your Webflow account through an OAuth2 workflow from the Jetboost dashboard and give Jetboost API access to your Webflow account.

This is required because Jetboost uses Webflow's CMS API to collect the fields of each Collection Item in your Collection List, so it can compute which items should be filtered on the page based on the users inputs.

Attributes

Attributes does not require any access token nor API key to interact with Webflow's CMS API. It is managed entirely on the frontend of the loaded website.

Instead reading your Collection List Item's fields from the API, Attributes collects the data from the DOM by reading the defined fields with attributes like <span class="article_code">fs-cmsfilter-field</span> or <span class="article_code">fs-cmssort-field</span>.
After that, all processes like filtering and sorting are also entirely done on the user's machine without the need of external APIs communication.

Note: You should always be careful when granting access to third party applications to integrate with your Webflow CMS. API tokens give full access to create, read, update and delete (CRUD) items in your Collections.

Filtering and sorting items

Both filtering and sorting actions are very similar in how they work. This section will focus on the filtering process specifically.

Jetboost

As explained in the API authentication section above, Jetboost uses CMS API to manage your filter system. Jetboost scripts allow them to communicate back and forth to retrieve data about which items need to be shown/hidden/rearranged.

It works like this:

  1. Jetboost listens for a user input (ie. filter button click) and collects the applied filters
  2. Jetboost then makes a request to their API with the collected user inputs.
  3. The API performs the filtering computation and returns a response that includes the items to be shown/hidden.

The time it takes to perform this round trip action varies depending on the amount of information being transferred.

This approach is not a significant performance problem when navigating the website from a fast network. However, a user’s experience can be impacted significantly when navigating to the website from a mobile network which is often much slower.

Below is a video example of the time it takes to apply a filter on a simulated slow network connection using Jetboost filters.

Filtering a Jetboost list on a slow network connection.

After switching to a simulated slow network connection, items are filtered on the page after the response is returned from the Jetboost server. Notice the significant delay when multiple filter options are selected.

⚠️ Since Jetboost requires a direct connection between servers, the filtering process may not work if there are network outages or interruptions.

Missing potential optimizations

In this video we can see that all items in the list are re-rendered regardless of whether or not they were affected by the new sort/filter input. This could affect performance when filtering large collections.

This is because Jetboost re-renders all items when a new sorting input is made, even if there are items which are not affected by the updated filter inputs.

Attributes

With Attributes, filtering happens in the browser. Since everything happens on the frontend, there is no need to communicate back and forth with an external server. This means there is no API request or network connection standing between a user and their filter requests.

This means:

  • Each filtering action starts immediately
  • Functionality is never affected by the users network connection*.
📌 *As long as Attributes have been loaded on the page, they will continue to work even if the users network connection is interrupted.

Further optimizations when filtering

Attributes only applies changes to items that need to be changed. This means that Attributes will only update an item in the list if there is a specific reason to update it. This is similar to a Virtual DOM approach used by frameworks like React or Vue.

Let’s look at an example of this in practice.

In the video below, we see that the first three items remain in place and untouched after filtering. Notice how the <span class="article_code">&#60;div></span> tags of the first three items are not flashing as the filter is run. This is because the first three items are completely omitted by the rendering action and are not changed. This additional efficiency allows Attributes to provide a lightning fast filter experience that does not impact the overall page performance or load speeds.

Filtering a large list of items with Attributes, only the required items are mutated.

The following video displays a user filtering a 2,000 items list in real time. As you can see, the filtering happens in real-time with no delay. As the user clicks a filter option, the items in the list update instantly.

You can also see that the main thread is never blocked and the page is always interactive, even while repeatedly filtering a 2,000 item list with Attributes.

Cost comparison

Server vs. frontend

Jetboost (server)

In the API authentication section we explain how Jetboost requires Webflow API access and Attributes does not.

In the Filtering and sorting items section we explain how each time you filter items on the page, Jetboost communicates with its server.

Let's continue to learn about how this influences the cost of the product.

The infrastructure that Jetboost uses requires several services to be maintained:

  • A server (or serverless functions) to communicate with each Webflow project.
  • An authentication service to validate the communications.
  • A database to securely store data of each user, like API tokens or Collection fields.
  • A storage solution to host static assets like the JavaScript files.
  • A CDN to serve them.
  • A platform where to deploy the main NextJS application from Jetboost.

While we cannot know what it costs Jetboost to run these services, we can be certain that there is a cost associated with it. Costs which must be offset by a monthly subscription as a matter of good business.

As a Jetboost user, your monthly subscription covers these costs along with any other necessary business expenses.

To learn more about Jetboost pricing, visit their website here.

Attributes (frontend)

Because Attributes works in the browser, there are no associated expenses. No cost to maintain a server, no cost to keep your Webflow API key secure in a database, no cost to authenticate your website project, and no cost to host our JavaScript files.

We have built Attributes in such a way that it does not require us to charge you for it.

Once the JavaScript is loaded, there is no additional communication to a server and every action happens entirely on the user's machine.

This is why Attributes still works if internet connection is interrupted. Once the page is loaded, Attributes does not need to access the internet again.

Our JavaScript files are hosted on jsDelivr, a free, fast, and reliable CDN platform. jsDelivr has data centers all over the world with multiple redundancies. This means we don't pay for jsDeliver to serve those files to you, regardless of how many people use the service and we are happy to pass this lack of expense on to you.

Free vs. paid

At the time of this writing, Jetboost has individual and bundled pricing packages. Attributes is completely free to use.

Cost is an important factor to many people when making a decision. As a Webflow agency, we understand how costs of a website project can quickly increase. When we add more paid services on top of Webflow, our monthly costs increases as well as our overall technical debt.

These costs may be absorbed by us as an agency — or they may be passed on to our clients. Either way, nobody likes to pay more than they have to for any particular service.

When we saw the opportunity to build Attributes without usage costs, we took it. We built Attributes as our ideal filter setup as a Webflow agency.

We see these benefits:

  1. No additional costs to pitch to our clients during the sale.
  2. No confusion with account access, billing, and cost inheritance.
  3. No requirement of interacting with Webflow CMS API. (Not all clients are OK with giving out API access).

We released Attributes for free because we understand the importance of filter functionality in Webflow and figured we could solve a huge problem for the entire community with a free and easy to implement solution. Since there is no long term carrying cost to us, we are happy to pass that on for free.

It's part of what makes us so F'in sweet!

Conclusion

We are proud of the work we do and stand behind our mission to provide the Webflow community with the highest quality products we can create.

This article was written for educational purposes as an honest comparison between two filtering solutions in Webflow.

We hope you learned a lot from this article and wish you luck in your journey as a professional Webflow developer.

If you’re interested in reading more about why we created this content, you can view it here.

If you have any thoughts about this article, we are always open to public and private discussion around this or any other product/solution we provide.

Subscribe

Sign up for future releases!

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.