運用webkit繪製渲染頁面原理解決iscroll4閃動的問題

原:http://www.iunbug.com/archives/2012/09/19/411.htmlhtml

已經有很多前端同行抱怨iScroll4的各類問題,我我的並不贊同將這些問題歸咎於iScroll4,由於iScroll4進不管是touch事件的捕獲,仍是使用transform來處理滾動,以及將cubic-bezier應前端

用到transition上實現高效的平滑滾動,這些原理咱們都是已知的。更多原理細節能夠參看[譯]手把手教你編寫iOS上Mobile Web App實現Fixed Position和模擬滾動 一文。此文則來解釋另外一個web

被不少人誤解爲iScroll4 形成的問題,那就是內容多的頁面閃動的問題。現象表現爲:canvas

1.滑動過程當中,滾動區內的元素在釋放手指時出現細微閃動緩存

2.圖片縮放過程當中釋放手指時明顯閃動ide

3.iOS上從mobile safari打開或第三方應用內打開後,切回主屏幕再切回頁面時明顯閃動動畫

4.頁面初始時閃動spa

大體這些狀況下會有閃動,在ipad2,new ipad上會明顯看得出。3d

下面就來分析產生的緣由和解決辦法:code

首先,咱們知道iOS5給咱們帶來了

overflow-y: scroll;
overflow-x: hidden;
-webkit-overflow-scrolling: touch;

實現固定區域內的滾動,當應用這種方式實現滾動時,上面的提到的現象也會不一樣程度的出現尤爲是1,2.是那麼咱們就能夠判定不是iScroll4 的緣由了。那麼到底是什麼緣由呢?

webkit在繪製頁面時會將結構分爲各類層,當層足夠大時就會變成很大的平鋪層。這各一來webkit在每次頁面結構發生變化時不須要都渲染整個頁面而是渲染對應層了,這對渲染速度來講至關的重要。webkit會給各類層分配必定大小的「備份存儲區」在內存裏緩存起來,這就是繪製層的上下文,經過這個上下文就能夠很容易的實現各類效果(動畫,3D變換等),「備份存儲區」內存佔用大小不只依層而定,跟設備和顯示方式也是有關的,假設這在普通屏幕下是1:1的,但在Retina屏幕下則是1:2的,而且放大時這個量會成倍增長;一張圖片是10X10,普通屏幕分配的就是10X10,Retina初始則是20X20。這也代表Retina是更加消耗內存的。當層很大時,意味着「備份存儲區」會消耗更大的內存,爲了不這點,webkit並不會繪製一個很大的層來存儲一個很大的頁面,好比說平鋪層則會拆分紅不少的塊來繪製,即盡佔用儘量小的內存,只是將可視範圍內的那部分渲染出來。這就是爲何咱們在大頁面滾動時會發現下面的內容慢慢顯示,向上滾動時上面的內容還慢慢顯示的緣由。

如下則是webkit劃分爲層繪製的場景:

  1. 頁面主容器永遠是獨立的平鋪層
  2. 繪製密集型元素時,如<video>, <canvas>
  3. 應用3D transformations的元素,包括translate3d, rotate3d, translateZ
  4. 內容被增強時,如Filters, masks, reflections, opacity, transitions, animations
  5. 某些特殊的狀況下也會,如position:fixed, -webkit-overflow-scroll:touch
  6. 任何在已知層上覆蓋的內容

這對咱們解決閃動問題有什麼幫助呢?按上頁的說明,和iScroll4實現原理咱們很容易知道,iScroll4做用的滾動區是一個很大的獨立層,webkit是不會將這麼大的層整個分配內存繪製渲染的,因此,只要將滾動區域可視範圍的列表項元素緩存起來就解決這個問題了。記webkit強制緩存起來便是將他們獨立成一個層,並且這個層固然不會很大不然會被視爲平鋪層處理了。通常列表裏項裏的元素不會像頁面主容器同樣的大的。實現方式就是將列表項置身於上面的6個場景中,好比:

#wrap>section>article{-webkit-transform:translateZ(0);}/*注意這裏*/
        <div id="wrap">
            <section>
                <article>1</article>
                <article>2</article>
                <article>3</article>
            </section>
        </div>
相關文章
相關標籤/搜索