Chrome 39 CSS3 漸變更畫BUG

原本地圖網頁運行的好好的,忽然從上週四(2014/11/27)開始,就開始接到 PM 和 QA 說網頁崩潰的報告。javascript

而後我就在本機重現,剛開始覺得是有網頁上有什麼內存泄漏;但是都運行這麼長時間了,而且 IE 和 Firefox 都沒有出現過此問題,看來應該是和 chrome 有關係了。說歸這樣說,但是須要證據啊。因而就猜想是否是 Chrome 新自動升級引入的BUG,而後就開始了漫長的排查過程。html

找了好幾個同事來協助排查,也沒有發現頁面上有任何內存使用異常的現象;可是就 Chrome 進程內存卻會飆升,而且嗖嗖的一會就 600M 以上了。java

一開始覺得是頁面 flash 致使的;因而就把頁面引入的 flash 去掉了,可對比後發現才省去 7M 內存(一個 flash 就佔 7M,而整個頁面內存才佔用 20M,看來 flash 做爲內存殺手和崩潰殺手,果然名不虛傳啊)。而後就滿懷驚喜的測試,結果是頁面依舊會崩潰,這下又無奈了。web

沒辦法,只能從頭再來,一步步的跟蹤時間點。刷新了好屢次以後,終於發現了一個規律,頁面在加載完地圖後,開始內存飆升,CPU 滿負荷運轉。等過個幾十秒,CPU正常,而後地圖開始陸續加載低圖。chrome

這下終於找到了一個突破口,因而找來地圖開發的同窗,讓來協助定位問題所在。可一塊兒研究了半天,除了觀察到頁面爆卡這個現象以外,緣由排查依舊毫無進展。因而又不停地刷新頁面,觀察規律。每次都是先加載地圖低圖,而後頁面 UI 中止響應,再過一段時間,頁面正常,開始加載頁面其餘地圖底圖。觀察了不知道多少次以後,猜想多是地圖縮放致使的。由於頁面地圖加載後,會有一次放大,此時頁面就會崩潰;在其餘同窗機器上測試,有的會復現,有的不會復現,好像就是由於有的同窗頁面會有地圖放大操做,而有的沒有地圖放大操做。app

肯定了這個緣由以後,趕忙寫了一個測試代碼。CSS以下:測試

.div { 
    height: 600px; 
    width: 600px; 
    background: red; 
}
.transform {
    transform: scale(200);
}
.transition {
    -webkit-transition: -webkit-transform .25s cubic-bezier(0, 0, .25, 1);
    -moz-transition: -moz-transform .25s cubic-bezier(0, 0, .25, 1);
    -o-transition: -o-transform .25s cubic-bezier(0, 0, .25, 1);
    transition: transform .25s cubic-bezier(0, 0, .25, 1)
}

因爲是作地圖開發的,因此也放入一些地圖底圖圖片,HTML 以下代碼:spa

<div class="div transition" id="d1">
    <img src="http://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&amp;size=1&amp;scale=1&amp;style=7&amp;x=1685&amp;y=775&amp;z=11">
    <img src="http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&amp;size=1&amp;scale=1&amp;style=7&amp;x=1686&amp;y=775&amp;z=11">
    <img src="http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&amp;size=1&amp;scale=1&amp;style=7&amp;x=1685&amp;y=776&amp;z=11">
    <img src="http://webrd03.is.autonavi.com/appmaptile?lang=zh_cn&amp;size=1&amp;scale=1&amp;style=7&amp;x=1686&amp;y=776&amp;z=11">
    <img src="http://webrd04.is.autonavi.com/appmaptile?lang=zh_cn&amp;size=1&amp;scale=1&amp;style=7&amp;x=1685&amp;y=774&amp;z=11">
    <img src="http://webrd03.is.autonavi.com/appmaptile?lang=zh_cn&amp;size=1&amp;scale=1&amp;style=7&amp;x=1687&amp;y=775&amp;z=11">
    <img src="http://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&amp;size=1&amp;scale=1&amp;style=7&amp;x=1686&amp;y=774&amp;z=11">
    <img src="http://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&amp;size=1&amp;scale=1&amp;style=7&amp;x=1684&amp;y=776&amp;z=11">
