
Ingat kapan terakhir kali Anda mengalami kesalahan UI yang membutuhkan waktu berjam-jam untuk memperbaikinya? Mungkin kesalahan ini terjadi secara berkala, tanpa alasan yang jelas. Mungkin itu muncul dalam kondisi tertentu (dapat bergantung pada perangkat, sistem operasi, browser atau tindakan pengguna) atau apakah itu tersembunyi di suatu tempat di kedalaman salah satu dari banyak teknologi front-end yang merupakan bagian dari sisi klien dari proyek web?
Baru-baru ini saya harus mengingat betapa membingungkan penyebab kesalahan UI. Yakni, kita berbicara tentang memperbaiki bug menarik yang memengaruhi keluaran gambar SVG di browser Safari. Kesalahan ini terjadi tanpa sistem khusus dan tanpa alasan yang jelas. Ketika dihadapkan pada suatu masalah, saya mencoba menemukan kasus serupa, berharap penjelasan dari kasus-kasus tersebut dapat memberi petunjuk kepada saya tentang apa yang terjadi. Tetapi saya belum dapat menemukan sesuatu yang berguna. Benar, terlepas dari semua rintangan di depan saya, saya bisa mengatasi kesalahan ini.
Saya telah menganalisis masalah menggunakan beberapa strategi debugging yang akan saya bahas di artikel ini. Setelah saya menyingkirkan kesalahan itu, saya teringat nasihat ituyang diberikan Chris Coyer kepada pembaca Twitternya beberapa tahun yang lalu. Nasihatnya seperti ini: "Tulis artikel yang ingin Anda temukan ketika Anda mengunjungi mesin pencari." Faktanya, itulah yang saya lakukan.
Ringkasan masalah
Dalam sebuah proyek yang saya kerjakan, di situs langsung, saya menemukan kesalahan, manifestasinya saya rekam di video ini . Seperti inilah tampilan tombol dalam keadaan normal.

Tombol dalam keadaan normal
Dan berikut adalah tombol yang sama setelah terjadi masalah.

Sebagian tombol terpotong.
Saya telah mereproduksi kesalahan ini dalam berbagai situasi yang menyebabkan halaman digambar ulang. Misalnya, ini terjadi saat jendela browser diubah ukurannya.
Untuk mendemonstrasikan masalahnya, saya membuat contoh di CodePen . Kami akan membahasnya lebih detail di bawah ini. Tetapi Anda dapat bereksperimen dengan contoh ini sendiri. Yaitu, kita berbicara tentang fakta bahwa jika Anda membuka contoh ini di browser Safari, maka, saat halaman dimuat, tombol akan terlihat seperti yang diharapkan. Tetapi jika Anda mengklik salah satu dari dua tombol yang lebih besar, bug tersebut menjulurkan kepalanya yang jelek.

