How to Make a Barcode Scanner App Performant

| Developers

sparkscan making barcode scanning performant on device

Many developers invest effort into building up the features of their barcode scanner app and only shift to performance optimization if there’s time left in the release cycle. Or they wait for user complaints before tuning settings and code.

This blog aims to change that behavior by explaining various deployment and API options for improving barcode scanning performance, and how they impact user workflows. The last thing you want is for users to come back to you, saying, “It takes too long to scan” or “I’m forced to repeat scans to get the right information.” You can also find out more about how to measure barcode scanning performance in our in-depth best practice guide.

Below, you’ll find performance tuning options that apply to any web-based barcode scanning library, using specific examples from:

  • Scandit SparkScan API — an easy-to-deploy interface providing pre-built and optimized barcode scanning with a minimalistic UI that floats on top of any app.
  • Scandit Barcode Capture API — the full set of features allowing deeper customization of the barcode scanning experience, but requiring greater time investment and in-house computer vision expertise.

We’ve focused on web applications in this blog, but these techniques will work for all development frameworks that Scandit supports, including those for iOS and Android native applications. Scandit’s barcode scanning software supports all major frameworks and programming languages.

What does performance mean when you’re building a barcode scanner app?

The belief that a barcode scanner app “just works” is common, especially if you’ve never deployed one under real-world conditions before.

Knowing how to make a barcode scanner app performant depends on how you manage the quirks of its operating environment (barcode types and number, lighting conditions, user training, and more). This in turn will depend on the many small configuration options, UX choices, and features you deploy.

So what does “performance” mean in this context? Software performance tests usually measure the stability, speed, scalability, and responsiveness of an application under a given workload. The focus of this blog is on speed and responsiveness, as stability and scalability have more to do with application architecture and other tasks on the device unrelated to barcode scanning.

For barcode scanning, this means:

  • Load time: how long it takes to load the barcode scanner library (e.g., the time between the user pressing a button and the app showing the scanning interface).
  • User capture time: The time it takes for users to isolate, focus, and initiate capture of a barcode label. This is influenced by camera resolution and tuning, as well as the UI controls you provide to allow users to access and trigger barcode scanning. Poorly designed barcode scanning UI is one of the biggest factors in users’ perception of slow barcode scanning speed.
  • Response time: how long it takes for the barcode scanner to detect and decode a barcode, and present results. This includes how well the barcode scanner adapts to different environmental conditions, such as wide angles, long distances, low light, tiny barcodes, and multiple barcodes in view.
  • Resource usage: how much CPU, memory, and battery resources are used.

All these factors directly impact how quickly users can scan barcodes and how often they must repeat scans. Real-world scanning happens in challenging environmental conditions. For example, imagine a busy warehouse with thousands of daily shipments and shelves crowded with packages and barcodes, or a poorly lit storeroom at the back of a retail facility.

How Scandit barcode scanning software works

To help understand the code samples presented here, you should know the basics of Scandit’s software components and setup:

SparkScan API

  1. SparkScanSettings sets up the enabled symbologies, SparkScan mode, and listeners that are informed whenever a new barcode is scanned.
  2. SparkScanView to set up various user interface options.

Barcode Capture API

  1. DataCaptureContext manages barcode scanning and general configuration options.
  2. DataCaptureView to set up user interface and camera settings.

Configuring barcode scanning build and deployment

Why this matters: By optimizing app artifacts and resources, you help users activate barcode scanning faster. In some situations, it’s also easier to update resources before the app is in production, versus having to release a new version of the app later.

Before releasing your barcode scanner app, follow these steps to reduce library load times:

  • Locate all resources, including libraries, images, and configuration files, on a server under your control to minimize the impact of downtimes and Internet delays associated with third-party servers. With Scandit software, all processing happens on device, so you don’t need to worry about connectivity or security for in-transit data.
  • Compile in WebAssembly (Wasm), which uses a compact binary format (.wasm) that is highly efficient in size and load times, for faster downloads and reduced latency. ( SparkScan does this for you.)
  • Serve all web assets compressed and with caching enabled by your web server.
  • Ensure optimal image compression that balances processing overhead with scanning quality. (If using Scandit, this is handled by Scandit SparkScan.)

For web apps, if the user’s browser is under your control, you can set it to use GPU acceleration for faster and more accurate barcode localization at challenging positions and angles. You can also explore technologies like WebGL or WebGPU to take advantage of a device’s GPU.

sparkscan package picking scanning mobile device

30-Day free trial

Test Scandit's fast, accurate, and reliable barcode scanning performance for yourself.

Optimizing application launch

Why this matters: Decreasing barcode scanner load times means users can do their jobs faster. While load times are affected by other tasks on the device (such as operating system activities and foregrounded apps), doing as much optimization work as you can upfront reduces issues down the road.

