一次 TableView 性能優化經歷

jopen 9年前發布 | 16K 次閱讀 TableView iOS開發 移動開發

 

一次 TableView 性能優化經歷

作者:@__weak_Point 。

題外話

前段時間才換了工作,從面試準備到入職新公司,大概有半個多月時間吧,感慨頗深。找工作,太多運氣成分在里面。有一些話想分享給大家:1.多認識一些這個行業的朋友,說不定你的下份工作就是其中的一個朋友介紹的。2.最好不要在7、8月份換工作,因為真的很熱。

緣由

來到新公司后,一開始是熟悉項目、代碼,以及改bug(填坑),然后上周開始做新的功能(準備挖坑)。生活不就是不停的挖坑和填坑嗎?!遇到了一個Tableview卡幀的問題,花了點時間才解決,記錄一下吧。好了,廢話不多說,先上張效果圖:

一次 TableView 性能優化經歷

ps:其實是仿照nice的照片詳情瀏覽效果

現在的照片詳情頁面是一個單獨的頁面(vc),用戶想看其他的照片詳情,需返回上一級頁面,再點擊進來,然后下個版本產品想改成上面那種效果。當時我想到兩種方案:

一:用一個傾斜90°的tableview來做,簡單,不用自己維護重用隊列,每個cell放一個 vc 的view 就可以了,so easy。但是后面出現了問題,沒記太清,當時也忘了截圖,就換用第二種方案。

二:用scrollView來寫,自己來維護重用隊列,具體做法大家可以參考 UIScrollView 實踐經驗 (3.重用) 。最后“完美”地實現了需求,開始做別的需求去了。

因為當時在模擬器上開發,也沒想到真機上會卡幀。過了1天,這個功能提交給測試,然后就發現了問題:在scrollView滾動的時候,明顯的感覺到了卡幀,然后就開始優化。

ps:有關TableView的效果一定要跑真機!!有關TableView的效果一定要跑真機!!有關TableView的效果一定要跑真機!! (重要的事說三遍)

卡幀猜想

因為也沒有仔細看那個vc以及cell中的代碼,就大概猜想了一下卡幀的原因:

1.尼瑪,該不會是 UIScrollView的重用 沒寫好?

斷點驗證了下,vc只會創建3個,重用沒問題呀。

2.因為涉及重用,所有vc里面tableview的內容肯定不是一下子全請求出來的,每滾動一次才會去請求下個頁面的數據,以及初始化頁面。然后再看 nice,忽然發現它滾動的時候,狀態欄居然沒有網絡請求的小菊花!!難不成是一次請求的?應該不會吧,這么多數據呀。為了驗證這種猜想,用 Charles 攔截下,結果nice也是每滾動次發次請求的:

一次 TableView 性能優化經歷

iOS開發工具-網絡封包分析工具Charles

3.這個時候我又想到去搜nice的iOS工程師的github 和 博客,可惜github不能搜組織,就在微博搜了下

一次 TableView 性能優化經歷

一次 TableView 性能優化經歷

(互相關注 是后來事)

一次 TableView 性能優化經歷

最后找到了他的博客,但是可惜沒有找到我想要的。。。

進入正題

不管什么原因,先跑下Instruments三件套吧(Time Profiler,Core Animation,GPU Driver)

一次 TableView 性能優化經歷

性能調優

好嘛,真是卡,一個一個看吧

1.首先排除了GPU的問題

一次 TableView 性能優化經歷

2.CPU

一次 TableView 性能優化經歷

這算多嗎?我不太確定,對比 上面性能調優一文中的這段

一次 TableView 性能優化經歷

得了,還是看那個vc里面是怎么寫得吧??

網絡請求

- (void)refreshData
{
  HBStoryDetailFetcher fetcher = [[HBStoryDetailFetcher alloc] init];
  fetcher.parameters = @{@"id": _story_id};
  [self runFetcher:fetcher forView:self.view success:^{
    _story = [fetcher.story mutableCopy];
    [self refreshCommentList];
  } failure:^(NSError error){
    [self refreshCommentList];
  }];
}

  • (void)refreshCommentList { HBCommentListFetcher *fetcher = [[HBCommentListFetcher alloc] init]; fetcher.parameters = @{@"story_id": _story_id}; [self runFetcher:fetcher forView:self.view success:^{ _page = 0; _comments = [[NSMutableArray alloc] init]; [_comments addObjectsFromArray:fetcher.comments]; [_tableView reloadData]; if (fetcher.comments.count == 20) {
    [self addLoadMore];
    
    } } failure:^(NSError *error){ [_tableView reloadData]; }]; } UITableViewDataSource
  • (UITableViewCell )tableView:(UITableView )tableView cellForRowAtIndexPath:(NSIndexPath )indexPath { if (indexPath.row == 0) { HBStoryDetailCell cell = [tableView dequeueReusableCellWithIdentifier:@"feedHomeCell" forIndexPath:indexPath]; cell.parent = self; cell.isStoryDetailView = YES; cell.indexPath = indexPath; cell.story = _story; cell.delegate = self; [cell updateUI]; return cell; } else { HBStoryCommentCell *cell = [tableView dequeueReusableCellWithIdentifier:@"commentCell" forIndexPath:indexPath]; cell.parent = self; cell.indexPath = indexPath; cell.story = [_comments[indexPath.row-1] mutableCopy]; [cell updateUI]; return cell; } } UITableViewDelegate
  • (CGFloat)tableView:(UITableView )tableView heightForRowAtIndexPath:(NSIndexPath )indexPath { if (indexPath.row == 0) { return [HBStoryDetailCell calculateHeightForStory:_story] - [HBStoryDetailCell commentLabelHeight:_story]; } else { return [HBStoryCommentCell calculateHeightForStory:_comments[indexPath.row-1]]; } }</pre>
 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!