天天看點

【H5疑難雜症】脫離文檔流時的渲染BUG

BUG重制

最近機票團隊在一個頁面布局複雜的地方發現一個BUG,非常奇怪并且不好定位,這類問題一般最後都會到我這裡,這個問題是,改變dom結構,頁面卻不渲染!!!

如圖所示,我動态的改變了dom結構,結果頁面那一坨變得什麼都沒有,相當奇怪!!!在PC模拟iPhone就可以重制,iPhone、note4等手機上也可重制,由于這種BUG我不是第一次碰到,很快便引起了注意,總結起來可以歸結于:

js代碼改變fixed元素的html結構(一般是動畫後并且布局相對複雜),頁面不會渲染

問題定位-分離法

本着發現問題,定位問題,解決問題的步驟,我開始了定位,這裡的難點是,這類問題往往非常難以定位,因為他的dom tree相當複雜,首先我做了一個事情,直接将其htmlcss分離出來,擺脫js的原因,直接顯示該dom。

于是問題不在了,這個很令人費解,難道是js對其造成了影響?經過一輪糾纏,定位失敗開始二輪定位。

問題定位-最小化問題

這種問題确實不好處理的時候,光靠看頁面可能不能處理了,這個時候便把機票的代碼拿到本地,部署起來,做了幾件事情:

① 去掉該頁多餘的業務代碼,基本上不完成任何功能

② 去掉多餘的dom結構(由于我們是單頁應用,dom可能相對比較複雜)

打開對應業務代碼一看,洋洋灑灑3000行,立馬想吐:

這個時候一行行去讀代碼就是2B的行為了,直接找到那個顯示月曆的代碼:

然後稍作改動,把其它業務邏輯全部搞掉,事件綁定也搞掉,隻留下顯示月曆的事件,直接一來點選顯示月曆,這個時候形成的dom結構由4000多行變成了1000多行,但是依舊有BUG

問題定位-CSS重置

由于機票對月曆的樣式,做了重置,是以有理由懷疑是他們自己的css導緻的問題,于是想去掉他們的css引用試了試,雖然樣式難看了點,但是問題依舊存在......

問題定位-js邏輯

這個時候便有理由懷疑其月曆顯示後,本身有一定邏輯功能導緻出錯,于是看到了月曆show後面幹的事情,并且為了防止dom結構過大,将月份顯示設定為1月。

都這個樣子了,他居然還是渲染不處理,有點傷害自尊!!!

因為這個月曆顯示時候有一個從右到左的動畫,這個時候将其動畫關掉,卻發現問題解決了!!!其中的代碼為zepto的實作,不是關鍵

複制代碼

$el.css({

      '-webkit-transform': prepareCss,

      transform: prepareCss

})

  .show()

  .animate({

    '-webkit-transform': 'translate(0, 0)',

    transform: 'translate(0, 0)'

  }, 500, 'ease-in-out', function() {

    $el.css({

      '-webkit-transform': '',

      transform: ''

    });

  });

問題定位成功-脫離文檔流的渲染

最後問題定位成功,至少從表現和處理來說是定位成功的,簡單來說:

動畫執行結束後,如果我改變的是fixed元素中的一個子單元的html,不會有反應,但是我們同時改變static元素便會引起一次渲染,尼瑪這是神馬鬼!!!

問題探索-渲染的差異

為了弄懂這個原因,我們得看到渲染的細節,這裡做了一個對比:

不引起static dom變化

引起static dom變化

這裡注意觀察最後一次paint便可以看見渲染出來的東西不一樣,導緻這種的差異是什麼呢,我們一次次的對比幾次不同

這裡做一個差異對比,因為這裡的static元素與fixed元素還有一些管理,我們這裡操作與之完全無關的元素試試。事實證明沒有什麼影響,是以這類問題的解決方案是:

移動端過多定位元素布局時,偶爾操作fixed元素html不會渲染,解決方案是同步改變與之相關的static元素,便會引導渲染

剛剛使用的是設定html,這裡完全可以使用這種做法:

el.html(el.html())

可以達到相同的功能,但是問題導緻原因依舊不可知......不可說不是一種遺憾!!!如果您知道這個問題的答案,請您留言。

本文轉自葉小钗部落格園部落格,原文連結:http://www.cnblogs.com/yexiaochai/p/4359983.html,如需轉載請自行聯系原作者

繼續閱讀