Web-based barcode scanning libraries are usually downloaded from a server, compiled, cached, and loaded into a browser session’s memory. Once cached, the library must be loaded by the page using it, usually upon user request.

The speed with which this process happens depends on several factors that can be tuned for performance. Here are some tips to reduce application launch times:

  • Pre-load and pre-compile libraries in the application background to avoid making the user wait for a response when they activate barcode scanning. Ideally, this happens when the page is loaded, regardless of whether the user activates barcode scanning.
  • Configure and initialize the barcode scanner library as early as possible to ensure it’s loaded and ready to go when the user needs it. For Scandit software, this is done using the configure() method.
  • If the device supports it, use the camera’s standby state to minimize delays. Depending on the device, the transition between the camera’s standby and on states can be between 50% to 90% faster than the transition between off and on.
  • Create a hidden and paused scanner instance in the background with the camera in a standby state. This avoids the user waiting for the app to create the instance on the fly. SparkScan does this for you; for Barcode Capture this looks like:
// Disable the barcode capture mode until the camera is accessed.
await barcodeCapture.setEnabled(false);
await camera.switchToDesiredState(FrameSourceState.Standby);

When the user wants to start scanning, reverse these steps:

// Switch the camera on to start streaming frames.
// The camera is started asynchronously and will take some time to completely turn on.
await camera.switchToDesiredState(FrameSourceState.On);
// Enable the barcode capture mode 
await barcodeCapture.setEnabled(true);
  • Reuse the existing scanner instance whenever possible by hiding/pausing and showing/resuming it instead of destroying and recreating it.

Reducing battery consumption

To minimize battery consumption, ensure the camera is on only when needed. SparkScan does this for you; for Barcode Capture, follow the “disable” code sample above with FrameSourceState set to Off.

You can also use SparkScan’s battery saving mode, enabled through the batterySaving property of SparkScanSettings. This mode is set to automatic by default, where SparkScan automatically enters battery saving mode when it detects abnormal battery consumption, but you can force it on at any time.

Tuning barcode capture when making a barcode scanner app

Why this matters: Optimizing capture times means users can move faster between items and reduce frustrations due to slow app response. Adjusting the UI to make scanning easier improves user satisfaction and can reduce the risk of mis-scans.

Barcode scanning follows six discrete steps as the user interacts with the device and software, as illustrated below. Each step offers opportunities for UI and performance improvements based on the user’s needs and environment.

making barcode scanning performant timeline

The following describes different actions you can take to improve barcode capture performance for all six of these steps.

Restrict the active scan area

The region within the camera’s field of view where the barcode scanner searches for labels is called the “active scan area.” Regions not covered by the active scan area are ignored.

Restricting this area helps capture barcodes in cluttered environments, and improves performance as less information needs to be processed. On lower-end devices, limiting the scan area can have a significant impact on CPU overhead.

With SparkScan, the active scan area is set by the user if you enable the control using the previewSizeControlVisible property of SparkScanView.

Restrict the active symbologies

Barcode scanning libraries are usually capable of reading multiple different types of barcodes, often referred to as symbologies (e.g., EAN Code, Code 39, and QR Code).

Different industries and use cases use specific symbologies. Limiting the active symbologies to only those needed by your users reduces application overhead, and also the chances of misidentifying a label.

With SparkScan, you can set the active symbologies through SparkScanSettings:

const settings = new SparkScanSettings();
settings.enableSymbologies([Symbology.EAN13UPCA]);

If you don’t know the correct symbologies for your use case, SparkScan makes setting them easy. Through capture presets, you can enable different sets of symbologies tailored for different industry verticals. For example, if your barcode scanner is used for retail and logistics, you can enable the RETAIL and LOGISTICS capture presets without setting individual symbologies manually.

Additionally, SparkScan and Barcode Capture prioritize symbologies based on your scanning behavior. Regardless of the symbologies you set, this prioritization helps improve scanning performance based on actual use.

Set the default zoom factor

In environments where scanning distances between the device and the label tend to be longer, setting the camera’s default zoom factor makes centering and focusing on the barcode easier. Starting users off “zoomed in,” for example, means they don’t need to zoom in themselves.

With SparkScan, the default zoom factor is set using the ZoomFactorOut property. The ZoomFactorIn property specifies the zoom factor to move to when the user taps the zoom control. This control is enabled by default.

For Barcode Capture, users can zoom in with a swipe gesture on the preview screen, making it easier to locate barcodes.

Handle barcode scanning errors gracefully