Mengapa gambar SVG di-crop?
Setiap kali peristiwa tersebut terjadi
paint, gambar SVG yang digunakan di tombol yang lebih besar tidak ditampilkan dengan benar. Gambar-gambar ini hanya dipotong. Hal ini dapat terjadi, tanpa alasan yang jelas, saat halaman dimuat. Ini dapat terjadi bahkan ketika jendela diubah ukurannya. Secara umum, kesalahan muncul dalam berbagai situasi.
Gambaran umum proyek tempat kesalahan terjadi
Saya pikir ketika berbicara tentang kesalahan, akan lebih baik untuk mengungkapkan detail tentang proyek dan kondisi di mana kesalahan itu terjadi.
- Proyek ini menggunakan React (tetapi pembaca artikel ini tidak perlu mengetahui React untuk memahaminya).
- Gambar SVG diimpor ke proyek sebagai komponen React dan disematkan dalam HTML menggunakan webpack.
- . .
- CSS.
- , , HTML-
<button>. - Safari ( 13 ).
Mari kita lihat kesalahannya dan pertimbangkan apakah kita dapat membuat asumsi tentang apa yang sedang terjadi. Alasan kesalahan seperti itu biasanya tidak terletak di suatu tempat di permukaan, oleh karena itu, menghadapi kesalahan seperti itu, seseorang tidak dapat segera mengatakan dengan yakin apa yang terjadi. Dalam upaya pertama kami untuk memahami masalah, kami tidak harus berusaha mengidentifikasi penyebabnya dengan akurasi 100%. Kami akan menyelidiki kesalahan langkah demi langkah, merumuskan dan menguji hipotesis yang akan membantu kami mempersempit daftar kemungkinan penyebab dari apa yang terjadi.
Merumuskan hipotesis
Sekilas, yang terjadi terlihat seperti kesalahan CSS. Mungkin, saat Anda mengarahkan mouse ke atas tombol, beberapa gaya diterapkan padanya, yang merusak tata letak. Mungkin atribut
overflowgambar SVG yang harus disalahkan . Selain itu, ada perasaan bahwa kesalahan terjadi tanpa sistem khusus saat halaman digambar ulang karena berbagai alasan (peristiwa paintsaat jendela browser diubah ukurannya, saat penunjuk mouse berada di atas tombol, saat diklik, dan sebagainya).
Mari kita mulai dengan asumsi yang paling sederhana dan paling jelas. Katakanlah kesalahannya ada di CSS. Kita dapat berasumsi bahwa ada bug di browser Safari yang menghasilkan keluaran SVG yang salah saat gaya tertentu diterapkan ke elemen SVG. Misalnya, seperti gaya yang digunakan untuk membuat tata letak fleksibel.
Kami baru saja merumuskan hipotesis. Langkah kita selanjutnya adalah melakukan pengujian yang akan mengkonfirmasi atau menyangkal hipotesis ini. Hasil dari setiap pengujian akan memberikan informasi baru tentang kesalahan tersebut dan membantu dalam merumuskan hipotesis berikut.
Menyederhanakan masalah
Kami akan menggunakan strategi debugging yang disebut "menyederhanakan masalah". Ini akan memungkinkan kami untuk menunjukkan dengan tepat lokasi kesalahan. Dalam salah satu kuliah ilmu komputer di Cornell University, strategi ini digambarkan sebagai "pendekatan untuk secara bertahap menghilangkan kode yang tidak terkait dengan kesalahan."
Dengan asumsi bahwa kesalahan terletak pada CSS, pada akhirnya kita dapat menemukan penyebab kesalahan atau mengecualikan CSS dari persamaan, yang akan mengurangi jumlah kemungkinan penyebab kesalahan dan mengurangi kompleksitas masalah.
Mari kita uji hipotesis kita. Mari coba konfirmasi. Dalam kasus ini, jika Anda menonaktifkan sementara semua gaya non-standar dari halaman, ini akan mengakibatkan kesalahan tidak lagi muncul.
Berikut adalah kode untuk memasukkan lembar gaya yang sesuai:
import 'css/app.css';
Saya membuat ini proyek CodePen untuk menunjukkan output dari elemen tanpa CSS . Di React, grafik SVG diimpor ke proyek sebagai komponen , kemudian kode yang sesuai disematkan dalam HTML menggunakan webpack.

Tampilan Tombol Normal
Jika Anda membuka proyek tersebut di Safari dan mengklik salah satu tombol besar, ternyata kesalahan masih ada. Itu juga terjadi ketika halaman dimuat, tetapi ketika menggunakan CodePen, Anda perlu mengklik tombol untuk memicu kesalahan.

