欧美日韩激情_美女国产一区_国产精品久久久久影院日本_69xxx在线

【成都網站建設】預加載與智能預加載(iOS)-成都創新互聯官方網站

2023-01-01    分類: 網站建設

前兩次的分享分別介紹了 ASDK 對于渲染的優化以及 ASDK 中使用的另一種布局模型;這兩個新機制的引入分別解決了 iOS 在主線程渲染視圖以及 Auto Layout 的性能問題,而這一次討論的主要內容是 ASDK 如何預先請求服務器數據,達到看似無限滾動列表的效果的。

這篇文章是 ASDK 系列中的最后一篇,文章會介紹 iOS 中幾種預加載的方案,以及 ASDK 中是如何處理預加載的。

不過,在介紹 ASDK 中實現智能預加載的方式之前,文章中會介紹幾種簡單的預加載方式,方便各位開發者進行對比,選擇合適的機制實現預加載這一功能。

網絡與性能

ASDK 通過在渲染視圖和布局方面的優化已經可以使應用在任何用戶的瘋狂操作下都能保持 60 FPS 的流暢程度,也就是說,我們已經充分的利用了當前設備的性能,調動各種資源加快視圖的渲染。

但是,僅僅在 CPU 以及 GPU 方面的優化往往是遠遠不夠的。在目前的軟件開發中,很難找到一個沒有任何網絡請求的應用,哪怕是一個記賬軟件也需要服務器來同步保存用戶的信息,防止資料的丟失;所以,只在渲染這一層面進行優化還不能讓用戶的體驗達到好,因為網絡請求往往是一個應用最為耗時以及昂貴的操作。

每一個應用程序在運行時都可以看做是 CPU 在底層利用各種資源瘋狂做加減法運算,其中最耗時的操作并不是進行加減法的過程,而是資源轉移的過程。

舉一個不是很恰當的例子,主廚(CPU)在炒一道菜(計算)時往往需要的時間并不多,但是菜的采購以及準備(資源的轉移)會占用大量的時間,如果在每次炒菜之前,都由幫廚提前準備好所有的食材(緩存),那么做一道菜的時間就大大減少了。

而提高資源轉移的效率的好辦法就是使用多級緩存:

從上到下,雖然容量越來越大,直到 Network 層包含了整個互聯網的內容,但是訪問時間也是直線上升;在 Core 或者三級緩存中的資源可能訪問只需要幾個或者幾十個時鐘周期,但是網絡中的資源就遠遠大于這個數字,幾分鐘、幾小時都是有可能的。

更糟糕的是,因為天朝的網絡情況及其復雜,運營商劫持 DNS、404 無法訪問等問題導致網絡問題極其嚴重;而如何加速網絡請求成為了很多移動端以及 Web 應用的重要問題。

預加載

本文就會提供一種緩解網絡請求緩慢導致用戶體驗較差解決方案,也就是預加載;在本地真正需要渲染界面之前就通過網絡請求獲取資源存入內存或磁盤。

預加載并不能徹底解決網絡請求緩慢的問題,而是通過提前發起網絡請求緩解這一問題。

那么,預加載到底要關注哪些方面的問題呢?總結下來,有以下兩個關注點:

需要預加載的資源 預加載發出的時間

文章會根據上面的兩個關注點,分別分析四種預加載方式的實現原理以及優缺點:

無限滾動列表 threshold 惰性加載 智能預加載 無限滾動列表

其實,無限滾動列表并不能算是一種預加載的實現原理,它只是提供一種分頁顯示的方法,在每次滾動到UITableView底部時,才會開始發起網絡請求向服務器獲取對應的資源。

雖然這種方法并不是預加載方式的一種,放在這里的主要作用是作為對比方案,看看如果不使用預加載的機制,用戶體驗是什么樣的。

很多客戶端都使用了分頁的加載方式,并沒有添加額外的預加載的機制來提升用戶體驗,雖然這種方式并不是不能接受,不過每次滑動到視圖底部之后,總要等待網絡請求的完成確實對視圖的流暢性有一定影響。