It’s important to define your success and failure criteria for barcode scanning and know how your library implements its validation criteria. For Scandit use cases and software, there are three definitions:

  • Unwanted barcodes: Barcodes that do not match the requirements of your specific use case or have already been captured (duplicates). For example, a Code 11 barcode label would be unwanted in most retail stores using UPC barcodes. To mitigate this issue, follow the steps above to restrict the active symbologies used by your app.
  • Unintended barcodes: These may be valid for your use case, but the user does not want to capture them. For example, barcodes that have already been scanned, or accidentally capturing a barcode affixed to a product next to the one the user is trying to scan would be considered unintended.
  • Rejected barcodes: These are barcodes that the scanning software rejects due to its configuration or capability. Examples include barcode symbologies outside the active range, and situations where the label cannot be captured. The Barcode Capture API has a list of rejection reasons here.

Here’s how to handle these conditions:

Unwanted and rejected barcodes

If users scan barcodes with identical data, you may need to adjust the scanner software to filter these duplicates out.

All Scandit barcode scanning software has a built-in duplicate filter, set by specifying a time interval where barcodes with the same data are ignored. The default interval is 1000 ms.

The ability to automatically reject barcodes will save the user from manually filtering them out, whether they are duplicates, belong to items outside the scope of the task, or for other scenario-specific reasons.

SparkScan supports this capability through its built-in error state. By setting SparkScanBarcodeErrorFeedback.resumeCapturingDelay to 0, it will immediately resume scanning without pausing on rejected codes.

Avoid unintended scans

You can reduce the user’s time spent on unwanted barcodes by designing a UX workflow that breaks the scanning operation down into discrete “scan” and “stop scan” steps (this also helps to extend battery life).

For SparkScan, setting the scanning behavior to single mode starts and stops sessions after every scan. Continuous mode keeps the session active for a longer duration.

For the Barcode Capture API, this would look like:

  1. Starting the scanner in paused mode, where the camera preview is on but the capture mode is disabled.
  2. Use a button to enable scanning when the user presses it. When the scanner is active, the button is grayed out, and “Scanning” is displayed to avoid an unintended scan.
  3. When a barcode is scanned, disable scanning by putting the camera in standby mode. This ensures the user is not scanning other barcodes and reduces battery consumption.
  4. To scan again, the user must click on the button again.

Smart Scan Intention: Intelligent reduction of unintended scans

Scandit’s barcode scanning software also includes the Smart Scan Intention feature, which uses advanced AI algorithms to anticipate and capture the user’s target barcode — even if multiple barcodes are clustered in a grocery aisle or on a warehouse shelf.

Even when aiming and focus are imperfect, Smart Scan Intention captures the desired barcode by pulling in contextual data such as device movement and barcode characteristics. This reduces unwanted scans by up to 100%.

Smart Scan Intention is either on or off, and is enabled by default in SparkScan.

User controls

An important aspect of performance tuning lies somewhat outside your hands: allowing the user to tune their own experience. Some users may find it easier to capture barcodes using the device’s hardware button or work faster if the scanner operates continuously rather than requiring single-shot captures.

You can configure SparkScan to allow users to customize their scanning experience by toggling visibility on or off for these controls:

  • Target mode: enables target mode; useful for scanning barcodes at longer distances without having to bend down low or reach up high.
  • Continuous mode: switch between single (sessions stop after each scan) and continuous (sessions remain active for a longer time) capture modes.
  • Torch: toggle the device’s torch (flashlight) on and off.
  • Zoom: toggle the zoom switch control on and off.

Don’t forget application shutdown

Performance optimization includes ensuring your barcode scanner doesn’t impact other apps and processes upon exit. A graceful shutdown follows a controlled process of terminating the app such that resources are released properly, ongoing tasks are completed, and no data loss or corruption occurs.

Two items to remember are:

  • Use the destroy() methods on barcode scanning objects to ensure all resources are cleaned up.
  • Close all browser connections to ensure no potential security exploits are left exposed.

Now you know how to make your barcode scanner app performant

The success of your barcode scanner app isn’t found under ideal conditions, it’s measured by how it performs under duress. Knowing your options at each step of the barcode scanning app lifecycle helps you choose what to tune in advance, and better isolate user-reported performance issues when you’re in production.

The techniques presented here will benefit almost any barcode scanning app. Choosing the optimization tips that will have the most impact should start by understanding your business environment and users – these needs will map to one or more of the sections above.

SparkScan has many of these optimizations built-in, so you don’t have to worry about configuring or testing them.

To try fast, accurate, and reliable barcode scanning performance for yourself using SparkScan or Barcode Capture, sign up for a free 30-day trial of the Scandit Data Capture SDK.

sparkscan package picking scanning mobile device

30-Day free trial

Test Scandit's fast, accurate, and reliable barcode scanning performance for yourself.