這篇文章向大家分享了一個關於Fix一個隨機重現的鍵盤issue後的思考,很有意義,有興趣的朋友可以看一下
最近花了近一周fix了一個行動端的bug,是個很有趣的bug,大概是這樣的。這是一個比較長的故事,有興趣的可以一直看。
bug的表現是在一款tablet端應用使用很久之後,第一,在輸入框內輸入一些內容後,點擊done/search,第二,然後點擊頁面的一些空白區域,軟鍵盤彈出,並且遊標focus在最近輸入過的輸入框內。
此時應用程式對使用者行為的回應會讓使用者很疑惑與費解。
總結,它有以下幾個特點
應用程式最開始是正常的,不是每次都能重現
一旦出現這個bug,在每個存在輸入框的頁面都存在這個問題
重現的場景不明,目前已知是應用程式使用的越久越容易出現,應用一旦後台關閉病重新啟動,又會消失。
我們先是試著去找一個最小的用戶journey去復現這個bug ,當時運氣比較好,花了大概半天找到了一條最小的重現路徑。
不說業務背景,簡單介紹下應用的頁面邏輯。
我們的應用程式在登入之後有一個home頁面,home頁面有三個tab可以滑動或點擊切換,在tab頁面之上還存在一些功能選單,其中某個功能選單menuA可以點擊跳到另一個新的帶有一個輸入框的頁面。
頁面大概如下,不是專業ux很醜勿見怪。
我們發現的一條可以快速重現的路徑是
#登入home頁面後,重複切換三個tab多次(20次以上)
點擊menuA到達一個輸入框的頁面
在輸入框輸入數據,並點擊軟鍵盤的done
點擊頁面空白區域
然後軟鍵盤就出來了。
找到一個最小重現路徑之後,我們可以從程式碼裡面找出為什麼會出現這個問題。
因為這個bug在應用重啟後沒有,我們懷疑的方向就定位在render的問題,大機率是出在組件上。
我們中間有幾個猜測
自己封裝的input組件有問題
三個tabs的滑動組件有問題,滑動組件內的scroll view影響了RN的手勢響應系統
最後發現貌似都不是,這個時候和組內另外一個同事pair,她發現在請求比較多的時候容易有問題,中間還懷疑過網路請求處理導致的。這個懷疑其實不大對,但確實為我們找到了一條路。
我們最後發現我們所有的網路請求都在請求結果返回之前在頁面出現一層蒙版mask以及一個類似web裡面spinner(在RN裡面是ActivityIndicator)的loading提示符號,這個部分是會影響頁面render的。
而把這部分去掉(在請求到達之前不出現蒙層),這個bug就沒有了,這個發現當時還是讓人很震驚的以及疑惑的,因為似乎找到了一部分原因但我們還是沒搞清楚為什麼。
有了這個思路的提示,我們試著嘗試修復。依照業務需求,我們不能取消ActivityIndicator的使用,因為給使用者適當的提示這個確實很有必要。
我們試著去修改mask的實現,在老的里面我們使用了一個第三方的RN組件react-native-root-siblings來幫助我們在root同級插入一個兄弟元素顯示我們的loading提示符號。
一般在發完請求請求結果未到達之前,我們就插入一個新的同級兄弟元素,請求完成後就刪除掉它。當時懷疑因為這部分重複的修改頁面的元素結構,就把new-destory的邏輯換成了new-update的邏輯,減少了元素的修改。 update的時候只是去讓ActivityIndicator不出現似乎被hide了。
我們希望透過減少頁面元素反覆的刪除創建,來fix這個bug,結果怎麼樣呢?
居然神奇的很難復現了,我們很開心,雖然還是沒搞懂原因。
後面QA說在真機上還是遇到了幾次,讓我們更是費解,費解的是出現的機率確實變少了,但為啥還會出現?
這時候我們需要了解bug產生的真正原因了。
我們重新回到這個bug的表現,為什麼點擊空白區域會觸發TextInput的focus方法?我們嘗試做了這樣幾件事情。
找出在會觸發TextInput的focus的地方
#除了在程式碼邏輯裡面少量的透過綁定ref然後觸發.focus方法(因為是少量出現,不符合我們這個bug一出現所有input都受影響的情景,快速排除不是這部分原因),我們發現在RN提供的TextInput組件裡面也有很多地方會調用到focus方法。
以上是Fix一個隨機重現的鍵盤issue後的思考(ReactNative)的詳細內容。更多資訊請關注PHP中文網其他相關文章!