一文完全解決iOS中鍵盤迴落後留白問題

最近作的一個H5剛開開心心提測就被QA一頓懟😭,當input輸入完成後頁面簡直卡成翔💩,當我接過手機親自測試時慌的一批😢,頓時開始懷疑人生😏,立刻開始進入緊張的排查中😊,通過兩天不斷的調試優化😂,最終完美解決全部問題❤️,此文能夠完全解決iOS的H5頁面卡頓以及鍵盤迴落後留白問題😄。css

1.定位問題

當QA和我反映頁面卡頓只在iOS上出現時,第一反應確定不是代碼的問題,我也很納悶iOS性能廣泛要比android高啊,爲啥會出現這麼嚴重的卡頓,有點慌啊。因而開始了一次驚心動魄的前端性能優化之旅,在Google大概的看了幾篇文章,感受到應該是我在頁面加了大量的動畫形成了頁面重排(reflow)致使的,初步定位問題是重排形成的😄html

2.解決卡頓

把問題定位爲重排形成的,因而就開始針對性的排查容易形成重排的隱患,發現有動畫的元素都是absolute的,應該問題不大。最後給最外層的元素前後增長了如下屬性:前端

.wrap {
    -webkit-transform: translateZ(0);
    -moz-transform: translateZ(0);
    -ms-transform: translateZ(0);
    -o-transform: translateZ(0);
    transform: translateZ(0);
}
複製代碼

在瀏覽器中用css開啓硬件加速,使GPU (Graphics Processing Unit)發揮功能,從而提高性能,若是要充分發揮瀏覽器的性能時,慎用will-change: transform;至於爲何請看CSS will-change 屬性;排查了一番該定位的定位,反正要避免掉重排的坑,再加上開啓了硬件加速因而就快速驗證了一下,發現頁面開始順暢了起來,可是依舊有空白,經驗證是input鍵盤收起後頁面不進行繪製出現的空白,因而換了思路從新開始Google關於iOS頁面input空白的問題,果真發現了新大陸,這是iOS12的大坑,在網上看了不少文章不斷的試錯,最終找到了一個比較穩妥的方法。android

3.解決空白

input上分別增長focusblur的方法,基本能夠解決鍵盤迴落後留白問題web

handleFocus(event) {
    let e = event.currentTarget;
    setTimeout(() => {
        e.scrollIntoView({
            block: 'start',
            behavior: 'smooth'
        });
    }, 300);
}
handleblur() {
    let e = event.currentTarget;
    setTimeout(() => {
        e.scrollIntoView({
            block: 'end',
            behavior: 'smooth'
        });
    }, 300);
}
複製代碼

至此覺得萬事大吉了,沒想到QA說iOS還會偶爾性的出現留白問題,我也是沒脾氣了,也許沒有解決掉根源問題,只是暫時提升了頁面的性能而已,再次開始了探索之旅,發現須要在input失去焦點時讓頁面的scrollTop爲0便可正常回落,因而增長了如下代碼:segmentfault

handleblur() {
    let e = event.currentTarget;
    setTimeout(() => {
        e.scrollIntoView({
            block: 'start',
            behavior: 'smooth'
        });
    }, 300);
    window.scrollTo(0, 0);
}
複製代碼

就這樣過了一天QA再也沒有反饋過,感受一會兒輕鬆了許多,尚未輕鬆多久,QA又報了有個頁面中有兩個input進行填寫時會彈跳形成的體驗很是很差,我一看體驗太差了,因而又開始了優化彈跳之旅。。。瀏覽器

4.優化彈跳

此次的定位很明確,就是失焦時的scrollTop=0形成的頁面彈跳。原本iOS是作了這方面的優化,在軟鍵盤彈出和收起時頁面會smooth的平滑,因爲我加了scrollIntoView破壞了原生的優化致使彈跳了。不斷的google,嘗試了不少種方法都無果,最後無奈之下只好向技術羣的小夥伴求助,果真有高手,提供了下他以前作的思路,我一試果真了得,定時器大法終於派上用場了,如下是最終代碼:性能優化

handleFocus(event) {
    clearTimeout(this.timer);
}
handleblur() {
    this.timer = setTimeout(() => {
        window.scrollTo(0, 0);
    }, 100);
}
複製代碼

至此終於完美解決了遇到的全部問題,QA也漏出了會心的微信😊兩天下來腦細胞死了很多,今天分享出來,以後的同行能夠一步到位,少走彎路了😄bash

總結

  1. 寫頁面時避免掉形成重排的隱患;
  2. 必要時謹慎開啓硬件加速;
  3. 精準定位問題,分析問題,收集問題;
  4. 善於提問能夠少走不少彎路;

精彩預告:最近歷時兩個月的大需求遇到不少深坑,接下來會相繼分享出來,以此共勉😂微信

更多精彩內容歡迎關注個人公衆號【天道酬勤Lewis】

相關文章
相關標籤/搜索