近期正處於一段工做空白區,也想着學習學習一下項目優化,因此就本身的項目出手,一步一步地優化項目。html
項目自己首先劃分功能區以Page
、Core
、App
劃分python
Page
存儲應用的模塊,包含首頁
、我的中心等
,每一個模塊下再以Controller
、View
、Model
劃分Core
存儲着一些與項目業務、界面無關的類,包括分類
、宏定義
、封裝的請求基類
等App
則存儲着一些與項目相關的類,包括API
、Base基類
等這裏使用了python
腳本 腳本地址 找出項目中未使用的圖片,結果不是很是準確,可是能夠自行判斷(存在圖片使用是根據服務端返回顯示的狀況等)
git
unUseImage.py
文件python unUseImage.py
使用後會在路徑裏輸出文件:
這裏使用工具 ImageOptim ,點擊連接下載 將項目圖片拖入優化便可 優化結果: github
這裏推薦使用LinkMap,能夠知道項目中各個類的大小,以權衡是否有替換方案 數組
安裝fui性能優化
sudo gem install fui -n /usr/local/bin
複製代碼
到項目中使用bash
fui find
複製代碼
便可找出未引用的類,自行判斷刪除便可 #####優化前與優化後的ipa
包大小對比 iphone
使用instruments leaks
檢測 打開:工具
CellTree
、下方篩選在性能優化中一個最具參考價值的屬性是FPS:全稱Frames Per Second,其實就是屏幕刷新率,蘋果的iphone推薦的刷新率是60Hz,也就是說GPU每秒鐘刷新屏幕60次,這每刷新一次就是一幀frame,FPS也就是每秒鐘刷新多少幀畫面。靜止不變的頁面FPS值是0,這個值是沒有參考意義的,只有當頁面在執行動畫或者滑動的時候,FPS值才具備參考價值,FPS值的大小體現了頁面的流暢程度高低,當低於45的時候卡頓會比較明顯。性能
Core Animation
來檢測,注:需使用真機打開: 一、Product -> Profile -> Core Animation 二、啓動應用 三、滑動查看FPS值
這個選項是檢測哪裏發生了圖層混合,先介紹一下什麼是圖層混合?不少狀況下,界面都是會出現多個UI控件疊加的狀況,若是有透明或者半透明的控件,那麼GPU會去計算這些這些layer最終的顯示的顏色,也就是咱們肉眼所看到的效果。例如一個上層Veiw顏色是綠色RGB(0,255,0),下層又放了一個View顏色是紅色RGB(0,0,255),透明度是50%,那麼最終顯示到咱們眼前的顏色是藍色RGB(0,127.5,127.5)。這個計算過程會消耗必定的GPU資源損耗性能。若是咱們把上層的綠色View改成不透明, 那麼GPU就不用耗費資源計算,直接顯示綠色。 若是出現圖層混合了,打開Color Blended Layers選項,那塊區域會顯示紅色,因此咱們調試的目的就是將紅色區域消減的越少越好。那麼如何減小紅色區域的出現呢?只要設置控件不透明便可。
運行應用 在模擬器中找到:
label.layer.masksToBounds = YES
,由於當UILabel的內容爲中文時,label實際渲染區域要大於label的size,最外層多了一個sublayer,若是不設置第二行label的邊緣外層灰出現圖層混合的紅色,所以須要在label內容是中文的狀況下加第二句。單獨使用label.layer.masksToBounds = YES
是不會發生離屏渲染的注:xib 也能夠直接設置 masksToBounds
在控件的:
+
號添加
layer.masksToBounds
打鉤便可 優化後的界面:
這個選項能夠幫助咱們查看圖片大小是否正確顯示。若是image size和imageView size不匹配,image會出現黃色。要儘量的減小黃色的出現,由於image size與imageView size不匹配,會消耗資源壓縮圖片。 選擇:
離屏渲染Off-Screen Rendering 指的是GPU在當前屏幕緩衝區之外新開闢一個緩衝區進行渲染操做。還有另一種屏幕渲染方式-當前屏幕渲染On-Screen Rendering ,指的是GPU的渲染操做是在當前用於顯示的屏幕緩衝區中進行。 離屏渲染會先在屏幕外建立新緩衝區,離屏渲染結束後,再從離屏切到當前屏幕, 把離屏的渲染結果顯示到當前屏幕上,這個上下文切換的過程是很是消耗性能的,實際開發中儘量避免離屏渲染。 觸發離屏渲染Offscreen rendering的行爲:
運行項目,打開:
在切圓角時,使用了layer.masksToBounds && layer.cornerRadius
這裏咱們換一種實現方式,使用貝塞爾曲線畫一個邊框Layer覆蓋在上面即解決了離屏渲染
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:rect byRoundingCorners:UIRectCornerAllCorners cornerRadii:CGSizeMake(cornerRadius, cornerRadius)];
CAShapeLayer *strokeLayer = [CAShapeLayer layer];
strokeLayer.path = maskPath.CGPath;
strokeLayer.fillColor = [UIColor clearColor].CGColor; //內容填充的顏色設置爲clear
strokeLayer.strokeColor = kWhiteColor.CGColor; //邊色
strokeLayer.lineWidth = 1; // 邊寬
[self.layer addSublayer:strokeLayer];
複製代碼
網上還有許多方式能夠設置圓角:
UIBezierPath + Core Graphics
切圓角UIBezierPath + Core Graphics
覆蓋鏤空圖片在四角 等等 處理後的效果:
程序運行中不免會出現崩潰,這裏咱們可使用runtime
儘可能避免一些常見的崩潰錯誤: #####eg: 給NSArray 替換 objectAtIndex:
方法
+ (void)load {
[NSClassFromString(@"__NSArrayI") swapMethod:@selector(objectAtIndex:) currentMethod:@selector(mq_objectAtIndex:)];
}
- (id)mq_objectAtIndex:(NSUInteger)index
{
if (index >= [self count])
{
return nil;
}
return [self mq_objectAtIndex:index];
}
+ (void)swapMethod:(SEL)originMethod currentMethod:(SEL)currentMethod;
{
Method firstMethod = class_getInstanceMethod(self, originMethod);
Method secondMethod = class_getInstanceMethod(self, currentMethod);
method_exchangeImplementations(firstMethod, secondMethod);
}
複製代碼
Load方法替換 objectAtIndex
爲 mq_objectAtIndex
,當調用objectAtIndex
時會走到mq_objectAtIndex
,判斷是否越界,以此來預防數組越界的crash 其餘類像NSDictionary、NSString
也能夠自行添加
iOS項目優化還有挺多方面的,包括電池優化、啓動優化等等,筆者這裏就先優化到這裏,若是有需求須要優化的話,會再進行更新,謝謝支持!