Halo, Habr! Saya sajikan kepada Anda terjemahan dari
posting Dan Abramov
"The Elements of UI Engineering" pada masalah dan tugas kontemporer yang harus diselesaikan dalam antarmuka yang baik. Penulis memeriksa masalah mendasar dalam pengembangan antarmuka, interpretasi dan solusi yang sendirian - tanpa menggunakan perpustakaan dan kerangka kerja yang sudah jadi - dapat memberikan pemahaman mendalam tentang solusi di bidang pengembangan frontend yang ada di pasar.

Catatan PenerjemahTeks ditulis dan diterjemahkan sebagai orang pertama. Penulis asli dalam bahasa Inggris adalah
Dan Abramov , pengembang perpustakaan React untuk membangun antarmuka pengguna yang kompleks.
Dalam
publikasi terakhir saya
, saya menulis tentang pentingnya bisa mengenali kesenjangan dalam pengetahuan seseorang. Mungkin sepertinya aku menawarkanmu alasan untuk menjadi biasa-biasa saja. Tidak semuanya! Namun pada kenyataannya, pengetahuan kita adalah topik pembicaraan yang luas.
Saya yakin bahwa Anda dapat memulai pengetahuan Anda “langsung” dan tidak perlu mempelajari teknologi (tumpukan teknologi untuk pengembangan web - sekitar Penerjemah) dalam urutan tertentu. Tetapi saya juga percaya bahwa akumulasi pengalaman dan keterampilan profesional di bidang yang dipilih sangat penting. Secara pribadi, saya selalu paling tertarik untuk membuat antarmuka pengguna.
Dan saya bertanya-tanya apa yang saya pahami dan apa yang saya temukan penting? Tentu saja, saya kenal baik dengan teknologi seperti Javascript dan Bereaksi. Namun, hal paling penting yang datang dengan pengalaman sulit dipahami dan biasanya hilang ketika mencoba mengartikulasikan mereka secara akurat. Saya tidak pernah mencoba memasukkannya ke dalam kata-kata. Ini adalah upaya pertama saya untuk mensistematisasikan dan menggambarkan beberapa di antaranya.
Saat ini, ada banyak cara untuk mempelajari teknologi. Perpustakaan mana yang bertaruh pada 2019? Dan pada tahun 2020? Haruskah saya mempelajari Vue atau React? Atau sudut? Bagaimana dengan Redux atau Rx? Apakah saya perlu belajar Apollo? ISTIRAHAT atau GraphQL? Mudah tersesat di sini! Selain itu, penulis mungkin juga salah.
Prestasi terbesar saya dalam kognisi tidak terkait dengan teknologi tertentu. Saya mulai lebih mengerti ketika saya sedang memecahkan masalah UI (Antarmuka Pengguna - sekitar. Penerjemah) tertentu. Pada saat yang sama, kadang-kadang saya menemukan perpustakaan dan pola orang lain yang membantu saya memecahkan masalah. Dan terkadang dia menulis keputusannya sendiri (baik dan buruk).
Kombinasi ini - yang terdiri dari
memahami masalah , bereksperimen dengan
alat dan menerapkan berbagai
solusi - memberi saya pengalaman dan keterampilan yang paling berharga.
Posting ini hanya berfokus pada masalah yang saya bahas dalam pengembangan antarmuka pengguna.
Jika Anda mengembangkan antarmuka pengguna, maka kemungkinan besar Anda menemukan beberapa masalah ini - langsung atau saat menggunakan perpustakaan. Dalam kedua kasus, saya sarankan Anda bekerja pada aplikasi sederhana tanpa perpustakaan sama sekali, cobalah untuk mereproduksi dan menyelesaikan masalah ini. Tidak ada satu solusi yang benar untuk mereka. Pengalaman datang dengan mengenal masalah-masalah ini dan mengeksplorasi solusi yang mungkin, mengingat kekuatan dan kelemahan masing-masing.
Konsistensi
Anda menyukai pos dan tulisan itu muncul: "Anda dan 3 teman Anda lebih menghargainya." Anda mengklik tombol Suka lagi dan tulisan itu menghilang. Kedengarannya mudah! Tetapi ada kemungkinan bahwa prasasti semacam itu ada di beberapa tempat di layar. Ada kemungkinan bahwa ada juga indikasi visual tambahan untuk sejenisnya (misalnya, warna latar belakang tombol), yang juga harus berubah. Dan daftar "likers", yang sebelumnya diterima dari server dan ditampilkan ketika Anda mengarahkan mouse, sekarang harus menyertakan nama Anda. Dan jika Anda pergi ke bagian lain atau mengklik tombol Kembali, maka pos tersebut tidak boleh “lupa” bahwa ia memiliki kesukaan Anda. Seperti yang Anda lihat, bahkan integritas lokal untuk satu pengguna membuat sejumlah tugas sulit. Pada saat yang sama, pengguna lain juga dapat berinteraksi dengan data yang ditampilkan pada Anda (misalnya, seperti posting yang Anda lihat). Bagaimana kita menjaga data disinkronkan di berbagai bagian layar? Bagaimana dan kapan kita harus memeriksa data lokal dengan server dan menerima / mengirim perubahan?
Responsif
Orang memungkinkan kurangnya umpan balik visual untuk tindakan mereka hanya untuk waktu yang sangat terbatas. Untuk tindakan pengguna
terus -
menerus , seperti menggulir, kurangnya reaksi aplikasi hanya mungkin untuk periode yang terpendek. Bahkan melewatkan satu frame pada 16 milidetik sudah terlihat bermasalah dan belum selesai. Untuk tindakan
diskrit (satu kali), seperti klik, menurut beberapa penelitian, pengguna biasanya merasakan keterlambatan dalam respons kurang dari 100 milidetik. Jika tindakan membutuhkan waktu lebih lama, maka perlu untuk menunjukkan indikator visual. Namun, ada beberapa tugas yang berlawanan dengan intuisi. Indikator yang menyebabkan pergeseran pada templat halaman atau yang melewati beberapa tahap bergantian dapat membuat tindakan lebih lama “terasa” daripada yang sebenarnya. Demikian pula, respons aplikasi dalam 20 milidetik dengan melewatkan satu frame animasi mungkin "merasa" lebih lambat daripada animasi penuh dalam 30 milidetik. Kesadaran kita tidak bekerja seperti tolok ukur. Bagaimana kita membuat aplikasi responsif?
Waktu Respons (Latensi)
Komputer menghitung dan mentransmisikan data melalui jaringan membutuhkan waktu. Terkadang kami dapat mengabaikan waktu perhitungan jika tidak memengaruhi responsif pada perangkat pengguna (namun, pastikan Anda telah menguji kode Anda pada perangkat lama dan anggaran). Namun, memproses waktu pengiriman data melalui jaringan tidak dapat dihindari - ini dapat dihitung dalam hitungan detik! Sebuah aplikasi tidak bisa begitu saja "hang" sambil menunggu data atau kode dimuat. Ini berarti bahwa setiap tindakan yang memerlukan data, kode, atau aset baru berpotensi tidak sinkron dan harus menangani status muatannya. Ini berlaku untuk sebagian besar layar dan elemen. Bagaimana menangani penundaan pengiriman data dengan benar tanpa menampilkan kaskade pemintalan yang berputar atau "lubang" kosong di antarmuka? Bagaimana cara menghindari pergeseran tata letak halaman? Dan bagaimana cara mengubah dependensi asinkron tanpa perlu menulis ulang kode konstan?
Navigasi
Kami berharap antarmuka menjadi "stabil" saat berinteraksi dengannya. Elemen seharusnya tidak tiba-tiba menghilang. Navigasi, baik di dalam aplikasi (misalnya, tautan) dan eksternal (misalnya, tombol Kembali di browser) juga harus mematuhi prinsip ini. Misalnya, beralih antara tab
/profile/likes
dan
/profile/follows
berikut di bagian pengguna tidak boleh membatalkan konten bidang pencarian di luar bagian ini. Bahkan beralih ke layar lain harus terlihat seperti berjalan ke ruangan lain. Orang-orang berharap bahwa ketika mereka kembali, mereka akan menemukan semua hal di mana mereka meninggalkan mereka (dan, mungkin, akan senang dengan beberapa hal baru). Jika Anda berada di tengah-tengah rekaman Anda, klik pada tab profil, dan kemudian kembali ke kaset - maka Anda pasti tidak ingin menggulir ulang rekaman itu dari awal atau menunggu sampai keadaan masa lalu rekaman itu dimuat. Bagaimana cara merancang aplikasi untuk menangani navigasi pengguna sewenang-wenang tanpa kehilangan konteks penting?
Staleness
Kita dapat membuat implementasi tombol Kembali seketika dengan menambahkan cache lokal ke aplikasi. Untuk melakukan ini, kami akan menyimpan data yang diperlukan dalam cache (data dari kondisi sebelumnya - sekitar Penerjemah). Kami bahkan dapat memperbarui cache secara teoritis untuk menjaga agar data tetap terbaru. Namun, implementasi caching memerlukan tantangan baru. Tembolok mungkin kedaluwarsa. Jika saya mengubah avatar, maka itu harus diperbarui termasuk dalam cache. Jika saya menerbitkan posting baru, maka itu akan segera muncul di cache, jika tidak cache akan menjadi tidak valid. Kode semacam itu pada akhirnya menjadi terlalu rumit dan sulit dipertahankan. Bagaimana jika proses penerbitan gagal? Berapa lama cache dalam memori? Saat kami mendapatkan kembali kumpulan data, apakah kami menggabungkan data baru dengan data yang di-cache sebelumnya, atau apakah kami membuang cache lama dan meng-cache seluruh set lagi? Bagaimana seharusnya pagination dan sortasi disajikan dalam cache?
Entropi
Hukum kedua termodinamika berbunyi kira-kira sebagai berikut: "Seiring waktu, semuanya berubah menjadi berantakan total" (tentu saja tidak kata demi kata). Ini juga berlaku untuk antarmuka pengguna. Kami tidak dapat memprediksi tindakan pengguna tertentu dan urutannya. Pada waktu tertentu, aplikasi kita dapat menjadi salah satu dari sejumlah besar negara (besar!). Kami berusaha sebaik mungkin untuk membuat hasilnya dapat diprediksi dan terbatas sesuai dengan desain kami. Kami tidak ingin melihat tangkapan layar dengan bug dan berpikir untuk diri kita sendiri: "Bagaimana ini bisa terjadi?" Untuk
N kemungkinan keadaan, ada
N × (N - 1) transisi yang mungkin di antara mereka. Misalnya, jika lima keadaan berbeda dimungkinkan untuk sebuah tombol (normal, aktif, melayang, disorot, dan dinonaktifkan), maka kode yang bertanggung jawab untuk mengubah tombol harus benar untuk 5 × 4 = 20 kemungkinan transisi - atau secara eksplisit melarang beberapa di antaranya. Bagaimana kita berurusan dengan peningkatan kombinatorial dalam keadaan yang memungkinkan dan membuat keluaran visual yang dapat diprediksi?
Prioritas
Beberapa hal lebih penting daripada yang lain. Mungkin antarmuka dialog Anda akan muncul secara ketat "di atas" tombol yang dipanggil, dan melampaui wadah induk. Atau, tugas yang baru saja dijadwalkan (mis., Hasil klik) mungkin lebih penting daripada tugas jangka panjang yang telah dimulai. Ketika aplikasi memperbesar, bagian-bagiannya yang berbeda, yang ditulis oleh orang yang berbeda atau bahkan tim, mulai bersaing untuk sumber daya yang terbatas, seperti daya komputasi prosesor, lalu lintas jaringan, ruang layar, atau ukuran bundel. Kadang-kadang Anda dapat mendistribusikan item pada skala "kepentingan" tunggal, mirip dengan aturan CSS
z-index
.
Tetapi biasanya itu tidak berakhir dengan sesuatu yang baik . Setiap pengembang dengan tulus menganggap kode itu penting. Tetapi jika semuanya sama pentingnya, artinya - tidak ada yang penting. Bagaimana kita dapat membuat bagian independen dari aplikasi
berinteraksi daripada memperjuangkan sumber daya yang terbatas?
Aksesibilitas
Situs yang tidak disesuaikan untuk penyandang cacat bukan masalah yang sangat terspesialisasi. Misalnya, di Inggris setiap pengguna kelima menghadapi masalah ini (di
sini adalah infografis visual). Saya merasakannya sendiri. Terlepas dari kenyataan bahwa saya hanya berusia 26 tahun, saya jarang menggunakan situs dengan font tipis dan skema warna buram. Saya mencoba menggunakan trackpad lebih jarang, tetapi saya takut pada hari ketika saya harus menggunakan situs yang tidak cocok untuk keyboard. Kita tidak boleh mengubah aplikasi kita menjadi mimpi buruk bagi para penyandang cacat - dan kabar baiknya adalah itu tidak terlalu sulit. Anda harus mulai dengan mengeksplorasi solusi dan alat. Selain itu, kita harus membuatnya sederhana dan mudah dipahami bagi desainer dan pengembang untuk membuat keputusan yang tepat. Apa yang dapat kita lakukan untuk memastikan bahwa ketersediaan aplikasi kita diaktifkan secara default, dan bukan revisi yang terlambat?
Internasionalisasi
Aplikasi kita harus bekerja di seluruh dunia. Ya, orang berbicara bahasa yang berbeda, tetapi selain itu, dukungan untuk menulis diperlukan dari kanan ke kiri, dan dengan upaya minimal dari pengembang. Bagaimana kami dapat mendukung berbagai bahasa dan skrip tanpa kehilangan respons dan waktu respons aplikasi?
Pengiriman
Kita harus mengirimkan kode aplikasi ke komputer pengguna akhir. Metode dan format transmisi apa yang akan kita gunakan? Dalam pertanyaan ini, setiap jawaban akan berkompromi dengan kekuatan dan kelemahan masing-masing. Misalnya, aplikasi asli harus mengunduh semua kode mereka terlebih dahulu karena ukurannya yang besar. Meskipun aplikasi web biasanya memiliki waktu boot yang jauh lebih pendek, tetapi dipaksa untuk menangani banyak latensi dan unduhan saat digunakan. Bagaimana kita memutuskan jenis penundaan untuk memilih dari dua opsi ini? Bagaimana cara mengoptimalkan waktu respons berdasarkan statistik penggunaan pengguna? Data apa yang perlu kita miliki untuk membuat keputusan terbaik?
Fleksibilitas (Ketahanan)
Tidak ada yang suka bertemu bug di program mereka sendiri. Namun, beberapa bug pasti akan dapat diproduksi. Dan ini sangat penting - apa yang akan terjadi kemudian. Beberapa bug menyebabkan perilaku yang salah, tetapi secara ketat didefinisikan dan ditentukan sebelumnya. Misalnya, kode Anda menunjukkan kondisi yang tidak pantas untuk kondisi tertentu. Tetapi bagaimana jika, sebagai akibat dari bug, aplikasi sepenuhnya berhenti render? Dalam hal ini, kami tidak akan dapat melanjutkan eksekusi program yang berarti, karena output visual tidak akan ditentukan. Kesalahan saat merender satu pos dari umpan tidak boleh “mematahkan” rendering seluruh umpan atau menempatkan aplikasi dalam keadaan tidak stabil, yang akan menyebabkan kesalahan lebih lanjut. Bagaimana kita dapat menulis kode yang mengisolasi kesalahan ketika membuat atau menerima data di salah satu bagian dan melanjutkan operasi yang benar dari sisa aplikasi? Apa arti toleransi kesalahan saat membuat antarmuka pengguna?
Abstraksi
Dalam aplikasi kecil, kita dapat melakukan hardcode dan menyelesaikan semua masalah di dahi. Tetapi aplikasi cenderung tumbuh. Kami ingin dapat
menggunakan kembali, bercabang, dan menggabungkan berbagai bagian aplikasi dan melakukannya bersama-sama dengan orang lain. Kami ingin mendefinisikan batas-batas yang dapat dimengerti antara bagian-bagian dari keseluruhan yang akan diterima oleh orang yang berbeda dan pada saat yang sama menghindari logika yang terlalu kaku, karena sering berubah dan berkembang dalam proses kerja. Bagaimana kita membuat abstraksi yang menyembunyikan detail implementasi UI? Bagaimana kita bisa menghindari terulangnya masalah ini dengan pertumbuhan aplikasi?
Tentu saja, ada banyak lagi masalah yang belum saya sebutkan. Daftar ini sama sekali tidak lengkap atau lengkap. Misalnya, saya tidak menyentuh topik kolaborasi antara desain dan pengembangan, topik debugging atau pengujian. Mungkin kita akan kembali ke ini lain waktu.
Sangat menggoda untuk membaca tentang masalah-masalah ini, mengingat sebagai solusi kerangka kerja khusus untuk menampilkan data atau pustaka untuk menerima data. Tetapi saya sarankan Anda membayangkan bahwa solusi ini tidak ada dan coba baca lagi. Bagaimana Anda mencoba menyelesaikan masalah ini? Cobalah untuk mewujudkan ide-ide Anda pada aplikasi sederhana. Saya akan senang melihat hasil percobaan Anda di Github. (Cukup beri tag Dan Abramov di
Twitter dan lampirkan tautan ke repositori - kira-kira. Penerjemah).
Apa yang sangat menarik dalam masalah ini adalah bahwa kebanyakan dari mereka memanifestasikan diri pada skala apa pun. Anda dapat menjumpai mereka ketika bekerja pada widget kecil, seperti tooltip, dan dalam aplikasi besar seperti Twitter atau Facebook.
Pikirkan tentang elemen antarmuka pengguna non-sepele dari aplikasi yang ingin Anda gunakan, dan jalankan kembali daftar masalah di atas. Bisakah Anda menggambarkan trade-off yang dibuat pengembang? Cobalah untuk mereproduksi perilaku serupa dari awal!
Saya menyadari banyak tentang pengembangan antarmuka pengguna yang baik, bereksperimen dengan masalah ini dalam aplikasi kecil tanpa menggunakan perpustakaan dan kerangka kerja pihak ketiga. Saya merekomendasikan hal ini kepada siapa pun yang ingin mendapatkan pemahaman yang mendalam tentang solusi dan pertukaran ketika mengembangkan antarmuka yang kompleks.