Sejak diumumkan, teknologi
WebAssembly telah segera menarik perhatian pengembang front-end. Komunitas web dengan antusias menerima gagasan menjalankan kode dalam peramban yang ditulis dalam bahasa selain JavaScript. Yang utama adalah WebAssembly menjamin kecepatan jauh lebih tinggi dari JavaScript.
Teknisi kami mengikuti perkembangan standar dengan cermat. Segera setelah dukungan WebAssembly 1.0 diimplementasikan di semua browser utama, para pengembang segera ingin mencobanya.
Tapi ada masalah. Meskipun
banyak aplikasi mendapat manfaat dari WebAssembly, ruang lingkup teknologi dalam e-commerce masih primitif. Kami tidak dapat segera menemukan versi penggunaan yang benar. Ada beberapa saran, tetapi JavaScript lebih baik di semua variasi. Ketika kami mengevaluasi teknologi baru di eBay, pertanyaan pertama adalah: "Apa manfaat potensial bagi pelanggan kami?" Jika tidak ada kejelasan di sini, kami tidak akan melanjutkan ke langkah berikutnya. Sangat mudah untuk terbawa oleh teknologi baru yang modis, bahkan jika itu tidak masalah bagi pelanggan dan hanya mempersulit alur kerja yang ada. Pengalaman pengguna selalu lebih penting daripada pengalaman pengembang. Tetapi dengan WebAssembly berbeda. Teknologi ini memiliki potensi yang sangat besar, kami tidak dapat menemukan use case yang tepat. Namun, pada akhirnya mereka tetap menemukannya.
Pemindai kode batang
Di aplikasi eBay asli di iOS dan Android, ada fitur pemindaian barcode
UPC untuk secara otomatis masuk ke dalam formulir. Ini hanya berfungsi dalam aplikasi dan membutuhkan pemrosesan intensif gambar pada perangkat untuk mengenali digit barcode dalam aliran gambar dari kamera. Kode yang dihasilkan kemudian dikirim ke layanan server, yang, pada gilirannya, mengisi formulir. Ini berarti bahwa logika pemrosesan gambar pada perangkat harus sangat efisien. Untuk aplikasi asli, kami mengkompilasi pustaka C ++ kami sendiri ke dalam kode asli untuk iOS dan Android. Ia mengenali barcode dengan sangat baik. Kami secara bertahap pindah ke API asli di iOS dan Android, tetapi pustaka C ++ kami masih dapat diandalkan.
Pemindai barcode adalah fungsi intuitif untuk penjual, ini secara signifikan menyederhanakan pengisian formulir. Sayangnya, fungsi ini tidak berfungsi pada versi seluler situs tersebut, dan penjual harus secara manual memasuki UPC, yang tidak nyaman.
Pemindai Kode Batang Web
Kami dulu mencari opsi untuk memindai barcode di web. Dua tahun lalu, mereka bahkan merilis prototipe berdasarkan
pustaka sumber terbuka
BarcodeReader JavaScript. Masalahnya adalah bahwa itu bekerja dengan baik hanya dalam 20% kasus. Sisa 80% dari waktu pemindai bekerja sangat lambat atau tidak berfungsi sama sekali. Dalam kebanyakan kasus, itu adalah batas waktu. Sangat diharapkan: JavaScript dapat dibandingkan dalam kecepatan dengan kode asli hanya jika berada di "jalur panas", yaitu sangat dioptimalkan oleh kompiler
JIT . Kuncinya adalah bahwa mesin JavaScript menggunakan banyak heuristik untuk menentukan apakah jalurnya "panas" tanpa menjamin hasil. Perbedaan ini jelas menyebabkan frustrasi pengguna, dan kami harus menonaktifkan fitur ini. Tapi sekarang semuanya berbeda. Dengan pesatnya perkembangan platform web, muncul pertanyaan: "Apakah mungkin untuk menerapkan pemindai barcode yang dapat diandalkan di web?"
Salah satu opsi adalah menunggu
API Deteksi Bentuk keluar dengan fitur deteksi gambar bawaannya, termasuk
barcode . Tetapi antarmuka ini masih pada tahap awal pengembangan dan jauh dari kompatibilitas lintas-browser. Dan bahkan dalam hal ini, bekerja di semua platform
tidak dijamin . Karena itu, Anda harus mempertimbangkan opsi lain.
Di sinilah WebAssembly ikut bermain. Jika pemindai kode batang diterapkan pada WebAssembly, maka dijamin akan berfungsi. Struktur pengetikan dan bytecode yang kuat dari WebAssembly memungkinkan Anda untuk selalu menjaga "jalur panas" eksekusi. Selain itu, kami sudah memiliki pustaka C ++ untuk aplikasi asli. Pustaka C ++ adalah kandidat ideal untuk kompilasi di WebAssembly. Kami pikir masalahnya sudah teratasi. Ternyata, tidak juga.
Arsitektur
Arsitektur prototipe yang berfungsi untuk pemindai barcode di WebAssembly cukup sederhana.
- Kompilasi pustaka C ++ dengan Emscripten . Ini akan menghasilkan middleware dan file .wasm.
- Pilih utas pekerja dari utas utama. Kode JavaScript untuk pekerja mengimpor kode tautan JavaScript yang dihasilkan, yang pada gilirannya menciptakan file .wasm.
- Streaming utama mengirimkan snapshot dari stream dari kamera ke stream pekerja, dan itu akan memanggil API WASM yang sesuai melalui kode penghubung. Respons API diteruskan ke utas utama. Respons dapat berupa string UPC (yang diteruskan ke backend) atau string kosong jika tidak ada barcode yang terdeteksi.
- Untuk jawaban kosong, langkah di atas diulangi sampai barcode terdeteksi. Siklus ini berjalan untuk interval waktu yang ditentukan dalam detik. Setelah ambang tercapai, kami akan menampilkan pesan peringatan โKode produk tidak valid. Coba cari barcode atau teks lain . " Entah pengguna tidak memfokuskan kamera pada barcode asli, atau pemindai tidak cukup efektif. Kami melacak statistik batas waktu sebagai indikator kualitas pemindai.

