BBV logo

Size matters - Halving a react-qr-reader bundle size

Manuel Tuero

06 April, 2020 - 3 min read

Context

In the last few weeks, the team has been involved in the great challenge of optimizing a PWA so it would be able to run smoothly on a low end Android device.

As part of the achieved results, the bundle size has been reduced by 70%, without removing any of the existing features.

The opportunity

One of the features the app has is a QR code reader. In that way, we found that the used library was a bit heavy for our app. So we decided to focus on that and started by inspecting the library code.

And then, it was time to act.

The decisions

First: Define the component to export

While inspecting QR scan library code, we found there were two exported components: Default and Legacy mode. The only difference between both were the input method of the QR code, but functionality was the same. So we decided to decouple them and remove unnecessary code.

It allowed us incrementing library maintainability and reducing total bundle size.

Second: Component updating

We found that the major part of the components was using classes and React lifecycle methods like componentDidMount or componentDidUpdate.

So, the next step was changing these classes to functional components and hooks. Letting the functional component with HTML markup and delegating all the logic on the hook. Therefore, we aim for the React target to be versions that support hooks.

This benefits us in two ways: decrementing components size and separating logic from the view.

Third: Updating dependencies

Many dependencies were old, so we bet to update them.

The key was reducing the probability of bugs associated with these old libraries, and incrementing the maintainability of our library.

Fourth (the Strong Dish): Improving the performance

At this point, first we needed to understand what were made wrong in the library.

We found there was an excessive use of the setTimeout function without cleaning the generated ids. This produced that they remained callbacks queued post-processing.

Then, our next decision was moving from setTimeout to requestAnimationFrame. This gave us an advantage since the scan callback started to be executed in moments when the browser does not use the capacity of computing to render frames, producing an improvement on the camera stream fluency and avoiding main thread block.

The last but not least decision associated with performance was using web workers in QR processing.

Fifth: Debugging mode

Library didn’t have any way of giving information to the dev about what was happening, how it worked or scanned. So it was so difficult trying to find an issue while debugging.

This helped us to take this decision: adding a debugging property to the component to start logging useful data that could explain what was happening or failing.

Sixth: Extend the Viewfinder

We found that the library provides support for a Viewfinder to show a frame that indicates the distance and center while scanning the QR. This frame was developed with a div and inline-styles.

In order to give it extensibility, we decided to transform a component into an SVG that could be edited as needed. In addition, we are going to extend Viewfinder capabilities, allowing it to be displayed or not and receiving a custom component.

The result

Finally, we published @blackbox-vision/react-qr-reader with all the mentioned optimizations.

All these changes resulted in reducing bundle size from 210.6 KB to 88.3 KB!

This implies a reduction of almost 60% of the weight of the library. This reduction in weight, results in a component that loads several times faster and whose average QR reading capacity is up to about 50 cm away at least.

Next steps

For the next versions, we have in mind:

  • Give support of QR scan to multi-camera cell phones.
  • Reduction of the weight of the lib to be able to weigh about 60 KB.
  • Be able to improve debug logs to make them more useful.
  • Extend the ViewFinder to be able to receive a custom render.
  • Remove inline-styles by CSS
Thanks a lot for your time 😁 Contact us for any suggestion or comments!
If you are interested into library development, stay tuned! We will be publishing a blog post series soon 🎉!

Manuel Tuero

I'm CTO and co-founder of BlackBox Vision. I consider myself a passionate and constant person who likes challenges and help other people.

Subscribe for latest updates

Sign Up for our newsletter and get notified when we publish new articles for free!

Maybe you could be interested to read