通常的 CSS 代碼只會出現 UI 版式或者兼容性方面的小問題。但這裏咱們要分享一行有趣的 CSS,它能夠直接讓你的 Chrome 頁面掛掉 :)後端
<body>
增長樣式 style: "width:1px; height:1px; transform:scale(10000)"
其實這臺機器只有 8GB 內存,不過這不重要了。和讓 JS 崩潰的紅線容量 4GB 比起來,果真仍是 CSS 更強大呢 :)瀏覽器
這行代碼的發現,源自於咱們的編輯器項目在實現畫布尺寸調節時的一個詭異現象:用戶調節畫布尺寸時,只要新舊尺寸之比超過必定幅度,Chrome 就會卡死。編輯器
雖然這個問題很難由普通用戶的操做路徑觸發,不過它所致使的後果確實比較嚴重。排查時咱們首先考慮了 JS 阻塞和 DOM 重繪過頻等方面的可能性,但它們都不是問題所在。一個突破點在於調試器 Rendering 工具中 FPS Meter 的輸出:工具
這裏 GPU Memory 被佔滿了。雖然這個提示信息如今看來很明顯是與硬件加速有關的,但在沒有相關經歷的狀況下咱們仍是沒有肯定它與具體代碼之間的關聯。直到咱們偶然查看 Chrome 設計文檔中關於 Compositing 的介紹時,發現了一個行爲:Blink 會將 DOM 節點映射到 LayoutObject 的渲染樹,這棵樹中的節點理論上每一個都能具有到渲染後端的上下文,但爲了節約資源 Chrome 會將它們作一些合併後再渲染。而這時存在 CSS 定位(如絕對定位與 transform)的元素是不能合併的,這會形成對顯存的額外開銷。設計
基於這個信息的提示,咱們使用 Layout 工具來調試當時的頁面,果真找到了一個特殊的地方:調試
圖中最大的矩形 Layer 經過通常的 DOM 調試是沒法看見的,所以咱們推測它的過大尺寸所致使的 RAM 開銷是罪魁禍首。基於這個信息,咱們最後找到了一個寬高都很合理但 transform 的 scale 值可能在邏輯中被修改得很大的 DOM 節點,限制它的 scale 上限便可解決問題:咱們不難發現 scale 的值和最終對應像素數量之間有着 O(N^2) 的關係,1 個像素只放大 100 倍也有 10000 個像素了。所以 scale 很大時對內存 / 顯存的過分使用也就是有可能的了(固然瀏覽器會作 Tiling 等工做,所以這不符合通常狀況下的實際情形,Safari / Firefox 這時候也沒有出現問題)。最後給 Chrome 提了個 bug 見 #894115code
須要注意的是,由於缺少對瀏覽器內核的深度瞭解,上面的調試思路極可能是不許確的。簡單的總結:orm
但願大佬指正,謝謝 XDcdn
edit: 彷佛不是全部設備必現的,讓配置太好掛不掉的吃瓜同窗們失望了。想更肯定地復現的同窗,在 bug 連接中有更容易復現問題的用例哈blog
edit-2: Chrome 團隊能夠復現並 assign 了這個問題,見 #894115