Web Alur Kerja PerakitanKompilasi
Langkah pertama dalam setiap proyek WebAssembly adalah menentukan pipa kompilasi yang jelas. Emscripten telah menjadi standar de facto untuk mengkompilasi WebAssembly, tetapi penting untuk memiliki lingkungan yang konsisten yang menghasilkan hasil deterministik. Frontend kami didasarkan pada Node.js, jadi kami perlu mencari solusi yang kompatibel dengan alur kerja npm. Untungnya, sekitar waktu itu,
Surma Das menerbitkan sebuah artikel
berjudul "Emscripten and npm" . Pendekatan berbasis
Docker untuk mengkompilasi WebAssembly masuk akal karena menghilangkan satu ton overhead. Seperti yang direkomendasikan dalam artikel, kami mengambil
gambar buruh pelabuhan
Emscripten dari
trzeci . Untuk mengaktifkan kompilasi di WebAssembly, pustaka C ++ asli harus di-tweak sedikit. Pada dasarnya, kami bertindak secara acak, coba-coba. Pada akhirnya, saya berhasil mengompilasinya, dan juga mengatur alur kerja WebAssembly yang rapi dalam pipa perakitan yang ada.
Ini bekerja cepat, tetapi ...
Kinerja pemindai diukur dengan jumlah frame yang diproses oleh Wasm API per detik. API Wasm mengambil bingkai dari aliran video kamera, melakukan perhitungan, dan mengembalikan respons. Ini dilakukan secara berkelanjutan hingga barcode terdeteksi. Kinerja diukur dalam FPS.
Implementasi pengujian kami atas WebAssembly menunjukkan kecepatan luar biasa 50 FPS. Namun, itu hanya bekerja di 60% kasus, dan sisanya jatuh karena batas waktu. Bahkan dengan FPS setinggi itu, mereka tidak dapat dengan cepat mendeteksi kode batang untuk sisa 40% pindaian, memberikan pesan peringatan di bagian akhir. Sebagai perbandingan, implementasi JavaScript sebelumnya biasanya berjalan pada 1 FPS. Ya, WebAssembly jauh lebih cepat (50 kali), tetapi untuk beberapa alasan itu tidak bekerja di hampir setengah kasus. Perlu juga dicatat bahwa dalam beberapa situasi, JavaScript bekerja dengan sangat baik dan segera menemukan kode batang. Salah satu opsi yang jelas adalah untuk meningkatkan batas waktu, tetapi ini hanya akan meningkatkan frustrasi pengguna, sehingga kami tidak memecahkan masalah sebenarnya. Karena itu, kami meninggalkan ide ini.
Pada awalnya, kami tidak dapat memahami mengapa pustaka C ++ asli, yang bekerja dengan sempurna dalam aplikasi asli, tidak menunjukkan hasil yang sama di web. Setelah pengujian dan debugging yang panjang, kami menemukan bahwa kecepatan pengenalan tergantung pada sudut fokus objek dan bayangan latar belakang. Tetapi bagaimana kemudian semuanya bekerja di aplikasi asli? Faktanya adalah bahwa dalam aplikasi asli kami menggunakan API bawaan untuk fokus otomatis dan memberi pengguna kesempatan untuk fokus secara manual dengan mengarahkan jari ke barcode. Oleh karena itu, aplikasi asli selalu menyediakan perpustakaan dengan gambar yang jelas berkualitas tinggi.
Menyadari esensi dari apa yang terjadi, kami memutuskan untuk mencoba perpustakaan asli lain: pemindai kode batang
ZBar sumber terbuka yang cukup populer dan stabil. Lebih penting lagi, ini bekerja dengan baik dengan gambar buram dan kasar. Mengapa tidak mencobanya? Karena kami sudah memiliki alur kerja WebAssembly, kompilasi dan penyebaran ZBar di WebAssembly berjalan dengan lancar. Kinerja ternyata lumayan, sekitar 15 FPS, meskipun tidak sebagus perpustakaan C ++ kami sendiri. Tetapi tingkat keberhasilannya mendekati 80% untuk batas waktu yang sama. Peningkatan yang jelas atas pustaka C ++ kami, tetapi masih belum 100%.
Hasilnya belum memuaskan kami, tetapi kami melihat sesuatu yang tidak terduga. Di mana Zbar crash, pustaka C ++ kami sendiri melakukan pekerjaan dengan sangat cepat. Itu adalah kejutan yang menyenangkan. Tampaknya perpustakaan memproses gambar dengan kualitas berbeda dengan cara yang berbeda. Ini membawa kami ke ide.
Multithreading dan balap cepat
Anda mungkin sudah mengerti. Mengapa tidak membuat dua utas pekerja: satu untuk Zbar dan satu untuk pustaka C ++ kami, dan tidak menjalankannya secara paralel. Siapa pun yang menang (siapa pun yang terlebih dahulu mengirim barcode yang valid) mengirimkan hasilnya ke aliran utama, dan kedua pekerja berhenti. Kami menerapkan skenario seperti itu dan mulai menguji diri kami, mencoba mensimulasikan sebanyak mungkin skenario. Pengaturan ini menunjukkan 95% dari pemindaian yang berhasil. Jauh lebih baik dari hasil sebelumnya, tetapi masih belum 100%.
Salah satu saran aneh adalah menambahkan perpustakaan JavaScipt asli ke kompetisi. Itu akan menjadi tiga aliran. Kami jujur โโtidak berpikir bahwa ini akan mengubah apa pun. Namun pengujian semacam itu tidak memerlukan upaya apa pun, karena kami menstandarisasi antarmuka yang berfungsi. Yang mengejutkan kami, dengan tiga aliran, tingkat keberhasilannya benar-benar mendekati 100%. Sekali lagi ini benar-benar tidak terduga. Seperti yang disebutkan sebelumnya, JavaScript bekerja sangat baik dalam beberapa situasi. Rupanya, dia menutup celah itu. Jadi kearifan populer dari hukum adalah
"JavaScript selalu menang .
" Jika tanpa lelucon, ilustrasi berikut ini memberikan gambaran arsitektur final yang telah kami terapkan.
Pemindai kode batang arsitektur webGambar berikut menunjukkan diagram fungsional tingkat tinggi:
Diagram fungsional pemindai barcodeCatatan Pemuatan Sumber Daya
Sumber daya yang diperlukan agar pemindai berfungsi sudah dimuat sebelumnya setelah merender halaman utama. Dengan cara ini, halaman arahan memuat dengan cepat dan siap untuk interaksi. Sumber daya WebAssembly (file wasm dan skrip middleware) dan pustaka pemindai JavaScript dimuat sebelumnya dan di-cache menggunakan
XMLHttpRequest setelah memuat halaman utama. Penting di sini bahwa mereka tidak dieksekusi segera untuk membiarkan utas utama gratis untuk interaksi pengguna dengan halaman. Eksekusi hanya terjadi ketika pengguna mengklik ikon barcode. Jika pengguna mengklik ikon sebelum memuat sumber daya, mereka akan dimuat sesuai permintaan dan segera dieksekusi. Penangan kejadian pemindai barcode dan pengontrol pekerja dimuat dengan halaman, tetapi mereka sangat kecil.
Hasil
Setelah pengujian yang ketat dan penggunaan internal oleh karyawan, kami meluncurkan pengujian A / B pada pengguna. Ikon pemindai (tangkapan layar di bawah) ditunjukkan ke grup uji, tetapi tidak ke grup kontrol.
Produk akhirUntuk mengukur keberhasilan, kami memperkenalkan metrik Draft Completion Rate. Ini adalah waktu antara mulai mengedit draf dan mengirimkan formulir. Metrik harus menunjukkan bagaimana pemindai barcode membantu orang mengisi formulir. Tes berlangsung beberapa minggu, dan hasilnya sangat menyenangkan. Mereka sepenuhnya konsisten dengan hipotesis asli kami.
Waktu penyelesaian konsep berkurang 30% untuk streaming dengan pemindai barcode.Hasil Tes A / BKami juga menambahkan profiling untuk mengevaluasi efektivitas semua jenis pemindai. Seperti yang diharapkan, kontribusi terbesar dibuat oleh Zbar (53% dari pemindaian yang berhasil), kemudian pustaka C ++ kami (34%) dan, akhirnya, pustaka JavaScript dengan 13%.
Kesimpulan
Pengalaman menerapkan WebAssembly telah menjadi sangat informatif bagi kami. Insinyur sangat senang dengan kemunculan teknologi baru dan segera ingin mencobanya. Jika teknologi ini juga berguna bagi pelanggan, maka ini adalah kesenangan ganda. Mari kita ulangi pemikiran yang diungkapkan di awal artikel. Teknologi berkembang dengan sangat cepat. Setiap hari sesuatu yang baru muncul. Tetapi hanya beberapa teknologi yang penting bagi pelanggan, dan WebAssembly adalah salah satunya. Kesimpulan terbesar kami dari latihan ini adalah mengatakan "tidak" dalam 99 situasi dan "ya" dalam satu-satunya kasus ketika itu benar-benar penting bagi klien.
Di masa depan, kami berencana untuk memperluas penggunaan pemindai barcode dan memperkenalkannya di sisi pembeli, sehingga mereka dapat memindai kode produk secara offline untuk pencarian dan pembelian di eBay. Kami juga akan mempertimbangkan untuk memperluas fungsi menggunakan Shape Detection API dan fungsi lainnya di browser. Tetapi kami senang telah menemukan kasus penggunaan yang tepat untuk WebAssembly di eBay dan berhasil menerapkan teknologi dalam e-commerce.
Terima kasih khusus kepada Surma Das dan
Lin Clark untuk banyak artikel di WebAssembly. Mereka benar-benar membantu kami memecahkan kebuntuan beberapa kali.