Kesalahan tidak hilang bahkan ketika CSS dinonaktifkan (Safari 13)
Sebagai hasilnya, kita dapat menyimpulkan bahwa CSS tidak ada hubungannya dengan itu. Namun, kami dapat memperhatikan fakta bahwa dalam kondisi seperti itu hanya dua dari lima tombol yang ditampilkan secara tidak benar. Mari kita ingat ini dan lanjutkan ke hipotesis berikutnya.
Isolasi kesalahan
Hipotesis kami berikutnya adalah Safari memiliki bug saat merender gambar SVG di dalam elemen HTML
<button>. Karena masalah muncul ketika dua tombol pertama ditampilkan, kami mengisolasi yang pertama dan melihat apa yang terjadi.
Sarah Drazner dalam hal iniMateri tersebut menjelaskan pentingnya isolasi. Saya sangat merekomendasikan membaca materi ini untuk siapa pun yang tertarik dengan detail lebih lanjut tentang alat debugging dan pendekatan berbeda untuk menemukan bug. Berikut adalah kutipan dari materi itu: “Isolasi mungkin adalah prinsip dasar yang paling penting dari debugging. Kode yang berfungsi dalam proyek kami dapat tersebar di berbagai perpustakaan dan kerangka kerja. Banyak orang mungkin terlibat dalam pengerjaan proyek, dan beberapa dari mereka yang berkontribusi pada pengembangan proyek tidak lagi mengerjakannya. Mengisolasi masalah membantu kami untuk secara perlahan memotong apa yang tidak menyebabkan munculnya kesalahan. Hal ini memungkinkan, pada akhirnya, untuk menemukan sumber masalah dan fokus padanya. "
Isolasi kesalahan sering disebut sebagai " kasus uji singkat ".
Saya memindahkan tombol ke halaman kosong terpisah (membuat tes terpisah untuk itu). Yakni, ini proyek CodePen diciptakan untuk menyelidiki tombol dalam isolasi. Meskipun kami telah menyimpulkan bahwa CSS bukanlah penyebab masalah, kami perlu membiarkan gaya dinonaktifkan sampai kami menemukan penyebab sebenarnya dari masalah tersebut. Ini akan memungkinkan kami untuk menyederhanakan masalah sebanyak mungkin.

Halaman dengan hanya tombol
Jika Anda membuka proyek ini di Safari, ternyata kami tidak dapat lagi menyebabkan kesalahan. Bahkan setelah mengklik tombol tersebut, gambar tidak berubah. Tetapi ini tidak dapat dianggap sebagai solusi yang dapat diterima untuk masalah tersebut. Namun, kode untuk proyek CodePen ini memberi kami dasar yang sangat baik untuk membuat contoh minimal yang dapat direproduksi.
Contoh minimal yang dapat direproduksi
Perbedaan utama antara dua proyek CodePen sebelumnya adalah kombinasi tombol. Memeriksa semua kemungkinan kombinasi tombol memungkinkan kami untuk menyimpulkan bahwa masalah hanya terjadi ketika suatu peristiwa
paintterjadi untuk gambar SVG yang lebih besar, di samping gambar SVG yang lebih kecil terletak di halaman.
Mengetahui hal ini memungkinkan kami untuk membuat contoh minimal yang dapat direproduksi yang memungkinkan kami mereproduksi kesalahan dan tetap menyingkirkan elemen yang tidak perlu. Berkat contoh minimal yang dapat direproduksi, kami dapat mempelajari masalah lebih dalam dan menyorot dengan tepat bagian kode yang menyebabkannya.
Berikut adalah proyek CodePen yang dimaksud.

Contoh minimal yang dapat direproduksi
Jika Anda membuka proyek ini di Safari dan mengklik tombolnya, kami kembali mengalami masalah. Ini akan memungkinkan kita untuk merumuskan hipotesis bahwa kedua elemen SVG saling bertentangan. Jika Anda menghamparkan gambar SVG kedua di atas gambar pertama, ternyata ukuran gambar yang tersisa dari gambar pertama sama persis dengan ukuran gambar yang lebih kecil.

