最近做項目的過程中遇到無限加載的問題,主要是當商品數(shù)據(jù)比較多時頁面卡頓的問題严卖,以及解決辦法席舍。
可能很多小伙伴都已經(jīng)做過這樣的業(yè)務(wù),而且網(wǎng)上也有很多很成熟的框架哮笆,下拉更新来颤,上滑加載更多很常見的業(yè)務(wù)場景。
以前也做過這樣的業(yè)務(wù)稠肘,不過頁面布局相對來說簡單一些福铅,并沒有發(fā)現(xiàn)問題,這次的應(yīng)用場景相對復(fù)雜项阴,頁面中有四處需要滑動的地方
1滑黔、3、4分別是導(dǎo)航區(qū)域环揽,2是內(nèi)容展示區(qū)域點擊不同的導(dǎo)航切換不同的內(nèi)容略荡,并且區(qū)域2內(nèi)還要有無限滾動還要下拉切換上一個分類,內(nèi)容中商品有圖片歉胶、標題汛兜、價格、銷量通今、平臺等等信息粥谬,頁面比較復(fù)雜,不多贅述辫塌,這里只是形容下復(fù)雜情況無限加載遇到的問題帝嗡。
先來說下主要問題,就是卡璃氢,內(nèi)容加載多了后就會卡,ios表現(xiàn)很不錯狮辽,但安卓數(shù)據(jù)多了后慘不忍睹一也。
頁面滑動的形式基本有三種
一巢寡、body的整體滾動,
優(yōu)勢很明顯椰苟,第一不卡抑月,完美的解決方案,很流暢舆蝴,無論是ios還是安卓谦絮,第二省心,內(nèi)容多了自動就有滾動條洁仗,
劣勢就是不能分層层皱,例如拿上圖示例,如果用body滾動赠潦,區(qū)域2就是body內(nèi)容區(qū)域叫胖,1、3她奥、4則是fixed定位上去的壓倒的body 上瓮增,模擬出銜接在旁邊的感覺,正常情況下沒有問題哩俭,互不干擾绷跑,但是快速滑動一下區(qū)域二讓他滾動起來,然后在滾動未停止的時候滑動區(qū)域三凡资,會發(fā)現(xiàn)你滑動的不是區(qū)域三還是區(qū)域二(雖然你手指在區(qū)域三內(nèi)砸捏,但沒卵用)而且你也沒有辦法來阻止這種行為,因為在這種快速的慣性滑動時候你拿不到任何的回調(diào)讳苦,手指在區(qū)域3中的touch回調(diào)是不觸發(fā)的带膜。
二、div區(qū)塊滾動
div滾動控制好高度鸳谜,給上overflow-y:scroll 當內(nèi)容過高時會出現(xiàn)滾動條達到可以區(qū)域滾動的目的膝藕。
優(yōu)勢:性能方面過得去,(簡單的布局情況下)雖然比不上body但是也在接受范圍咐扭,主要的是比較自由相互之間不影響芭挽。
劣勢:微信瀏覽器中ios 在頂部下拉會觸發(fā)默認的彈性滑動,這里的滑動分兩種 一種是在頂部下拉蝗肪,會顯示“此網(wǎng)頁由 XXX.XXX.XXX 提供” 俗稱露底(body滾動也存在這種情況)袜爪,另一種是在頂部的時候向上回一小下,再下拉也會出現(xiàn)這種彈動但沒有 提供信息什么的 第二種情況是div的默認滾動薛闪,當然這些都可以使用代碼解決辛馆,判斷手指移動距離以及方向可以用阻止默認行為的方式來避免,當然這也是一些小煩惱,但是碰到復(fù)雜情況的布局商品加載超過二百條后昙篙,ios表現(xiàn)可以腊状,安卓只用用慘烈形容。
三苔可、css3模擬滾動缴挖,自己畫滾動條
利用transform translate(0px, 0px) 控制div的位移方向,然后再按照比例畫個滾動條出來焚辅,
優(yōu)勢:控制性強映屋,各種回調(diào)函數(shù)可拿,各種位置可控制同蜻,而且解決安卓下沒有觸底后的彈性滾動問題棚点,很人性化,并且有的框架自身集合了下拉刷新和上拉加載的回調(diào)埃仪,就算沒有提供乙濒,根據(jù)框架的各種回調(diào)想寫一個也是事半功倍。
劣勢:只能應(yīng)付簡單的布局卵蛉,場景復(fù)雜后ios表現(xiàn)尚可颁股,安卓比慘烈更慘烈,數(shù)據(jù)多了后像看ppt一樣還不如ppt流程傻丝。寫個靜態(tài)的列表或是分類集合什么的還是蠻不錯的選擇甘有。
嘗試了幾款市面上主流的框架,jroll 2 better-scroll iscrol 他們的原理差不多葡缰,使用的方法也差不多亏掀,個人感覺 iscrol 優(yōu)于 jroll 2 better-scroll, jroll 2 優(yōu)于 better-scroll泛释,但是也沒卵用哪個都沒有達到滿意的程度滤愕。
經(jīng)過幾次實驗都沒有最終的解決問題,但是大概的摸清了幾種滑動方式的優(yōu)缺點怜校,body滾動 > div區(qū)間滾動 > css3模擬滾動(不要在意命名间影,這是我自己取的名)
首先問題出現(xiàn)了 比較卡 解決問題第一步向來都是找到問題根源才能對癥下藥,所以首先思考時哪里造成的卡頓茄茁,有三種猜想
1 加載卡頓
頁面打開首先要加載數(shù)據(jù) 數(shù)據(jù)獲取到要根據(jù)商品圖片的src 去獲取圖片魂贬,是不是這層層數(shù)據(jù)加載造成的卡頓
2 渲染的卡頓
剛開始數(shù)據(jù)在兩百條以內(nèi)還是滿流程,隨著數(shù)據(jù)越來越多 需要渲染的圖片文字增多 會不會是內(nèi)容太多造成的渲染卡頓
3 布局的卡頓
簡單樣式布局情況下很流暢裙顽,是不是頁面中渲染的布局div層層嵌套過多造成的卡段
問題分析出來 總結(jié)可能造成卡頓問題的關(guān)鍵點 接下來就是開始一一測試
根據(jù)上面的總結(jié) 前后測試了幾次 分別 模擬數(shù)據(jù)(阻斷了加載)去掉圖片渲染 以及改變布局
發(fā)現(xiàn)和數(shù)據(jù)加載沒有關(guān)系付燥,不渲染圖片頁面明顯流程了一些,改變成簡單布局了以后又上升了一些愈犹。
找到了關(guān)鍵點 其實就是渲染的問題键科,但是也不能不渲染,啥都不顯示肯定嘎嘎快但是人家用戶看啥,采取戰(zhàn)略減少渲染的商品萝嘁,思路根據(jù)用戶所瀏覽的位置梆掸,展示用戶當前所能看見區(qū)域的商品,其余商品隱藏牙言,滑動技術(shù)用div區(qū)塊滑動
紅色是當前用戶屏幕所在區(qū)域,黃色部分是渲染的商品怪得,其余部分是未渲染商品咱枉,用戶每次滑動都根據(jù)屏幕距離頭部的距離進行計算, 得出用戶正在瀏覽區(qū)域的商品然后上下預(yù)加載兩個防止用戶往回滑動徒恋,這樣就最小程度的保證了渲染的數(shù)量蚕断。
但是測試結(jié)果還是不盡人意,因為計算量太大了每次滑動都要進行百次的計算入挣,滑動的回調(diào)次數(shù)很密集亿乳,而且用戶瀏覽滑動時會很頻繁的釋放和加載不同的商品,這些也都很耗費性能径筏。
所以再次改變策略葛假,(重點來了 下面是解決問題的思路)
第一要減少計算量,滑動回調(diào)密集要盡量少計算滋恬,減少不必要的計算量聊训。
第二要減少渲染切換的頻率,每次滑動都有商品在隱藏有商品在渲染恢氯,這也是很大的性能開銷带斑。
根據(jù)最新的思路開始從新規(guī)劃
1 商品分組 每次分頁加載的數(shù)據(jù)都要分組,每一百個商品 一組勋拟, 在商品信息中加個屬性 group : 1 這樣 前一百的商品 都是等于1 第100至200 就等于2 以此類推
2 記錄當前所展示的分組 showGroup:[1] showGroup 最多可能有兩個成員連續(xù)[0,1] 像這樣
3 商品組件里面 根據(jù) showGroup 進行判斷 判斷自己的 group 是不是在 showGroup 內(nèi) 如果在正常渲染 否則 渲染有個空div 高度和商品的高度一樣
準備工作完成 然后 優(yōu)化計算 也很簡單
當前屏幕距離頂部的高度 / 商品高度 / 100
大家好好想想 這樣計算后 你就能得到 1.xxxxxxx 或是 2.xxxxxx 這就是所展示的分組
然后再計算一次
(當前屏幕距離頂部的高度 / 商品高度)- 100
這樣就能知道渲染是的是當前的分組第幾個商品 根據(jù)這個值來對比 小于15 showGroup 變成[0,1] (假設(shè) showGroup 原本是[1] 也就是用戶瀏覽在 第100-200 位置)如果大于85 就是 [1,2] 用這樣的形式來預(yù)判用戶滑動的方向形成了預(yù)加載的形式勋磕,無論用戶怎么滑動都有商品可以瀏覽,而且最多還可以保障200條商品敢靡。
最后切記要對比 只有在 showGroup 不同的時候再去更新 showGroup 所以每次滑動只需計算兩個公式 形成 數(shù)組和 showGroup 比較即可挂滓,也減少了計算量
這就是基本解決問題的思路。
總結(jié) 主要的解決思路就是 用div區(qū)塊滾動 + 商品展示隱藏醋安,每次只展示100個商品其余隱藏
最后在聊一聊與之相關(guān)的 不展示的商品隱藏 在制作的過程中 使用過 visibility:hidden 這樣的屬性步清,這樣的好處是 可以不用換成div 設(shè)置和商品高度一樣 解決了適配的問題因為有的屏幕小 不讓頁面跳動说敏,對高度還是很嚴格的 但是 visibility:hidden 這個屬性還是有些卡頓,沒有直接變成一個簡潔的div流程。
再說說為什么的選擇 div區(qū)塊滾動 因為這多少也算是原生的滾動性能還是蠻不錯的纤虽,body肯定不能用,不滿足業(yè)務(wù)場景渴邦,css3沒有這個流程所以就選擇了這個走触,而且也沒有完全獨立用自己寫的 采用的是mescroll 框架 是一款很不錯的解決下拉刷新 上滑加載的js框架 他內(nèi)部采用的就是 div區(qū)塊滾動 滑動頭部根據(jù)手指滑動距離增加高度來實現(xiàn)的拉動效果,主要的是他采用div區(qū)塊滾動所以整理來說很流暢。
好习勤,想說的就是這些踪栋,以上是我遇到的問題以及解決思路。