前言
俗話說,常在河邊走哪能不溼鞋,天天和瀏覽器打交道,發現瀏覽器竟然也隱藏BUG也不是新鮮事了。可以看下我之前的文章:
【原創】分享IE7一個神奇的BUG(不是封閉標籤的問題,的確是IE7的BUG)
【原創】三招搞死你的IE11,可重現程式碼下載(IE Crash keyframes iframe)!
【原創】抓個Firefox的小辮子,圍觀群眾有:Chrome、Edge、IE8-11
【續】抓個Firefox的小辮子,jQuery表示不背這黑鍋,Chrome,Edge,IE8-11繼續圍觀中
這類BUG之所以被大家所深惡痛絕,在於其隱蔽性,很多時候不能用常規的邏輯去分析。另一個原因是開發人員一般都很善良,出現問題總是從自身找原因,很少會懷疑到IDE,瀏覽器這些開發工具上面來。
事實情況是,瀏覽器也是開發人員開發的,是個軟體就有BUG!
今天公開的這個Chrome BUG一直長期存在,並且行為表現的和IE11下的一模一樣,而Edge和Firefox沒有這個問題,下面就聽我詳細道來......
起因
最初這個問題是我們的一個客戶發現的,為了測試效能,客戶修改了官網示例的程式碼:
https://pro.fineui.com/#/gridpaging/gridpaging_pageitems_pagesize_database.aspx
增加到每頁 100 行資料,就有如下的聊天截圖:
總結下來,這個問題有如下特點:
1. 滾動時卡頓,CPU佔用率飆升至 27%,滾動結束後CPU佔用率下降
2. IE11下滾動中有白屏
為了重現這個效果,我們加大了測試力度,把列增加到100列,行調整為190行,在Chrome下的效果如下:
在滾動過程中,可以明顯看到白屏!!
分析問題
由於這個白屏發生在滾動的過程中,所以首先懷疑 FineUIPro 註冊的滾動事件,如下所示:
me._fjs_gridBodyctEl.on('scroll', function (event) { return; ...... }
scroll事件處理函式中直接返回,測試發現白屏依舊!
既然不是JavaScript程式碼導致的,那就可能是CSS程式碼,因為 FineUIPro 中用到了 CSS3 動畫,而白屏可能是動畫過程,這是極有可能的:
/* .f-animation .f-calendar-header .f-calendar-nav, .f-animation .f-tool, .f-animation .f-btn, .f-animation .f-tab-header .f-tool.f-tool-close .f-tool-icon, .f-animation .f-checkbox, .f-animation .f-radiobutton { -webkit-transition: background-color .3s, border-color .3s, color .3s; transition: background-color .3s, border-color .3s, color .3s; } .... */
經測試白屏依舊!!
既然不是JavaScript的影響,也不是CSS3 動畫的影響,莫非是某些CSS規則導致的?
為了便於分析問題,我們將頁面生成的HTML拷貝到一個獨立的檔案中,在頁面中只引用 FineUIPro 的CSS檔案,經過一點一點的對CSS進行刪除測試,最終發現瞭如下程式碼會對頁面滾動產生影響:
由於表格有近200行100列,所以這個測試檔案有 3M 左右,文末會提供下載,你也可以自行測試。
簡單來說,就是如下兩個CSS規則:
.f-grid-cell { overflow: hidden; } .f-grid-cell-inner { position: relative; }
其中,f-grid-cell 是表格的 td 元素,而 f-grid-cell-inner 是表格 td 裡面的 div 元素,如下所示:
<td class="f-grid-cell"> <div class="f-grid-cell-inner">楊婷婷</div> </td>
在Chrome中測試效果如下:
這裡觀察到兩個顯現:
1. 滾動中有明顯的白屏
2. Chrome的CPU佔用率由最初的 0%,隨著滾動的進行一路飆升到 19%
現在修改頁面上的CSS規則如下:
.f-grid-cell { /* overflow: hidden; */ } .f-grid-cell-inner { position: relative; }
也即是註釋掉表格td元素的 overflow 樣式規則,重新整理頁面,再次測試:
僅僅是註釋掉 td 的 overflow:hidden 屬性,這次的現象截然不同:
1. 滾動過程中已沒有白屏現象
2. Chrome的CPU佔用率在滾動過程中最高不超過 5%
說明Chrome在解析如下兩個屬性時出現了問題,至少目前發現的這個問題是由於這兩個屬性衝突導致的:
1. TD 上的 overflow 屬性
2. TD 內部 DIV 上的 position:relative
瀏覽器對比
為了確定是否其他瀏覽器也有類似問題,我們分別對 Edge,IE11,Firefox進行測試,這些瀏覽器都是目前最新版,版本如下:
1. Chrome:75.0.3770.100(正式版本) (64 位)
2. Firefox:68.0.1 (32 位)
3. Edge:44.18362.1.0
4. IE11:11.239.18362.0
測試程式碼是如下兩個CSS屬性同時存在的情況:
.f-grid-cell { overflow: hidden; } .f-grid-cell-inner { position: relative; }
Chrome:前面已經測試過了。
Edge:
IE11:
Firefox:
下面對比下各個瀏覽器的表現:
- Chrome:滾動時出現白屏,CPU 在滾動過程中會飆升到 19%
- Edge:滾動時不會出現白屏,CPU 在滾動過程中會升到到 9%
- IE11:滾動時出現白屏,CPU 在滾動過程中會飆升到 17%
- Firefox:滾動時不會出現白屏,CPU 在滾動過程中會升到到 5%
而把CSS樣式改為:
.f-grid-cell { /* overflow: hidden; */ } .f-grid-cell-inner { position: relative; }
則在滾動時,四個瀏覽器都不會出現白屏現象,CPU佔用率也會提升,但已經沒有那麼明顯,看下Chrome下的表現:
IE11下的表現:
這裡的效果和之前的有天壤之別,簡單概述下,在Chrome下:
- 新增 TD 的 overflow 屬性:滾動時有白屏現象,CPU佔用率會飆升到 19%
- 去掉 TD 的 overflow 屬性:滾動時沒有白屏,CPU佔用率小於3%
在IE11下:
- 新增 TD 的 overflow 屬性:滾動時有白屏現象,CPU佔用率會飆升到 19%
- 去掉 TD 的 overflow 屬性:滾動時沒有白屏,CPU佔用率會升到10%
解決辦法
目前的解決辦法也很簡單,去掉 TD 的 overflow 屬性,這個設定應該屬於歷史遺留程式碼,暫時也沒有什麼用處。
最後,再來對比下修改前後,在Chrome 下 FineUIPro 測試頁面的執行效果:
修改前:
修改後:
效能提升明顯!
注意:不是說td有 overflow:hidden 屬性就會出現這個滾動問題,而是要同時滿足如下幾個條件:
1. 頁面結構如下:
<td class="f-grid-cell"> <div class="f-grid-cell-inner">楊婷婷</div> </td>
2. 頁面樣式包含:
.f-grid-cell { overflow: hidden; } .f-grid-cell-inner { position: relative; }
3. 表格包含大量的元素,本示例包含200行100列。
你也可以自行測試:
不忘初心,砥礪前行!