雖然僅僅使用無限滾動列表而不提供預加載機制會在一定程度上影響用戶體驗,不過,這種需要用戶等待幾秒鐘的方式,在某些時候確實非常好用,比如:投放廣告。

QQ 空間就是這么做的,它們投放的廣告基本都是在整個列表的最底端,這樣,當你滾動到列表最下面的時候,就能看到你急需的租房、租車、同城交友、信用卡辦理、只有 iPhone 能玩的游戲以及各種奇奇怪怪的辣雞廣告了,很好的解決了我們的日常生活中的各種需求。

Threshold

使用 Threshold 進行預加載是一種最為常見的預加載方式,知乎客戶端就使用了這種方式預加載條目,而其原理也非常簡單,根據當前UITableView的所在位置,除以目前整個UITableView.contentView的高度,來判斷當前是否需要發起網絡請求:

let threshold: CGFloat = 0.7 var currentPage = 0 override func scrollViewDidScroll(_ scrollView: UIScrollView) { let current = scrollView.contentOffset.y + scrollView.frame.size.height let total = scrollView.contentSize.height let ratio = current / total if ratio >= threshold { currentPage += 1 print("Request page \(currentPage) from server.") }}

上面的代碼在當前頁面已經劃過了 70% 的時候,就請求新的資源,加載數據;但是,僅僅使用這種方法會有另一個問題,尤其是當列表變得很長時,十分明顯,比如說:用戶從上向下滑動,總共加載了 5 頁數據:

| Page | Total | Threshold | Diff | | :-: | :-: | :-: | :-: | | 1 | 10 | 7 | 7 | | 2 | 20 | 14 | 4 | | 3 | 30 | 21 | 1 | | 4 | 40 | 28 | -2 | | 5 | 50 | 35 | -5 |

Page 當前總頁數; Total 當前UITableView總元素個數; Threshold 網絡請求觸發時間; Diff 表示最新加載的頁面被瀏覽了多少;

當 Threshold 設置為 70% 的時候,其實并不是單頁 70%,這就會導致新加載的頁面都沒有看,應用就會發出另一次請求,獲取新的資源。

動態的 Threshold

解決這個問題的辦法,還是比較簡單的,通過修改上面的代碼,將 Threshold 變成一個動態的值,隨著頁數的增長而增長:

let threshold: CGFloat = 0.7 let itemPerPage: CGFloat = 10 var currentPage: CGFloat = 0 override func scrollViewDidScroll(_ scrollView: UIScrollView) { let current = scrollView.contentOffset.y + scrollView.frame.size.height let total = scrollView.contentSize.height let ratio = current / total let needRead = itemPerPage * threshold + currentPage * itemPerPage let totalItem = itemPerPage * (currentPage + 1) let newThreshold = needRead / totalItem if ratio >= newThreshold { currentPage += 1 print("Request page \(currentPage) from server.") }}

通過這種方法獲取的newThreshold就會隨著頁數的增長而動態的改變,解決了上面出現的問題:

惰性加載

使用 Threshold 進行預加載其實已經適用于大多數應用場景了;但是,下面介紹的方式,惰性加載能夠有針對性的加載用戶“會看到的” Cell。

惰性加載,就是在用戶滾動的時候會對用戶滾動結束的區域進行計算,只加載目標區域中的資源。

用戶在飛速滾動中會看到巨多的空白條目,因為用戶并不想閱讀這些條目,所以,我們并不需要真正去加載這些內容,只需要在ASTableView/ASCollectionView中只根據用戶滾動的目標區域惰性加載資源。

惰性加載的方式不僅僅減少了網絡請求的冗余資源,同時也減少了渲染視圖、數據綁定的耗時。

計算用戶滾動的目標區域可以直接使用下面的代理方法獲取:

