New vs cached object (v11)

Revision 11 of this benchmark created on


Preparation HTML

<script>
const iterations = 128; // Adjust this number to find the tipping point

const styleMap = {    
  'font-sans': { fontFamily: 'ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"' },
  'font-serif': { fontFamily: 'ui-serif, Georgia, Cambria, "Times New Roman", Times, serif' },
  'font-mono': { fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace' },
  'text-xs': { fontSize: '0.75rem', lineHeight: '1rem' },
  'text-sm': { fontSize: '0.875rem', lineHeight: '1.25rem' },
  'text-base': { fontSize: '1rem', lineHeight: '1.5rem' },
  'text-lg': { fontSize: '1.125rem', lineHeight: '1.75rem' },
  'text-xl': { fontSize: '1.25rem', lineHeight: '1.75rem' },
  'text-2xl': { fontSize: '1.5rem', lineHeight: '2rem' },
  'text-3xl': { fontSize: '1.875rem', lineHeight: '2.25rem' },
  'font-thin': { fontWeight: '100' },
  'font-extralight': { fontWeight: '200' },
  'font-light': { fontWeight: '300' },
  'font-normal': { fontWeight: '400' },
  'font-medium': { fontWeight: '500' },
  'font-semibold': { fontWeight: '600' },
  'font-bold': { fontWeight: '700' },
  'font-extrabold': { fontWeight: '800' },
  'font-black': { fontWeight: '900' },
  'italic': { fontStyle: 'italic' },
  'not-italic': { fontStyle: 'normal' },
  'uppercase': { textTransform: 'uppercase' },
  'lowercase': { textTransform: 'lowercase' },
  'capitalize': { textTransform: 'capitalize' },
  'normal-case': { textTransform: 'none' },
  'text-left': { textAlign: 'left' },
  'text-center': { textAlign: 'center' },
  'text-right': { textAlign: 'right' },
  'text-justify': { textAlign: 'justify' },

  // Colors
  'text-black': { color: '#000000' },
  'text-white': { color: '#ffffff' },
  'text-gray-500': { color: '#6b7280' },
  'text-red-500': { color: '#ef4444' },
  'text-blue-500': { color: '#3b82f6' },
  'text-green-500': { color: '#10b981' },
  'bg-black': { backgroundColor: '#000000' },
  'bg-white': { backgroundColor: '#ffffff' },
  'bg-gray-100': { backgroundColor: '#f3f4f6' },
  'bg-red-100': { backgroundColor: '#fee2e2' },
  'bg-blue-100': { backgroundColor: '#dbeafe' },
  'bg-green-100': { backgroundColor: '#d1fae5' },

  // Spacing
  'm-0': { margin: '0px' },
  'm-1': { margin: '0.25rem' },
  'm-2': { margin: '0.5rem' },
  'm-4': { margin: '1rem' },
  'm-8': { margin: '2rem' },
  'p-0': { padding: '0px' },
  'p-1': { padding: '0.25rem' },
  'p-2': { padding: '0.5rem' },
  'p-4': { padding: '1rem' },
  'p-8': { padding: '2rem' },
  'mt-1': { marginTop: '0.25rem' },
  'mr-2': { marginRight: '0.5rem' },
  'mb-4': { marginBottom: '1rem' },
  'ml-8': { marginLeft: '2rem' },
  'pt-1': { paddingTop: '0.25rem' },
  'pr-2': { paddingRight: '0.5rem' },
  'pb-4': { paddingBottom: '1rem' },
  'pl-8': { paddingLeft: '2rem' },

  // Sizing
  'w-full': { width: '100%' },
  'w-1/2': { width: '50%' },
  'w-1/3': { width: '33.333333%' },
  'w-1/4': { width: '25%' },
  'h-full': { height: '100%' },
  'h-screen': { height: '100vh' },
  'h-64': { height: '16rem' },
  'h-32': { height: '8rem' },

  // Flexbox
  'flex': { display: 'flex' },
  'inline-flex': { display: 'inline-flex' },
  'flex-row': { flexDirection: 'row' },
  'flex-col': { flexDirection: 'column' },
  'justify-start': { justifyContent: 'flex-start' },
  'justify-center': { justifyContent: 'center' },
  'justify-end': { justifyContent: 'flex-end' },
  'justify-between': { justifyContent: 'space-between' },
  'justify-around': { justifyContent: 'space-around' },
  'items-start': { alignItems: 'flex-start' },
  'items-center': { alignItems: 'center' },
  'items-end': { alignItems: 'flex-end' },
  'items-stretch': { alignItems: 'stretch' },

  // Grid
  'grid': { display: 'grid' },
  'grid-cols-1': { gridTemplateColumns: 'repeat(1, minmax(0, 1fr))' },
  'grid-cols-2': { gridTemplateColumns: 'repeat(2, minmax(0, 1fr))' },
  'grid-cols-3': { gridTemplateColumns: 'repeat(3, minmax(0, 1fr))' },
  'grid-cols-4': { gridTemplateColumns: 'repeat(4, minmax(0, 1fr))' },
  'gap-1': { gap: '0.25rem' },
  'gap-2': { gap: '0.5rem' },
  'gap-4': { gap: '1rem' },
  'gap-8': { gap: '2rem' },

  // Borders
  'border': { borderWidth: '1px' },
  'border-2': { borderWidth: '2px' },
  'border-4': { borderWidth: '4px' },
  'border-8': { borderWidth: '8px' },
  'border-t': { borderTopWidth: '1px' },
  'border-r': { borderRightWidth: '1px' },
  'border-b': { borderBottomWidth: '1px' },
  'border-l': { borderLeftWidth: '1px' },
  'rounded-none': { borderRadius: '0' },
  'rounded-sm': { borderRadius: '0.125rem' },
  'rounded': { borderRadius: '0.25rem' },
  'rounded-md': { borderRadius: '0.375rem' },
  'rounded-lg': { borderRadius: '0.5rem' },
  'rounded-full': { borderRadius: '9999px' },

  // Effects
  'shadow-sm': { boxShadow: '0 1px 2px 0 rgba(0, 0, 0, 0.05)' },
  'shadow': { boxShadow: '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)' },
  'shadow-md': { boxShadow: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)' },
  'shadow-lg': { boxShadow: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)' },
  'shadow-xl': { boxShadow: '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)' },
  'shadow-2xl': { boxShadow: '0 25px 50px -12px rgba(0, 0, 0, 0.25)' },
  'opacity-25': { opacity: '0.25' },
  'opacity-50': { opacity: '0.5' },
  'opacity-75': { opacity: '0.75' },
  'opacity-100': { opacity: '1' },

  // Transitions
  'transition': { transition: 'all' },
  'transition-colors': { transitionProperty: 'color, background-color, border-color, text-decoration-color, fill, stroke' },
  'transition-opacity': { transitionProperty: 'opacity' },
  'transition-shadow': { transitionProperty: 'box-shadow' },
  'transition-transform': { transitionProperty: 'transform' },
      'duration-75': { transitionDuration: '75ms' },
  'duration-100': { transitionDuration: '100ms' },
  'duration-150': { transitionDuration: '150ms' },
  'duration-200': { transitionDuration: '200ms' },
  'duration-300': { transitionDuration: '300ms' },
  'ease-linear': { transitionTimingFunction: 'linear' },
  'ease-in': { transitionTimingFunction: 'cubic-bezier(0.4, 0, 1, 1)' },
  'ease-out': { transitionTimingFunction: 'cubic-bezier(0, 0, 0.2, 1)' },
  'ease-in-out': { transitionTimingFunction: 'cubic-bezier(0.4, 0, 0.2, 1)' },

  // Transforms
  'scale-90': { transform: 'scale(0.9)' },
  'scale-100': { transform: 'scale(1)' },
  'scale-110': { transform: 'scale(1.1)' },
  'rotate-45': { transform: 'rotate(45deg)' },
  'rotate-90': { transform: 'rotate(90deg)' },
  'rotate-180': { transform: 'rotate(180deg)' },

  // Interactivity
  'cursor-pointer': { cursor: 'pointer' },
  'cursor-not-allowed': { cursor: 'not-allowed' },
  'select-none': { userSelect: 'none' },
  'select-text': { userSelect: 'text' },
  'select-all': { userSelect: 'all' },

  // SVG
  'fill-current': { fill: 'currentColor' },
  'stroke-current': { stroke: 'currentColor' },
}

// Setup
const styleKeys = Object.keys(styleMap)

function getRandomClasses(count) {
  const classes = new Set();
  while (classes.size < count) {
    classes.add(styleKeys[Math.floor(Math.random() * styleKeys.length)]);
  }
  return Array.from(classes);
}

function composeStyle(styleKey) {
  return { ...styleMap[styleKey] }
}

// Test case 1: Always generating objects
function testAlwaysGenerate() {
  return cases.map(set =>
  	set.map((style) => composeStyle(style))
  )
}

// Test case 2: Using a cache
function testWithCache() {
  const cache = {};
  return cases.map(set =>
  	set.map(style => {
      if (!cache[style]) {
        cache[style] = composeStyle(style);
      }
      return cache[style];
    })
  )
}

const cases = []
for (let i = 0; i < iterations; i++) {
	cases.push(getRandomClasses(i % 15))
}
</script>

Test runner

Ready to run.

Testing in
TestOps/sec
Always Create
testAlwaysGenerate()
	.map(v => Object.assign({}, ...v))
ready
Always Cache
testWithCache()
	.map(v => Object.assign({}, ...v))
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.