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