Gambar di mana gambar kedua ditempatkan di atas gambar pertama, terdistorsi sebagai akibat dari kesalahan
Bagilah dan kuasai
Kami dapat mereproduksi bug menggunakan jumlah minimum elemen yang diwakili oleh sepasang gambar SVG. Sekarang kita akan lebih mempersempit ruang lingkup masalah, mempersempitnya ke bagian tertentu dari kode SVG yang merupakan sumber masalah. Jika kita hanya memiliki pemahaman umum tentang cara kerja SVG dan masih ingin mencari sumber masalahnya, maka kita dapat menggunakan strategi pencarian pohon biner dengan menggunakan pendekatan divide and conquer. Berikut adalah kutipan lain dari kuliah tersebutdari Cornell University Computer Science: “Misalnya, Anda dapat memulai dengan memeriksa sebagian besar kode dan menempatkan kode validasi di tengah bagian yang Anda periksa. Jika kesalahan tidak terjadi di sini, itu berarti sumbernya ada di paruh kedua kode. Jika tidak, sumbernya ada di paruh pertama kode. "
Saat memeriksa kode SVG, Anda dapat mencoba menghapus elemen
<filter>dari deskripsi gambar pertama (dan juga <defs>, karena tidak ada apa pun di blok ini). Mari kita perhatikan jenis tugas apa yang diselesaikan elemen tersebut <filter>. Penjelasan yang bagus untuk ini dapat ditemukan di sini . Yakni, kita berbicara tentang hal berikut: “Untuk menerapkan filter ke gambar SVG, ada elemen khusus yang disebut<filter>... Ini pada dasarnya menyerupai elemen yang dirancang untuk bekerja dengan gradien linier, topeng, templat, dan efek grafis lainnya. Elemen <filter>tidak pernah ditampilkan sendiri. Ini hanya digunakan sebagai sesuatu yang dapat dirujuk menggunakan atribut filterdi kode SVG atau fungsi url()di CSS. "
Di gambar SVG kami, filter digunakan untuk menambahkan bayangan bagian dalam kecil di bagian bawah gambar. Setelah menghapus filter dari kode gambar pertama, kami menunggu bayangan ini menghilang. Jika setelah itu masalah tetap ada, maka kita dapat menyimpulkan bahwa ada yang salah dengan kode lain untuk mendeskripsikan elemen SVG.
Saya membuat proyek CodePen lain untuk menunjukkan hasil tes ini.

Konsekuensi menghapus elemen <filter>
Masalahnya, seperti yang Anda lihat dengan mudah, belum ke mana-mana. Dan bayangan bagian dalam terus ditampilkan bahkan setelah menghapus kode filter. Tapi sekarang, antara lain, masalah muncul di semua browser. Ini memungkinkan kita untuk menyimpulkan bahwa kesalahan ada di suatu tempat di kode deskripsi tombol lainnya. Jika Anda menghapus sisanya
iddari<g filter="url(#filter0_ii)">, maka bayangan menghilang. Apa yang terjadi di sini?
Mari kita lihat lagi definisi elemen di atas
<filter>dan perhatikan kata-kata berikut: “Sebuah elemen<filter>tidak pernah ditampilkan dengan sendirinya. Ini hanya digunakan sebagai sesuatu yang dapat direferensikan menggunakan atributfilterdi SVG. " (Saya menyorot satu bagian teks.)
Jadi, dengan mengetahui hal ini, kita dapat menyimpulkan bahwa deklarasi filter dari gambar SVG kedua diterapkan ke gambar SVG pertama, yang menyebabkan error.
Perbaikan bug
Kami sekarang tahu bahwa masalah kami terkait dengan elemen
<filter>. Kita juga tahu bahwa kedua gambar SVG memiliki elemen ini, karena filter digunakan untuk membuat bayangan dalam melingkar. Mari bandingkan kode dari dua gambar SVG dan pikirkan apakah kita dapat menjelaskan kesalahan dan memperbaikinya.
Saya telah menyederhanakan kode dari kedua gambar tersebut sehingga Anda dapat melihat dengan jelas apa yang terjadi di dalamnya.
Berikut kode untuk gambar SVG pertama:
<svg width="46" height="46" viewBox="0 0 46 46">
<g filter="url(#filter0_ii)">
<!-- ... -->
</g>
<!-- ... -->
<defs>
<filter id="filter0_ii" x="0" y="0" width="46" height="46">
<!-- ... -->
</filter>
</defs>
</svg>
Berikut kode untuk gambar kedua:
<svg width="28" height="28" viewBox="0 0 28 28">
<g filter="url(#filter0_ii)">
<!-- ... -->
</g>
<!-- ... -->
<defs>
<filter id="filter0_ii" x="0" y="0" width="28" height="28">
<!-- ... -->
</filter>
</defs>
</svg>
Menganalisis kedua fragmen ini, Anda dapat melihat bahwa
id=filter0_iipengenal yang sama digunakan dalam konstruksi . Safari menerapkan definisi filter parsing browser terakhir ke elemen (dalam hal ini, filter gambar kedua). Ini mengarah pada fakta bahwa gambar pertama di-crop. Ukuran aslinya adalah 48px, dan setelah menerapkan filter, sebagian akan dipotong 26px. Properti idDOM harus memiliki nilai unik. Jika ada beberapa yang sama di halaman id, browser tidak dapat mengetahui mana yang perlu digunakan. Dan karena properti filterdiganti saat setiap peristiwa terjadipaint, kemudian, bergantung pada definisi mana yang akan siap terlebih dahulu (sesuatu seperti kondisi balapan terjadi di sini), kesalahan muncul atau tidak.
Mari kita coba menetapkan nilai unik
iddalam kode masing-masing gambar dan lihat hasilnya. Berikut adalah proyek CodePen yang sesuai.