</div>

而後就是寫一段代碼,模擬地圖放大操做,JS代碼以下:code

setTimeout(function () {
    var d1 = document.getElementById("d1");
    d1.classList.add("transform");
}, 1000);

setTimeout(function () {
    var d1 = document.getElementById("d1");
    d1.classList.remove("transform");
    document.getElementById("d1").classList.remove("transition");
}, 3000);

而後刷新一下頁面,果然,頁面還真是實實在在的卡爆了,和線上網頁卡爆現象如出一轍。orm

找到了緣由所在,而後就是怎麼解決了。頁面開發了這麼久,還真不是一時半會說改就能改的。而後費了半天的時間,把地圖 JS-API 的版本從 1.2 切換到 1.3,這下就終於搞定了(1.3版本API地圖縮放縮放過程與1.2不一樣,基本不會出現此問題)。等QA測試穩妥後,趕忙上線。這兩天快被 PM 給逼瘋了,每天在耳邊說,趕忙上線趕忙上線。

到最後,獨悅樂不如衆悅樂,遇到問題就要會和你們分享一下。一方面給 Chromium 提BUG,一方面在此碼字,真是醉了。

最後,放上頁面完整代碼,並附上內存和CPU使用圖表,有興趣的同窗能夠在本機嘗試一下,記住 chrome 的版本號是39.0.2171.71 m:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Chrome transition and transform scale bug</title>
    <style>
        .div { 
            height: 600px; 
            width: 600px; 
            background: red; 
        }
        .transform {
            transform: scale(200);
        }
        .transition {
            -webkit-transition: -webkit-transform .25s cubic-bezier(0, 0, .25, 1);
            -moz-transition: -moz-transform .25s cubic-bezier(0, 0, .25, 1);
            -o-transition: -o-transform .25s cubic-bezier(0, 0, .25, 1);
            transition: transform .25s cubic-bezier(0, 0, .25, 1)
        }
    </style>
</head>
<body>
<a href="javascript:" id="a1">點擊我,測試頁面是否相應?</a>
<div id="a1Test"></div>
<script>
    var clickedTimes = 0;
    document.getElementById("a1").addEventListener("click", function(){
        clickedTimes++;
        document.getElementById("a1Test").innerHTML = "你一共點擊了 " + clickedTimes + " 次!";
    }, false);
</script>
<div class="div transition" id="d1">
    <img src="http://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&amp;size=1&amp;scale=1&amp;style=7&amp;x=1685&amp;y=775&amp;z=11">
    <img src="http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&amp;size=1&amp;scale=1&amp;style=7&amp;x=1686&amp;y=775&amp;z=11">
    <img src="http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&amp;size=1&amp;scale=1&amp;style=7&amp;x=1685&amp;y=776&amp;z=11">
    <img src="http://webrd03.is.autonavi.com/appmaptile?lang=zh_cn&amp;size=1&amp;scale=1&amp;style=7&amp;x=1686&amp;y=776&amp;z=11">
    <img src="http://webrd04.is.autonavi.com/appmaptile?lang=zh_cn&amp;size=1&amp;scale=1&amp;style=7&amp;x=1685&amp;y=774&amp;z=11">
    <img src="http://webrd03.is.autonavi.com/appmaptile?lang=zh_cn&amp;size=1&amp;scale=1&amp;style=7&amp;x=1687&amp;y=775&amp;z=11">
    <img src="http://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&amp;size=1&amp;scale=1&amp;style=7&amp;x=1686&amp;y=774&amp;z=11">
    <img src="http://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&amp;size=1&amp;scale=1&amp;style=7&amp;x=1684&amp;y=776&amp;z=11">
</div>
<script>
setTimeout(function () {
    var d1 = document.getElementById("d1");
    d1.classList.add("transform");

}, 1000);

setTimeout(function () {
    var d1 = document.getElementById("d1");
    d1.classList.remove("transform");
    document.getElementById("d1").classList.remove("transition");
}, 3000);
</script>
</body>
</html>

CPU和內存佔用狀況:

CPU

neicun

相關文章
相關標籤/搜索