let markedView = UIView() let rowHeight: CGFloat = 44.0 override func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer) { let targetOffset = targetContentOffset.pointee let targetRect = CGRect(origin: targetOffset, size: scrollView.frame.size) markedView.frame = targetRect markedView.backgroundColor = UIColor.black.withAlphaComponent(0.1) tableView.addSubview(markedView) var indexPaths: [IndexPath] = [] let startIndex = Int(targetRect.origin.y / rowHeight) let endIndex = Int((targetRect.origin.y + tableView.frame.height) / rowHeight) for index in startIndex...endIndex { indexPaths.append(IndexPath(row: index, section: 0)) } print("\(targetRect) \(indexPaths)")}

以上代碼只會大致計算出目標區域內的IndexPath數組,并不會展開新的 page,同時會使用淺黑色標記目標區域。

當然,惰性加載的實現也并不只是這么簡單,不僅需要客戶端的工作,同時因為需要加載特定 offset 資源,也需要服務端提供相應 API 的支持。

雖然惰性加載的方式能夠按照用戶的需要請求對應的資源,但是,在用戶滑動UITableView的過程中會看到大量的空白條目,這樣的用戶體驗是否可以接受又是值得考慮的問題了。

智能預加載

終于到了智能預加載的部分了,當我第一次得知 ASDK 可以通過滾動的方向預加載不同數量的內容,感覺是非常神奇的。

如上圖所示 ASDK 把正在滾動的ASTableView/ASCollectionView劃分為三種狀態:

Fetch Data Display Visible

上面的這三種狀態都是由 ASDK 來管理的,而每一個ASCellNode的狀態都是由ASRangeController控制,所有的狀態都對應一個ASInterfaceState:

ASInterfaceStatePreload當前元素貌似要顯示到屏幕上,需要從磁盤或者網絡請求數據; ASInterfaceStateDisplay當前元素非常可能要變成可見的,需要進行異步繪制; ASInterfaceStateVisible當前元素最少在屏幕上顯示了 1px

當用戶滾動當前視圖時,ASRangeController就會修改不同區域內元素的狀態:

上圖是用戶在向下滑動時,ASCellNode是如何被標記的,假設當前視圖可見的范圍高度為 1,那么在默認情況下,五個區域會按照上圖的形式進行劃分:

| Buffer | Size | | :-: | :-: | | Fetch Data Leading Buffer | 2 | | Display Leading Buffer | 1 | | Visible | 1 | | Display Trailing Buffer | 1 | | Fetch Data Trailing Buffer | 1 |

在滾動方向(Leading)上 Fetch Data 區域會是非滾動方向(Trailing)的兩倍,ASDK 會根據滾動方向的變化實時改變緩沖區的位置;在向下滾動時,下面的 Fetch Data 區域就是上面的兩倍,向上滾動時,上面的 Fetch Data 區域就是下面的兩倍。

這里的兩倍并不是一個確定的數值,ASDK 會根據當前設備的不同狀態,改變不同區域的大小,但是滾動方向的區域總會比非滾動方向大一些

智能預加載能夠根據當前的滾動方向,自動改變當前的工作區域,選擇合適的區域提前觸發請求資源、渲染視圖以及異步布局等操作,讓視圖的滾動達到真正的流暢。

原理

在 ASDK 中整個智能預加載的概念是由三個部分來統一協調管理的:

ASRangeController ASDataController ASTableView與ASTableNode

對智能預加載實現的分析,也是根據這三個部分來介紹的。

工作區域的管理

ASRangeController是ASTableView以及ASCollectionView內部使用的控制器,主要用于監控視圖的可見區域、維護工作區域、觸發網絡請求以及繪制、單元格的異步布局。

以ASTableView為例,在視圖進行滾動時,會觸發-[UIScrollView scrollViewDidScroll:]代理方法:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView { ASInterfaceState interfaceState = [self interfaceStateForRangeController:_rangeController]; if (ASInterfaceStateIncludesVisible(interfaceState)) { [_rangeController updateCurrentRangeWithMode:ASLayoutRangeModeFull]; } ...}

