今天要說的 CSS 程式碼真的是讓 app 崩潰了,至於信不信,看圖片就知道咯。
突然收到一封郵件,大概內容是說因為 CSS 的問題讓 app 掛了。當時在想,怎麼樣的 CSS 如此屌,居然讓 app 掛了!於是掏出手機按照郵件中提示的 URL 打開看了一下,我只想說,這代碼,額,算了,還是不吐槽了,其實要是我寫的話,肯定會更爛。
雖然是來自其他部門的一個頁面,但作為公司的一員,怎麼能不為公司的產品考慮呢。聽起來感覺像是在拍馬屁,其實真的是,因為我最好奇的是出現 bug 的原因是什麼,當然,肯定也是關心產品的啦。
於是第二天一早就到公司開始排雷…
仔細看了一下程式碼,從最初懷疑是 animation 的性能影響低端設備運行開始排查。結果發現這個所謂的效能問題其實也沒那麼厲害,一時也找不到頭緒,然後源文件又不是在我們自己這邊,只好打開花瓶抓 CSS 文件,然後替換後,用刪除法一點點查。
最後在儲大師的提點以及提供的一個 URL 來看,居然是 rem 導致的。
這個網址大家應該都知道,是專門看 bug 的,當然,也可以提 bug 啦。
@-webkit-keyframes crashChrome { 0%{ -webkit-transform: translateX(0rem);} } .anim:before{ content: ""; width: 3rem; height: 3rem; border-radius: 3rem; position: absolute; left:5rem; top: 5rem; background-color: #06839f; -webkit-animation: crashChrome; }
<div class="anim"></div>
剛開始看到這段 CSS 程式碼的時候,感覺這個好像也沒什麼問題啊,不就是透過 :before 這個偽元素來做一個 animation 動畫效果麼,然後使用了 rem 這個單位量。
反正是百思不得其解。
還是找測試機,繼續刪除那個有問題的頁面程式碼吧。先是用了三星的,發現沒問題,接著用了小米的,果然奔潰了。看了一下版本,三星的是 Android 4.4.2,小米的是 Android 4.4.4,難道是版本的關係?
總之,在最開始那塊有動畫效果的部分排查了很久都沒找到問題。最後還是回到那個已經報了 bug 的頁面上看具體說明。
突然想到,這個頁面中用了 :before 來做動畫,莫非我們的這個頁面中也有,於是一搜,結果, 真的有 !
趕緊我們自己頁面上的這段程式碼拿過來做嘗試,終於找到你了。趕緊回郵件告訴對方…
再次感謝儲大師的提點,有機會了解未曾了解到的一個問題。
這個bug 在目前桌面端的設備中已經被處理掉了,按照bug list 頁面上說的,當時發現這個bug 是在
Chrome Version: 34.0.1847.116 (Official Build 260972) m上的這個版本
,並且各系統都有。然而,現在的 Chrome 都已經是 50 以上的版本了,所以桌面端完全不需要擔心了。 但這次既然是在行動端上遇見了,而且是Android 4.4.4 這個版本,雖然是在小米3 中發現,但Android 4.4.4 這個版本應該還算是比較普遍的,難道真的會是這個問題。 獲取一下這個webview 的UA 信息,看到其中有一個是 Chrome/33.0.0.0 Mobile Safari ,於是我想啊,可能應該就是這個webview 的關係了,畢竟我在小米3 這台測試機上的各個瀏覽器都看了一遍,沒發現問題。 現在是知道 rem 和 animation 一起的時候回出現這個 bug,但是在其他元素中並沒有問題。 然後開始做各種實驗:把 animation 換成 transition ,並且也是透過改變有 rem 的屬性,結果發現這個想法的結果是,沒有任何問題。 想到 :before 是偽元素,那麼對於偽元素的選擇符還有幾個,都試試看。 結果發現這四個偽元素選擇符全部都會讓頁面崩潰…瀏覽器(webview)的底層渲染機制我不懂,但就目前來看,可能應該就是因為 Chrome/33.0. 0.0 Mobile Safari 這個版本的問題,如果在偽元素中使用animation ,並且改變了其中的rem 的值就會出現頁面崩潰的問題。 所以,可能應該就是這樣:使用了:before 等偽元素中的其中一個來做animation 動畫;在animation 動畫改變了其中的某個rem 的值;在這樣的前提下,又是使用有這個bug 的版本瀏覽器,那就會讓頁面崩潰。 如果要避免這個 bug 的出現,那麼應該是:換一個 webview,高版本的應該會好一些;在偽元素中使用 animation 動畫時,不用 rem 單位;在偽元素中使用 animation 動畫時,不用 rem 單位;🎜不過好像現在大家都會去用 rem 單位,然後也會去用 animation 做動畫,那這樣好了,不在偽元素上使用者兩樣東西咯。