Faster String Sorting with Intl.Collator

Updated on · 2 min read
Faster String Sorting with Intl.Collator

String sorting can create unexpected performance bottlenecks, especially when working with large datasets that need proper localization. Many developers rely on String.localeCompare for alphabetical sorting, but there's a more efficient approach worth exploring.

The limitation of String.localeCompare

Most JavaScript developers are familiar with code like this:

js
const names = ["Élodie", "Anna", "Özil", "Bob"]; // Standard approach with localeCompare const sortedNames = names.sort((a, b) => a.localeCompare(b, "en", { sensitivity: "base" }), ); console.log(sortedNames); // Output: ["Anna", "Bob", "Élodie", "Özil"]
js
const names = ["Élodie", "Anna", "Özil", "Bob"]; // Standard approach with localeCompare const sortedNames = names.sort((a, b) => a.localeCompare(b, "en", { sensitivity: "base" }), ); console.log(sortedNames); // Output: ["Anna", "Bob", "Élodie", "Özil"]

This works perfectly for small arrays, but becomes problematic with larger datasets. The issue? Each localeCompare call processes locale settings from scratch, creating significant overhead when repeated thousands of times during a sort operation.

The Intl.Collator API provides a better alternative by allowing developers to create a reusable collator object:

js
const names = ["Élodie", "Anna", "Özil", "Bob"]; // Create once, use repeatedly const collator = new Intl.Collator("en", { sensitivity: "base" }); const sortedNames = names.sort((a, b) => collator.compare(a, b)); console.log(sortedNames); // Output: ["Anna", "Bob", "Élodie", "Özil"]
js
const names = ["Élodie", "Anna", "Özil", "Bob"]; // Create once, use repeatedly const collator = new Intl.Collator("en", { sensitivity: "base" }); const sortedNames = names.sort((a, b) => collator.compare(a, b)); console.log(sortedNames); // Output: ["Anna", "Bob", "Élodie", "Özil"]

This approach initializes the locale settings only once, then reuses them for all comparisons.

Performance impact

Testing with larger datasets typically shows sorting time improvements of 60-80% when using Intl.Collator instead of repeated localeCompare calls. For applications that display thousands of sorted records, this can transform a noticeably laggy interface into a responsive one.

The code also becomes more maintainable. Instead of repeating locale parameters throughout the codebase, a single collator can be created as a utility and reused wherever sorting is needed.

Best use cases

Intl.Collator provides the most benefit in these scenarios:

  • Sorting large collections (hundreds or thousands of items)
  • Repeatedly sorting the same data (such as when users change sort direction)
  • Virtual lists with frequent sorting operations during scrolling
  • Applications dealing with multilingual text

For very small lists or one-off sorting operations, the performance difference may be negligible compared to the additional setup code.

Browser compatibility

Support for Intl.Collator is strong in modern browsers (even IE 11) and Node.js environments. However, for applications supporting legacy browsers, compatibility checking or a polyfill might be necessary.

Conclusion

For developers working with substantial string sorting tasks, especially with international text, Intl.Collator represents a straightforward optimization with meaningful real-world benefits. It's a small implementation change that can notably improve application performance.

References and resources