每一個ASTableView的實例都持有一個ASRangeController以及ASDataController用于管理工作區域以及數據更新。

ASRangeController 最重要的私有方法-[ASRangeController _updateVisibleNodeIndexPaths]一般都是因為上面的方法間接調用的:

-[ASRangeController updateCurrentRangeWithMode:] -[ASRangeController setNeedsUpdate] -[ASRangeController updateIfNeeded] -[ASRangeController _updateVisibleNodeIndexPaths]

調用棧中間的過程其實并不重要,最后的私有方法的主要工作就是計算不同區域內 Cell 的NSIndexPath數組,然后更新對應 Cell 的狀態ASInterfaceState觸發對應的操作。

我們將這個私有方法的實現分開來看:

- (void)_updateVisibleNodeIndexPaths { NSArray<NSArray *> *allNodes = [_dataSource completedNodes];

分享名稱:【成都網站建設】預加載與智能預加載(iOS)-成都創新互聯官方網站
轉載來源:http://m.kartarina.com/news20/227320.html

網站建設、網絡推廣公司-創新互聯,是專注品牌與效果的網站制作,網絡營銷seo公司;服務項目有網站建設

廣告

聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯

成都網站建設
欧美日韩激情_美女国产一区_国产精品久久久久影院日本_69xxx在线
337p粉嫩大胆噜噜噜噜噜91av| 91精品1区2区| 青青草成人在线观看| 亚洲午夜电影在线观看| 一区二区三区在线观看欧美 | 国产高清一区日本| 精品一区二区免费看| 蜜桃视频在线一区| 国产一区福利在线| 99久久久久久| 欧美午夜影院一区| 欧美日韩国产一级| 精品电影一区二区三区| 亚洲精品一线二线三线| 欧美激情综合网| 一区二区三区美女视频| 亚洲h动漫在线| 韩国视频一区二区| 91在线视频免费观看| 欧美三级电影精品| 久久综合狠狠综合久久激情| 国产视频一区在线观看| 1区2区3区国产精品| 亚洲成av人片在线| 国产91综合网| 欧美午夜免费电影| 久久久久久一二三区| 亚洲激情六月丁香| 蜜桃精品视频在线观看| 成人免费电影视频| 91精品国产综合久久蜜臀| 久久精品男人的天堂| 亚洲国产日产av| 国产成人精品免费看| 91女厕偷拍女厕偷拍高清| 日韩一区二区三区在线| 亚洲欧洲一区二区在线播放| 日本不卡视频一二三区| 99久久精品国产精品久久| 91精品国产综合久久久久| 欧美国产精品专区| 美女视频黄免费的久久| 91麻豆国产在线观看| 久久免费视频色| 青娱乐精品视频在线| 99久久精品国产精品久久| 亚洲精品一区在线观看| 午夜不卡av在线| 99久久免费精品| 欧美精品一区二区三区蜜臀| 午夜精品一区二区三区免费视频| 6080yy午夜一二三区久久| 久久久综合精品| 日韩成人dvd| 在线这里只有精品| 中文字幕中文字幕一区| 国产在线国偷精品免费看| 日韩一区二区三区高清免费看看| 亚洲精品乱码久久久久久久久| 国产99久久久国产精品免费看| 日韩精品中文字幕在线一区| 天天av天天翘天天综合网| 91国产免费看| 亚洲女与黑人做爰| 色婷婷综合久久| 伊人色综合久久天天| 99re亚洲国产精品| 自拍偷在线精品自拍偷无码专区| 成人免费视频一区| 亚洲欧洲精品一区二区三区| 99精品视频免费在线观看| 国产精品久久久久一区二区三区 | 制服视频三区第一页精品| 亚洲一区二区视频| 在线一区二区三区四区五区| 亚洲欧美aⅴ...| 在线看一区二区| 午夜欧美大尺度福利影院在线看| 在线一区二区观看| 婷婷综合在线观看| 日韩一级欧美一级| 国产乱码精品一区二区三区av | 久久久久九九视频| 粉嫩蜜臀av国产精品网站| 国产精品色在线观看| 91视视频在线观看入口直接观看www | 欧美色精品在线视频| 香蕉乱码成人久久天堂爱免费| 在线成人小视频| 国产一区二区三区最好精华液| 国产视频在线观看一区二区三区| www.99精品| 亚洲一二三区在线观看| 欧美一级片在线| 狠狠色丁香婷婷综合久久片| 中文字幕成人av| 91色九色蝌蚪| 日本中文字幕一区二区有限公司| 久久久五月婷婷| 色欧美88888久久久久久影院| 视频一区二区国产| 国产天堂亚洲国产碰碰| 欧美伊人久久大香线蕉综合69| 日本欧美一区二区| 国产精品亲子伦对白| 欧美日韩日本视频| 国产成人啪午夜精品网站男同| 一区二区三区四区中文字幕| 精品久久久久久久久久久久久久久| 高清国产一区二区三区| 午夜久久久影院| 国产精品夫妻自拍| 精品国产91乱码一区二区三区| 99国产精品久久久| 精品一区二区三区在线播放视频| 久久国产精品一区二区| 亚洲精品五月天| 久久久久国产成人精品亚洲午夜| 91丨九色丨国产丨porny| 久久精品久久综合| 亚洲一区二区三区自拍| 国产精品嫩草影院com| 91 com成人网| 欧美中文字幕一二三区视频| 国产成人综合网站| 久久99精品国产麻豆婷婷洗澡| 亚洲一二三四久久| 亚洲欧美综合另类在线卡通| 精品精品欲导航| 欧美久久久久久久久久| 91蜜桃免费观看视频| 国产馆精品极品| 国产在线播放一区三区四| 亚洲444eee在线观看| 亚洲精品乱码久久久久久久久| 国产午夜精品理论片a级大结局 | 国产成人精品免费网站| 久久av资源网| 蜜臀av一区二区| 日韩国产在线一| 五月开心婷婷久久| 亚洲一区视频在线观看视频| 国产精品久久久久久亚洲毛片 | 日韩精品视频网| 亚洲图片欧美色图| 夜夜嗨av一区二区三区四季av| 亚洲图片欧美激情| 国产精品久久久久三级| 国产精品成人在线观看| 国产精品电影院| 亚洲精品福利视频网站| 一区二区成人在线视频| 亚洲午夜在线观看视频在线| 亚洲国产日产av| 欧美aaaaa成人免费观看视频| 日韩精品成人一区二区在线| 免费在线一区观看| 久久91精品国产91久久小草| 国产一区二区三区不卡在线观看| 国产精品亚洲专一区二区三区 | 欧美一区二区在线视频| 911精品国产一区二区在线| 欧美一区中文字幕| 久久综合999| 中文字幕一区av| 亚洲午夜激情网站| 激情图区综合网| 99久久伊人精品| 欧美日韩亚洲高清一区二区| 日韩一区二区视频| 国产欧美精品在线观看| 亚洲伊人伊色伊影伊综合网| 青青草97国产精品免费观看 | 欧美精品一区二区三区蜜桃 | 肉丝袜脚交视频一区二区| 免费观看91视频大全| 国产成人精品午夜视频免费| 99久久国产免费看| 国产精品国产精品国产专区不蜜 | 欧美精选午夜久久久乱码6080| 日韩一区二区视频在线观看| 精品国产乱子伦一区| 亚洲美女在线一区| 美女国产一区二区| gogogo免费视频观看亚洲一| 欧美日韩视频在线一区二区| 国产日本欧洲亚洲| 手机精品视频在线观看| 成人午夜激情视频| 91精品视频网| 亚洲六月丁香色婷婷综合久久| 麻豆精品一二三| 色视频一区二区| 久久在线观看免费| 亚洲成av人片| 色综合久久精品| 久久久噜噜噜久久人人看| 午夜精品福利一区二区蜜股av| 国产91清纯白嫩初高中在线观看 | 成人午夜私人影院|