大约一年前,我们开始开发基于 Web 的移动应用程序开发,目标是在移动 Web 浏览器中运行。简而言之,移动应用程序是关于通过扫描二维码来定位特定仓库库存的工具。

这是我们应用程序的主要流程

1.从请求浏览器HTML5权限打开设备原生摄像头

  1. 捕获二维码并从该图像中获取文本

3.发送扫描文本到服务器

  1. 如果代码存在于数据库中,导航到该库存详细信息页面。

看起来很简单,就是这样!

开始

我们以一个简单的 React.js 应用程序开始这个项目,并使用jsQR库从捕获的图像中获取二维码文本。

在桌面上它工作得很好。每当我们尝试从笔记本电脑的网络摄像头扫描二维码时,它都能立即运行,没有任何问题。所以我们认为就是这样!但事实证明,在移动设备上处理以100010 window.requestAnimationFrame 100011 100009频率捕获的图像对于移动设备 CPU 来说是一项艰巨的任务。所以我们开始考虑以某种方式调整这个过程以获得最佳性能而不冻结 UI 线程。

想法 1:获得更少的图像帧

window.requestAnimationFrame回调适用于设备在动画期间可以处理的最短时间。在大多数移动设备中,网络动画帧约为 20-24 帧/秒,这意味着回调将每 50 毫秒触发一次,并且在每次回调时,我们将使用 jsQR 处理捕获相机帧。如果考虑到现在大多数设备都以 4K 图像质量拍摄照片,这对于移动设备来说是一项极其艰巨的任务。

我们想,也许我们会停止使用window.requestAnimationFrame,而是使用setInterval来提供更多的睡眠时间,从而每秒获得更少的图像。

这实际上提高了性能! 但是突然大部分二维码识别停止工作,尤其是在光线不好的情况下。经过一些调试和尝试其他应用程序后,我们了解到 jsQR 的原理是每秒解析大量图像以捕获至少一张包含足够像素数据的图像以提取 QR 码内容。因此需要使用window.requestAnimationFrame捕获图像以获得更可靠的 QR 码解析器应用程序。

想法2:让WebWorkers使用并发

这个想法是让 WebWorker 可用于处理来自主应用程序框架的图像框架,将其放入某个队列数组中,并开始使用 jsQR 处理它们,然后当找到文本时,将该字符串发送回主应用程序线程。

在这种情况下,当每秒捕获大量帧时,按照设计,在 jsQR 同步处理期间 UI 不会冻结,该部分将由单独的 WebWorker 线程处理。

![](data:image/svg+xml,%3csvg%20xmlns=%27http://www.w3.org/2000/svg%27%20version=%271.1%27%20width=%27800%27%20height=%27495%27/%3e)JavaScript 二维码扫描器

<img altu003d"JavaScript 二维码扫描器" srcsetu003d"/_next/image?urlu003dhttps%3A%2F%2Fcdn.hackernoon.com%2Fhn-images%2F0*3hxR69eHO4UPs2eH.png&wu003d828&qu003d75 1x, / _next/image?urlu003dhttps%3A%2F%2Fcdn.hackernoon.com%2Fhn-images%2F0*3hxR69eHO4UPs2eH.png&wu003d1920&qu003d75 2x" srcu003d"/_next/image?urlu003dhttps%3A% 2F%2Fcdn.hackernoon.com%2Fhn-images%2F0*3hxR69eHO4UPs2eH.png&wu003d1920&qu003d75" 解码u003d"async" data-nimgu003d"intrinsic" styleu003d"position:absolute;top:0;left:0;底部:0;右侧:0;框尺寸:边框框;填充:0;边框:无;边距:自动;显示:块;宽度:0;高度:0;最小宽度:100%;最大宽度:100%;最小高度:100%;最大高度:100%;object-fit:contain" classu003d"image" loadingu003d"lazy">

JavaScript 二维码扫描器

JavaScript 二维码扫描器

这很完美!

QR 码解析开始工作没有任何问题,即使在低性能的 Android 设备上也是如此。

经验教训

大多数 Web 开发都发生在单线程中,直到您不必让同步操作阻塞整个 UI 之前都可以,很遗憾大多数 UI 开发人员没有并行编程经验。

WebWorkers 将我们的 Web 项目免于将其嵌入到 Cordova 中,这太棒了。但通常,您不需要将它们用于所有事情。它们有一些限制,并且可以做一些基本的事情,尤其是不能从主线程调用函数并且不能访问document or window个对象,这意味着它们只有在你有一些同步操作想要卸载时才非常有用从用户界面。

我的 QR Code React 组件在这里Github — Reactive QR

别忘了鼓掌! 👏和分享! 🔗

Logo

React社区为您提供最前沿的新闻资讯和知识内容

更多推荐