原來 CSS 這樣寫是會讓 app 崩潰的
先廢話一下
之前在自己的個人公眾號中提到了一篇利用 CSS 的方式進行 XSS 攻擊,當時有朋友跟我說,讓我去獲取那個網站的 cookie,再然後進入那個網站的後臺去玩。然而,技術能力實在有限,搞不了這些東西,只是覺得那個網站沒有適當過濾 HTML 標籤是一件很危險的事情。
不過今天要說的 CSS 程式碼真的是讓 app 崩潰了,至於信不信,看圖就知道咯。
故事背景
昨晚在被窩中的我突然收到一封郵件,大概內容是說因為 CSS 的問題讓 app 掛了。當時在想,怎麼樣的 CSS 如此牛逼,居然讓 app 掛了!於是掏出手機按照郵件中提示的 URL 開啟看了一下,我只想說,這程式碼,額,算了,還是不吐槽了,其實要是我寫的話,肯定會更爛。
雖然是來自其他部門的一個頁面,但作為公司的一員,怎麼能不為公司的產品考慮呢。聽起來感覺像是在拍馬屁,其實真的是,因為我最好奇的是出現 bug 的原因是什麼,當然,肯定也是關心產品的啦。
於是第二天一早就到公司開始排雷……
大概的過程
首先我仔細看了一下程式碼,從最初懷疑是 animation
的效能影響低端裝置執行開始排查。結果發現這個所謂的效能問題其實也並沒那麼厲害,一時也找不到頭緒,然後原始檔又不是在我們自己這邊,只好開啟花瓶抓 CSS 檔案,然後替換後,用刪除法一點點查。
最後在儲大師的提點以及提供的一個 URL 來看,居然是 rem
導致的。
https://bugs.chromium.org/p/chromium/issues/detail?id=364222
這個網址大家應該都知道,是專門看 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
把 animation
換成 transition
,並且也是通過改變有 rem
的屬性,結果發現這個想法的結果是,沒有任何問題。
放棄這個想法……
:before
是偽元素
想到 :before
是偽元素,那麼對於偽元素的選擇符還有幾個,都嘗試一下看看。
注:這個截圖是曾經個人整理的有關 CSS 選擇符的一張圖
結果發現這四個偽元素選擇符全部都會讓頁面崩潰……
小結一下
瀏覽器(webview)的底層渲染機制我不懂,但就目前來看,可能應該就是因為 Chrome/33.0.0.0 Mobile Safari 這個版本的問題,如果在偽元素中使用 animation
,並且改變了其中的 rem
的值就會出現頁面崩潰的問題。
所以,可能應該就是這樣:
- 使用了
:before
等偽元素中的其中一個來做animation
動畫; - 在
animation
動畫改變了其中的某個rem
的值;
在這樣的前提下,又是使用有這個 bug 的版本瀏覽器,那麼就會讓頁面崩潰。
如果要避免這個 bug 的出現,那麼應該是:
- 換一個 webview,高版本的應該會好一些;
- 在偽元素中使用
animation
動畫時,不用rem
單位;
不過好像現在大家都會去用 rem
單位,然後也會去用 animation
做動畫,那這樣好了,不在偽元素上使用者兩樣東西咯。
題外話
說到在偽元素上使用動畫,我想起了幾年前自己在做國際網站的時候,當時好像用的比較多的是 Firefox,然後在往返程的一個模組中,就是用了偽元素的方式。
不過當時我好像使用的是 transition
,並且當時主要是考慮 Firefox,所以也沒遇到什麼問題。印象中遇到的問題就是,好像在某個瀏覽器中並沒看到那個 transition
效果,而且這個只是作為一個小“亮點”的存在,產品經理也沒砍我。想想也算萬幸的……
哦,還有,如果各位已經知道了這個 bug,也請不要嘲笑我,我真的是第一次知道,平時日常中很少這樣去寫樣式。-_”
相關文章
- CSS 之原來你是這樣子的: first-childCSS
- 讓 Chrome 崩潰的一行 CSS 程式碼ChromeCSS
- 原來你是這樣的FlutterFlutter
- 原來你是這樣的switch~
- 原來你是這樣的PromisePromise
- 原來你是這樣的GitGit
- app 崩潰的原因APP
- 原來 CSS 與 JS 是這樣阻塞 DOM 解析和渲染的CSSJS
- 學會這些CSS技巧讓你寫樣式更加絲滑CSS
- APP防崩潰APP
- 能否讓APP永不崩潰—小光與我的對決APP
- 原來JavaScript是這樣執行的JavaScript
- 原來Stable Diffusion是這樣工作的
- JavaScript 中的原型原來是這樣的JavaScript原型
- 原來CSS中的border還可以這樣玩CSS
- 原來CNN是這樣提取影像特徵的。。。CNN特徵
- 原來你是這樣的http2......HTTP
- javascript棄坑之路之原來是這樣的thisJavaScript
- 2. 媽呀,Jackson原來是這樣寫JSON的JSON
- Dapper原來還可以直接這樣寫SQL,很強大哦APPSQL
- 支招:原來這些才是APP崩潰的主要原因!資深技術大牛測試經驗總結APP
- WkWebView 令人崩潰的崩潰WebView
- GodBlessYou: 讓你的應用不再崩潰Go
- 實戰技巧,Vue原來還可以這樣寫Vue
- 【Spring】原來SpringBoot是這樣玩的Spring Boot
- 原來你是這樣的Websocket--抓包分析Web
- 執行緒崩潰為什麼不會導致 JVM 崩潰執行緒JVM
- 程式媛眼中的程式猿原來是這樣子的!
- 這個不起眼的“黑點”表情:讓所有安卓機秒崩潰安卓
- 原來YouTube推薦系統的內幕是這樣……
- 探索React Hooks:原來它們是這樣誕生的!ReactHook
- 「趣圖」CSS 又歪了!你是第幾次被 CSS 搞崩潰了?CSS
- 【效能管理】為毛我的APP崩潰了?!APP
- 谷歌叫停VR耳機計劃 原因原來是這樣谷歌VR
- 大資料解讀:原來你是這樣的Z世代!大資料
- 讓Google Chrome崩潰?只需16個位元組!GoChrome
- vue原來可以這樣上手Vue
- Vuex原來可以這樣上手Vue