摘要:方案未引起重視,并沒有做出相應(yīng)處理。頁面中元素的布局是相對的,因此一個元素的布局發(fā)生變化,會聯(lián)動地引發(fā)其他元素的布局發(fā)生變化。這里可以使用的和來分析的性能。寫在最后性能優(yōu)化是一門做減法的藝術(shù)。
歡迎一起交流
歡迎關(guān)注我的個人公眾號,不定期更新自己的工作心得。
題記:可以把這篇文章看成一次事故記錄,一次線上事故。此刻我能坐在這里寫下這篇文章,要感謝我司沒有開除我,或者說我解決了這次性能問題,所以我有機會寫下這篇文章。
起因我司全球購業(yè)務(wù)改版,將原生的全球購頁面采用Hybird模式開發(fā),這是我司H5頁面第一次出現(xiàn)在以及入口位置,作為開發(fā)者顯得很是興奮。
第一階段 - 問題初顯 問題根據(jù)設(shè)計稿,如期完成工作,測試也已準備好,部分Android低端機中顯示出卡頓現(xiàn)象,出于對自身技能的肯定,誤以為是硬件性能問題,并未引起過多關(guān)注。
方案未引起重視,并沒有做出相應(yīng)處理。
第二階段 - 引起重視 問題上到pre環(huán)境后,發(fā)現(xiàn)部分iPhone機型出現(xiàn)崩潰,初步排查在iOS 8.4系統(tǒng)上DOM節(jié)點高度達到10000px以上奔潰率100%,其他8-9之間的系統(tǒng)版本當(dāng)分頁數(shù)據(jù)使得DOM達到10000px以上快速滾動會出現(xiàn)卡頓,9以上iOS系統(tǒng)與Android4.4以上系統(tǒng)均表現(xiàn)良好。定位問題后,迅速進行更多特殊機型與相應(yīng)系統(tǒng)的測試,期間借遍了公司幾百位小伙伴的手機,在此向他們表示感謝。
你問我為什么,我只能說測試環(huán)境沒有這么多數(shù)據(jù),至于為什么沒有?呵呵,你懂得!
方案iOS將UIWebview切換為WKWebview,WKWebview為iOS在8以上系統(tǒng)中新加入的一個高性能Webview,具體哪里好,可以點這里 這里 還有這里 ,由于iOS已經(jīng)發(fā)版(對的,在H5頁面還在pre環(huán)境測試的時候,iOS已經(jīng)發(fā)版了)這個方案只能作為下一個版本了
臨時降低數(shù)據(jù)顯示總量,同時尋找性能瓶頸(這里要和運營的同學(xué)說聲sorry)
實施針對iOS 8以下以及8.4系統(tǒng) Android 4.4以下系統(tǒng)做自動降級處理。
一些經(jīng)驗測試不能僅僅做功能測試,還要做性能測試
開發(fā)人員常使用chrome、Firefox等瀏覽器的開發(fā)工具進行開發(fā),這里要注意的是:瀏覽器開發(fā)工具只能模擬手機UI與交互,其性能要遠遠強于手機環(huán)境。
開發(fā)過程中常用微信、QQ、手機瀏覽器進行測試,這是不可取的,因為最終環(huán)境不一,容易給自己造成錯覺,覺得在微信 QQ的Webview中沒問題,就OK了
deadline 真的要好好定。很多人認為H5很靈活,并不依賴于iOS發(fā)版,可以將測試定在iOS發(fā)版的那幾天進行。其實這真的是巨大的錯誤,后面我會說明。
第三階段 - 全面升級經(jīng)過降級后,仍然存在很多問題,同時我們也在抓緊研究后續(xù)升級方案。經(jīng)過協(xié)調(diào),將系統(tǒng)切回了老版本暫時使用原生替代H5(感覺很受打擊~)。
問題數(shù)據(jù)量不足,對運營影響很大
對降級機型的體驗很差,數(shù)據(jù)統(tǒng)計顯示,受影響的機型還是有一定份額
由于此次H5是存在于以及目錄,所以設(shè)計上是常駐內(nèi)存以保證體驗,UIWebview的內(nèi)存一直得不到釋放,同事系統(tǒng)中其他頁面也使用到了UIWebview,長時間使用仍然會出現(xiàn)崩潰。
距離iOS和Android下一次發(fā)版還有一段時間,不可能一直降級
無論如何解決性能問題,這是唯一目標!
經(jīng)過一個星期枯燥而漫長的努力與實驗,從以下幾個方面徹底解決了性能瓶頸;
方案iScroll是我們內(nèi)部框架中引入的一個第三方組件,官方的介紹是「Smooth scrolling for the web」,奈何在大數(shù)據(jù)量面前性能確實令人堪憂。如果數(shù)據(jù)量少,還是推薦使用的。
在對比了競品,和天貓、JD等知名廠商H5實現(xiàn)后,確實郁悶了一段時間,同樣的數(shù)據(jù)量為什么別人可以做到?最后得到兩個結(jié)論:
別人DOM節(jié)點沒我們復(fù)雜,由于我們采用了內(nèi)部研發(fā)的m-fast框架,框架頂層就確定了DOM結(jié)構(gòu)的復(fù)雜性,例如:框架預(yù)設(shè)了整個布局為上、下、左、右、中的布局,即使我的頁面只是一個流式布局。
別人H5頁面沒有圖片輪播!對,你沒看錯,一個圖片輪播居然對性能影響如此之大
居于上面這兩點,我開始了DOM性能研究
m-fast框架采用模板預(yù)編譯技術(shù),將頁面模板編譯為js文件,在通過異步加載的方式載入,所以,網(wǎng)頁的渲染大致符合上面這五個步驟
JavaScript。一般來說,我們會使用JavaScript來實現(xiàn)一些視覺變化的效果。比如用jQuery的animate函數(shù)做一個動畫、對一個數(shù)據(jù)集進行排序、或者往頁面里添加一些DOM元素等。當(dāng)然,除了JavaScript,還有其他一些常用方法也可以實現(xiàn)視覺變化效果,比如:CSS Animations, Transitions和Web Animation API。
計算樣式。這個過程是根據(jù)CSS選擇器,比如.headline或.nav > .nav_item,對每個DOM元素匹配對應(yīng)的CSS樣式。這一步結(jié)束之后,就確定了每個DOM元素上該應(yīng)用什么CSS樣式規(guī)則。
布局。上一步確定了每個DOM元素的樣式規(guī)則,這一步就是具體計算每個DOM元素最終在屏幕上顯示的大小和位置。web頁面中元素的布局是相對的,因此一個元素的布局發(fā)生變化,會聯(lián)動地引發(fā)其他元素的布局發(fā)生變化。比如,``元素的寬度的變化會影響其子元素的寬度,其子元素寬度的變化也會繼續(xù)對其孫子元素產(chǎn)生影響。因此對于瀏覽器來說,布局過程是經(jīng)常發(fā)生的。
繪制。繪制,本質(zhì)上就是填充像素的過程。包括繪制文字、顏色、圖像、邊框和陰影等,也就是一個DOM元素所有的可視效果。一般來說,這個繪制過程是在多個層上完成的。
渲染層合并。由上一步可知,對頁面中DOM元素的繪制是在多個層上進行的。在每個層上完成繪制過程之后,瀏覽器會將所有層按照合理的順序合并成一個圖層,然后顯示在屏幕上。對于有位置重疊的元素的頁面,這個過程尤其重要,因為一旦圖層的合并順序出錯,將會導(dǎo)致元素顯示異常。
如果你修改一個DOM元素的“paint only”屬性,比如背景圖片、文字顏色或陰影等,這些屬性不會影響頁面的布局,因此瀏覽器會在完成樣式計算之后,跳過布局過程,只做繪制和渲染層合并過程。
如果你修改一個非樣式且非繪制的CSS屬性,那么瀏覽器會在完成樣式計算之后,跳過布局和繪制的過程,直接做渲染層合并。這種方式在性能上是最理想的,對于動畫和滾動這種負荷很重的渲染,我們要爭取使用這種渲染流程。
最終得出以下幾點改進:繪制,是填充像素的過程,這些像素將最終顯示在用戶的屏幕上。通常,這個過程是整個渲染流水線中耗時最長的一環(huán),因此也是最需要避免發(fā)生的一環(huán)。
CSS屬性中,除了transform和opacity之外,修改任何屬性都會觸發(fā)繪制
如果布局被觸發(fā),那么接下來繪制一定會被觸發(fā)。因為改變一個元素的幾何屬性就意味著該元素的所有像素都需要重新渲染!
如果改變元素的非幾何屬性,也可能觸發(fā)繪制,比如背景、文字顏色或者陰影效果,盡管這些屬性的改變不會觸發(fā)布局。
繪制并非總是在內(nèi)存中的單層畫面里完成的。實際上,瀏覽器在必要時將會把一幀畫面繪制成多層畫面,然后將這若干層畫面合并成一張圖片顯示到屏幕上。
這種繪制方式的好處是,使用tranforms來實現(xiàn)移動效果的元素將會被正常繪制,同時不會觸發(fā)對其他元素的繪制。
在頁面中創(chuàng)建一個新的渲染層的最好方式就是使用CSS屬性will-change,Chrome/Opera/Firefox都支持該屬性。同時再與transform屬性一起使用,就會創(chuàng)建一個新的組合層:
.moving-element { will-change: transform; }
對于那些目前還不支持will-change屬性、但支持創(chuàng)建渲染層的瀏覽器,比如Safari和Mobile Safari,你可以使用一個3D transform屬性來強制瀏覽器創(chuàng)建一個新的渲染層:
.moving-element { transform: translateZ(0); }
但需要注意的是:不要創(chuàng)建太多的渲染層。因為每創(chuàng)建一個新的渲染層,就意味著新的內(nèi)存分配和更復(fù)雜的層的管理。
上面提到的,由于框架的限制,頁面布局相對需求來說復(fù)雜很多。開發(fā)中應(yīng)該盡量避免復(fù)雜的DOM結(jié)構(gòu),復(fù)雜的DOM結(jié)構(gòu)更容易引起大面積的重繪。
渲染層的合并,就是把頁面中完成了繪制過程的部分合并成一層,然后顯示在屏幕上。
使用transform/opacity來實現(xiàn)動畫效果,目前只有transforms和opacity這兩個屬性不會觸發(fā)瀏覽器的布局和繪制,對網(wǎng)頁元素這兩個屬性的修改會直接觸發(fā)渲染層合并。
對于動畫效果的實現(xiàn),避免使用setTimeout或setInterval,請使用requestAnimationFrame。
把耗時長的JavaScript代碼放到Web Workers中去做。
這里可以使用Chrome DevTools的Timeline和JavaScript Profiler來分析JavaScript的性能。
寫在最后性能優(yōu)化是一門做減法的藝術(shù)。我們首要要盡力簡化頁面渲染過程,然后要使渲染過程的每一步都盡量高效。
THKS GoogleCSS Triggers
render performance
simplify paint
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/54337.html
摘要:方案未引起重視,并沒有做出相應(yīng)處理。頁面中元素的布局是相對的,因此一個元素的布局發(fā)生變化,會聯(lián)動地引發(fā)其他元素的布局發(fā)生變化。這里可以使用的和來分析的性能。寫在最后性能優(yōu)化是一門做減法的藝術(shù)。 歡迎一起交流 歡迎關(guān)注我的個人公眾號,不定期更新自己的工作心得。showImg(https://segmentfault.com/img/bVEk23?w=258&h=258); 正文從這里開始...
摘要:方案未引起重視,并沒有做出相應(yīng)處理。頁面中元素的布局是相對的,因此一個元素的布局發(fā)生變化,會聯(lián)動地引發(fā)其他元素的布局發(fā)生變化。這里可以使用的和來分析的性能。寫在最后性能優(yōu)化是一門做減法的藝術(shù)。 歡迎一起交流 歡迎關(guān)注我的個人公眾號,不定期更新自己的工作心得。showImg(https://segmentfault.com/img/bVEk23?w=258&h=258); 正文從這里開始...
摘要:用戶綁定的邏輯主要復(fù)雜在既需要考慮微信本身的接口在不同情況下提供的數(shù)據(jù)不同,另外一方面就是考慮本身用戶模塊的業(yè)務(wù)邏輯問題。針對每一節(jié)課以及每一節(jié)系列課程生成小程序太陽碼主要涉及到幾個細節(jié)問題。 感覺已經(jīng)好久沒寫程序了,最近這段時間,一方面是學(xué)習(xí)了python,然后折騰了scrapy框架,用python寫了下守護進程程序監(jiān)聽任務(wù)以及用redis做隊列任務(wù)通信,并開進程來處理爬蟲任務(wù)。以上...
摘要:為了一探究竟,于是開啟了這次應(yīng)用性能調(diào)優(yōu)之旅。使用即時編譯器和都能輕輕松松的讓你的應(yīng)用程序在不用做任何修改的情況下,直接提高或者更高的性能。 這是一份事后的總結(jié)。在經(jīng)歷了調(diào)優(yōu)過程踩的很多坑之后,我們最終完善并實施了初步的性能測試方案,通過真實的測試數(shù)據(jù)歸納出了 Laravel 開發(fā)過程中的一些實踐技巧。 0x00 源起 最近有同事反饋 Laravel 寫的應(yīng)用程序響應(yīng)有點慢、20幾個并...
閱讀 3291·2021-11-25 09:43
閱讀 2093·2021-09-22 10:02
閱讀 3348·2021-09-06 15:00
閱讀 2305·2019-08-30 15:56
閱讀 2356·2019-08-30 15:54
閱讀 3233·2019-08-30 14:14
閱讀 2268·2019-08-29 17:25
閱讀 2909·2019-08-29 17:16