關於迴流,重繪,以及documentFragment,requestAnimationFrame的應用
首先在網頁裡面的DOM應該是靜態的,每一個節點長什麼樣,裡面寫的什麼,都是靜態的不會改變的,會在第一次載入的時候根據一些資訊進行繪製,之所以會發生改變是因為js腳本里改變了dom結構或者css裡觸發了一些變化,在js修改dom之後,網頁會重新渲染這個網頁,這就觸發了迴流,比如改變了一個元素的寬高,這個寬高影響了其他元素的位置,所以瀏覽器需要對檢視進行變化,而當某個元素沒有發生影響其他元素以及只對自身樣式做出改變的話只會觸發重繪不會迴流。
可以這麼理解,迴流是畫骨架,重繪是上色,骨架變化了之後對應地方的顏色也需要重新畫,但只是變了個顏色,就不用改變骨架位置。
迴流一定會導致重繪,重繪不一定會迴流。
迴流觸發的幾種情況:
1. dom結構變化,增減node節點等
2. 位置資訊發生變化,寬高邊距等
3. 初始化的時候
4. 瀏覽器大小發生改變需要適應的時候 onresize事件觸發的時候
5. 資料獲取的時候
到這裡就可以說,更改元素位置就會出發回流,重繪,改變元素樣式只會重繪,不會迴流。還要一種情況就是獲取元素資訊的時候,會觸發迴流,就是上面說的第5種情況,資料獲取的時候,因為瀏覽器要返回給你一個最新正確的資料,所以會重新繪製。
以下幾種情況:
offsetTop, offsetLeft, offsetWidth, offsetHeight
scrollTop/Left/Width/Height
clientTop/Left/Width/Height
width,height
請求了getComputedStyle(), 或者 IE的 currentStyle
所以為了更好的效能,在獲取不會頻繁改變的元素的位置資訊時,最好進行一個變數快取。
在執行一個動畫的時候最好把元素脫離文件流,以免它的變化影響其他元素導致多個元素參與迴流。
需要頻繁更改元素的時候(比如增減多個子節點)可以把display改成none,完成之後再次恢復,這樣只會觸發兩次迴流。
還有就是下面要說的使用documentFragment
documentFragment是一個虛擬的Dom列表,可以儲存待處理的xml片段(el元素),因為他不在真實的Dom結構中,所以對它所做的操作不會觸發瀏覽器的迴流,只會在他插入dom的時候觸發一次而已。
用法:
const fragment=document.createDocumentFragment();
for(let i=0;i<100;i++){
let div=document.createElement('div');
div.innerText="Hello "+ i;
fragment.appendChild(div);
}
document.querySelector('#app').appendChild(fragment);
上面把多個動態生成的div插入到了虛擬節點裡,在最後完成之後只做了一次插入,這樣就只會觸發一次迴流。
但是在數量太多的時候,哪怕是一次插入,也會因為瀏覽器渲染不過來導致失去響應,這時候就需要增加一定的時間間隔,可以使用setTimeout,也可以使用一個api
requestAnimationFrame.
requestAnimationFrame()方法是為了動畫專門使用的api,在通常的動畫中會定義一個定時器來幾秒幾秒的發生變化,但是為了效能和更加方便,它提供了這個可以在1秒鐘執行大約60次(≈16.7ms)回撥的api。
而且會把這一刻所有的dom操作快取起來,在一次迴流重繪中完成操作,它的每次呼叫並不是指定時間的,而是跟緊瀏覽器的重新整理頻率,所以可以做到:在瀏覽器的重新整理頻率時進行迴流,保證效能效率。
當頁面不是啟用狀態的情況下,這個函式將會停止回撥,進行暫停來節省cpu操作。啟用時再繼續。
在元素隱藏時不會進行重繪迴流。
它的返回值為一個long的識別符號,和settimeout一樣,可以呼叫cancelAnimationFrame()傳入這個識別符號來取消這個回撥。
使用這個可以在瀏覽器下一次’重新整理’的時候執行指定的回撥,在這裡來插入這多個節點。
const wapper=document.querySelector('#wapper');
let all=100000,num=20,duration=all/num,count=0;
function add(){
let fragment=document.createDocumentFragment();
//建立虛擬dom
for(let i=0;i<num;i++){
let div=document.createElement('div');
div.innerText='我是'+(num*count+i);
fragment.appendChild(div);
}
wapper.appendChild(fragment)
count++;
if(count<duration){
requestAnimationFrame(add);//在瀏覽器
}
}
add();
使用這樣可以大批量插入很多資料 頁面也不會失去響應卡住,可以保證比較好的效能(那麼多東西懶載入不好嗎…)
相關推薦
關於迴流,重繪,以及documentFragment,requestAnimationFrame的應用
首先在網頁裡面的DOM應該是靜態的,每一個節點長什麼樣,裡面寫的什麼,都是靜態的不會改變的,會在第一次載入的時候根據一些資訊進行繪製,之所以會發生改變是因為js腳本里改變了dom結構或者css裡觸發了一些變化,在js修改dom之後,網頁會重新渲染這個網頁,這就觸
窗體背景的繪制(Windows窗體每次都會重繪其窗體背景,所以我們可以通過攔截窗體重繪背景的消息(WM_ERASEBKGND),並自定義方法來實現重繪窗體背景)
height com call 消息響應 int idt http msg mes 核心思想:由於Windows窗體每次都會重繪其窗體背景,所以我們可以通過攔截窗體重繪背景的消息(WM_ERASEBKGND),並自定義方法來實現重繪窗體背景。通過TImage組件也可以實現,
vc++圖像保存,重繪
設備描述表 技術 for循環 art 處理 tar .com 內存 函數 新建mfc應用程序,單文檔 增加繪圖 分別增加命令響應 添加成員變量UINIT 圖形可以運行,如何保存呢?(一個集合類,CPtArt) 用一個類的對象來保存一個圖形的三個要素 所以插
元檔案的儲存,儲存圖形,重繪圖形
1, CMateFileDC 可以用來多次開啟自己的畫布,這個元檔案包含許多介面的命令 當繪製好之後可以用來播放元檔案 首先,建立一個CMateFileDC的元檔案物件 然後呼叫Create原函式,建立一個windows檔案裝置上下文,將CMateFileDC物件關聯起來 下一步,給CMateFil
GridView 自帶的全選表頭顯示文字,重繪表頭和表頭繫結控制元件
雖然我比較喜歡GridView自帶的全選功能頭部是checkbox,不過還是有些人比較想要用文字,作為版主,分享一下經驗吧。Dev13.x開始就有GridView的全選功能,目前也越來越完善了,13.x的版本是有問題的,當初我就放棄用自帶的功能。GridView 如果設定全
display和visibility的區別以及迴流和重繪
display:none會脫離文件流,不佔據頁面空間; visibility:hidden,只是隱藏內容,並沒有脫離文件流,會佔據頁面的空間。 講述迴流以及重繪之前需要先了解頁面在文件載入完成之後到完全顯示中間的過程: 1.根據文件生成DOM樹(包括display:none的節點) 2.在D
Python資料預處理之---統計學的t檢驗,卡方檢驗以及均值,中位數等
Python資料預處理過程:利用統計學對資料進行檢驗,對連續屬性檢驗正態分佈,針對正態分佈屬性繼續使用t檢驗檢驗方差齊次性,針對非正態分佈使用Mann-Whitney檢驗。針對分類變數進行卡方檢驗(涉及三種卡方的檢驗:Pearson卡方,校準卡方,精準卡方)等。
return,抽象類與介面,物件序列化機制,this和super,識別符號,break和continue以及return,final,finally和finalize
(2)介面中定義的成員變數預設為public static final,只能夠有靜態的不能被修改的資料成員,而且,必須給其賦初值,其所有的成員變數只能被public,abstract這兩個關鍵字修飾。抽象類可以有自己的成員變數,還可以有非抽象的成員方法,抽象類的成員變數預設為de
抽紙牌,任意張牌,1拿一張到牌底,2拿一張放到桌面,重復1,2操作,直到手中沒牌,最後桌子上的牌是從1到n有序,求出牌排放順序。
size i++ mine fir ray port ++ tps 開始 抽紙牌,任意張牌,1拿一張到牌底,2拿一張放到桌面,重復1,2操作,直到手中沒牌,最後桌子上的牌是從1到n有序,求出牌排放順序。 很久以前的代碼,電腦清理,留存 package linkedlist;
關於迴流與重繪優化的探索
前言 杭州下雪了,冷到不行,在家躺在床上玩手機,開啟微信進入前端交流群裡日常吹水,看到大佬在群裡發了一篇文章你應該要知道的重繪與重排,文章裡有一段騷操作,就是為了減少重繪與重排,合併樣式操作,這個騷操作成功的引起了我的注意,然後開啟了我的探索。 原文地址 正文 前言中描述的合併樣式的騷操作是如下:
你真的瞭解迴流和重繪嗎
迴流和重繪可以說是每一個web開發者都經常聽到的兩個詞語,我也不例外,可是一直不是很清楚這兩步具體做了什麼事情。最近由於部門內部要做分享,所以對其進行了一些研究,看了一些部落格和書籍,整理了一些內容並且結合自己的體會,寫了這篇文章,希望可以幫助到大家。 瀏覽器的渲染過程 本文先從瀏覽器的渲染過程來從頭到尾
你真的瞭解迴流和重繪嗎?
作者:我不是陳紀庚https://segmentfault.com/a/1190000017329980 迴流和重繪可以說是每一個web開發者都經常聽到的兩個詞語,我也不例外,可是我之前一直不是很清楚這兩步具體做了什麼事情。最近由於部門內部要做分享,所以對其進行了一些研究,看了一些部落格和書籍,整理了一些內
前端效能優化第二篇-迴流和重繪
前端效能優化第二篇-迴流和重繪 先給自己持續更新的專欄打個廣告,歡迎大家讀一讀專欄中的其他文章,戳一戳->前端效能優化 瀏覽器渲染過程 先請今天的主角“迴流”和“重繪”在後臺等一下,我們先來看看瀏覽器渲染頁面的過程,不要跳過這個重要的部分啊~ 當瀏覽器
迴流和重繪
不同的瀏覽器對html和css在瀏覽器上呈現的處理流程可能會有略微的不同,但是基本都是類似的。 瀏覽器把獲取到的HTML程式碼解析成一個dom樹,html中的每個tag都是dom樹種的一個節點,根節點就是我們常說的document物件。dom樹包含了所有的html標籤以及display隱藏的,以及使
瀏覽器渲染流程和重繪,迴流
1、渲染大致流程 渲染引擎首先通過網路獲得所請求文件的內容,渲染引擎在取得內容之後的基本流程: ①解析html以構建dom樹 ②構建render樹 (render tree一般翻譯為渲染樹) ③佈局render樹  
從瀏覽器渲染原理,淺談迴流重繪與效能優化
目錄 前言 瀏覽器的渲染引擎 渲染流程 渲染樹與渲染物件 迴流 全域性佈局和增量佈局 "迴流"還是"重排"?
自行實現透明的控件如Panel GroupBox(使用不需要重繪父控件的效果,一切都因為窗口有了WS_EX_TRANSPARENT屬性)
AR highlight ner alignment 重繪 == 答案 nsh none CSDN的Blog開通了。我想這裏的Blog作為今後自己回答別人問題的時候,收藏答案的地方很不錯呢。 因為社區的貼子早晚都會沈下去,查找起來很不方便,甚至再也找不到呢。 Q: ht
重繪ListCtrl中增加子控制元件Edit是,在父控制元件失去焦點時,子控制元件不進行隱藏
問題:現在有一個listctrl控制元件,需要在某一列上新增一個子控制元件edit。當點選子控制元件(edit)時,子控制元件顯示出來,父控制元件(ListCtrl)已經失去焦點了。此時,要是滑鼠點選的位置不在該控制元件內,edit處於顯示狀態,父控制元件(ListCtrl)是失去焦點狀態。
演算法--全排列,去重全排列以及非遞迴實現
問題1: 給定字串1234無重複字元,求其所有排列 遞迴方式求解: def swap(num, i, j): tmp = num[i] num[i] = num[j] num[j] = tmp #num無重複數字 def fullSort(num, index)