batch

Group synchronous ref writes and flush their notifications after the callback.

batchObservation and Batch

Group synchronous ref writes and flush their notifications after the callback.

Overview

The batch function is used to batch multiple updates to refs, which can help optimize performance by reducing the number of observer notifications and triggers during a series of updates. When multiple changes to refs are made within a batch block, observers are only notified once, at the end of the batch.

Try it live

Same writes, different notification countsLive API
0Source value
0Observer callbacks

Choose an update strategy.

Each action adds three. Compare notification counts for the same amount of state change.

import { batch, endBatch, html, observe, ref, startBatch } from 'regor'

export function createBatching(interactive = false) {
  const source = ref(0),
    notifications = ref(0),
    value = ref(0)
  const mode = ref('Choose an update strategy.')
  observe(source, () => notifications(notifications() + 1))
  const update = (strategy: string) => {
    notifications(0)
    const writes = () => {
      for (let i = 0; i < 3; i++) source(source() + 1)
    }
    if (strategy === 'batch') batch(writes)
    else if (strategy === 'manual') {
      startBatch()
      try {
        writes()
      } finally {
        endBatch()
      }
    } else writes()
    value(source())
    mode(
      strategy === 'plain'
        ? 'Three separate writes'
        : strategy === 'batch'
          ? 'One batch callback'
          : 'startBatch + finally endBatch',
    )
  }
  return {
    interactive,
    notifications,
    value,
    mode,
    plain: () => update('plain'),
    grouped: () => update('batch'),
    manual: () => update('manual'),
  }
}

export const batchingTemplate = html` <div class="guide-demo">
  <div class="guide-session-bar">
    <button type="button" @click="plain" :disabled="!interactive">
      Three plain writes</button
    ><button type="button" @click="grouped" :disabled="!interactive">
      Use batch</button
    ><button type="button" @click="manual" :disabled="!interactive">
      Start / end batch
    </button>
  </div>
  <div class="guide-metrics api-metrics-pair">
    <div><output>{{ value }}</output><span>Source value</span></div>
    <div>
      <output>{{ notifications }}</output><span>Observer callbacks</span>
    </div>
  </div>
  <p class="guide-event" role="status">{{ mode }}</p>
  <p class="guide-hint">
    Each action adds three. Compare notification counts for the same amount of
    state change.
  </p>
</div>`
import { createApp, RegorConfig, useScope } from 'regor'
import { apiExamples } from './examples'

const element = document.getElementById('api-demo')
const name = element?.dataset.example
if (element && name && Object.hasOwn(apiExamples, name)) {
  const example = apiExamples[name as keyof typeof apiExamples]
  const scope = useScope<object>(() => example.create(true))
  const config =
    'config' in scope.context && scope.context.config instanceof RegorConfig
      ? scope.context.config
      : undefined
  createApp(scope, { element, template: example.template }, config)
}

Each action adds three to one ref. Compare plain writes, batch, and a manual start/end pair.

Usage

Batching Updates

To batch updates to refs, wrap the code that performs the updates within a batch function call. The batch function takes an updater function as an argument, and all updates made within the updater function are batched together.

import { batch, ref } from 'regor'

const myRef1 = ref(5)
const myRef2 = ref(10)

batch(() => {
  myRef1.value = 15
  myRef2.value = 20
})

// Observers are notified only once at the end of the batch
// Outputs:
// Observer triggered: 20

Parameters

  • updater: A function that contains the updates to refs that should be batched together. Any changes made to refs within this function will be batched.
Keep the update group synchronous

Use batch for a bounded set of related writes. Awaited work belongs outside that synchronous update group.

Notes

  • Batching updates with the batch function can help improve the performance of your application when multiple changes are made to refs in a short period. It reduces the number of observer notifications and triggers, which can be especially beneficial in situations with complex reactivity logic.

  • When using the batch function, observers associated with refs will be notified once, at the end of the batch, rather than for each individual update. This can lead to more efficient reactivity handling.

  • The batch function can be particularly useful when performing multiple ref updates within a loop or in response to user interactions.

  • Important: When using the batch function, keep in mind that reads of refs within the batch can return potentially stale or outdated values due to pausing auto-updates. Ensure that your code logic accounts for this situation when reading refs within a batch.

See Also

Related APIs and guides Continue with the references connected to batch.

Back to the API list