Menetapkan id unik menyelesaikan masalah
Jika Anda sekarang membuka proyek di Safari dan mengklik tombol, Anda dapat yakin bahwa kami memecahkan masalah dengan menetapkan
idfilterunik yangdigunakan dalam gambar SVG. Jika Anda memikirkan fakta bahwa proyek memiliki nilai non-unik untuk atribut sepertiiditu, ini akan mengarah pada kesimpulan bahwa masalahnya seharusnya muncul di semua browser, tidak hanya di Safari. Tetapi untuk beberapa alasan, browser lain (termasuk Chrome dan Firefox) tampaknya telah menangani situasi yang tidak biasa ini tanpa kesalahan. Ini bisa jadi kebetulan.
Hasil
Itu adalah petualangan lain! Kami mulai mengetahui hanya bahwa ada beberapa jenis kesalahan dalam proyek, yang terkadang muncul dan kemudian tidak, tetapi pada akhirnya kami sepenuhnya memahami alasan apa yang terjadi dan mengatasi masalah tersebut. Men-debug kode antarmuka pengguna dan mencari tahu mengapa grafik terdistorsi bisa jadi rumit jika Anda tidak memahami apa yang terjadi. Beruntung bagi kami, ada strategi debugging yang dapat membantu kami menemukan akar penyebab dari kesalahan yang paling membingungkan.
Pertama, kami menyederhanakan masalah dengan merumuskan hipotesis yang memungkinkan kami untuk menghapus dari komponen proyek yang tidak terkait dengan kesalahan (gaya, markup, peristiwa dinamis, dll.). Setelah itu kami mengisolasi markup dan menemukan contoh minimal yang dapat direproduksi. Ini memungkinkan kami untuk fokus pada sepotong kecil kode. Dan kami akhirnya mengidentifikasi masalah menggunakan strategi divide and conquer untuk menghilangkan kesalahan.
Terima kasih kepada semua orang yang telah meluangkan waktu untuk membaca artikel ini. Tapi, sebelum kita mengakhiri percakapan, izinkan saya memberi tahu Anda tentang strategi debugging lain yang disebutkan dalam kuliah.Universitas Cornell. Intinya adalah bahwa dalam proses kerja Anda perlu istirahat, istirahat dan membebaskan pikiran Anda dari semua pikiran: “Jika terlalu banyak waktu untuk men-debug, programmer menjadi lelah. Mungkin ternyata dia, dalam keadaan seperti itu, bekerja dengan sia-sia. Dalam situasi seperti ini, ada baiknya istirahat dan membuang semuanya dari kepala Anda. Dan setelah beberapa saat Anda harus mencoba untuk melihat masalah dari sudut pandang yang berbeda. "
Bagaimana Anda memperbaiki kesalahan yang tidak bisa dipahami?
