리플로우(reflow)와 리페인트(repaint)? 리플로우와 리페인트를 줄이는 방법은 무엇입니까?
document.write는 전체 페이지를 리플로우합니다.
innerHTML은 페이지의 일부를 다시 그릴 수 있습니다.
1. DOM 트리 구축(파싱): 렌더링 엔진이 HTML 문서, 먼저 태그를 DOM 트리(js에서 생성된 태그 포함)의 DOM 노드로 변환하여 콘텐츠 트리(콘텐츠 트리/DOM 트리)를 생성합니다.
2. 렌더링 트리를 구축합니다(구성). ): 해당 CSS 스타일 파일 정보(js 및 외부 CSS 파일에서 생성된 스타일 포함)와 HTML에 표시되는 이러한 파일 정보 및 지침(예: )을 구문 분석하고 렌더링 트리(렌더링 트리/ 프레임 트리);
3. 레이아웃 렌더링 트리(리플로우/레이아웃): 루트 노드에서 재귀적으로 호출되며, 각 요소의 크기, 위치 등을 계산하고, 각 노드의 정확한 좌표를 제공합니다. 화면에 나타나야 합니다.
4. 렌더링 트리 그리기(페인트/다시 그리기): 렌더링 트리를 탐색하고 UI 백엔드 레이어를 사용하여 각 노드를 그립니다.
다시 그리기 또는 다시 그리기: 색상, 글꼴 크기 등과 같은 상자의 위치, 크기 및 기타 속성이 결정되면 브라우저는 해당 특성에 따라 이러한 기본 색상을 그립니다. 페이지의 콘텐츠. 다시 그리기는 요소 모양의 변경으로 인해 발생하는 브라우저 동작을 의미합니다. 브라우저는 요소의 새 속성을 기반으로 다시 그려 요소에 새로운 모양을 부여합니다.
다시 그리기를 트리거하는 조건: 요소의 모양 속성 변경. 예: 색상, 배경색 등
리플로우(reconstruction/reflow/reflow): 요소의 크기, 레이아웃, 숨기기 등의 변경으로 인해 렌더링 트리의 일부(또는 전체)를 다시 작성해야 하는 경우 이를 리플로우라고 합니다. ( 리플로우). 모든 페이지는 페이지가 처음 로드될 때 적어도 한 번은 리플로우되어야 합니다.
다시 그리기와 리플로우 간의 관계: 리플로우 중에 브라우저는 렌더링 트리의 영향을 받은 부분을 무효화하고 리플로우를 완료한 후 렌더링 트리의 이 부분을 재구성합니다. 영향을 받은 부분은 다음과 같습니다. 화면으로 이동하는 과정을 다시 그리기라고 합니다.
리플로우로 인해 반드시 다시 그리기가 발생하지만 다시 그리기로 인해 반드시 리플로우가 발생하는 것은 아닙니다.
리플로우 트리거 조건: 페이지 레이아웃 및 기하학적 속성이 변경되면 다음과 같은 리플로우가 트리거됩니다.
1. 페이지 렌더링 초기화(피할 수 없음)
2. 표시되는 DOM 요소를 추가하거나 삭제합니다.
3. 요소의 위치를 변경하거나 애니메이션을 사용합니다.
4. 요소의 크기(크기, 여백, 테두리)를 변경합니다. ;
5. 브라우저 창 크기 변경(크기 조정 이벤트 발생 시)
6. 텍스트 변경이나 이미지 크기 변경으로 인한 계산 등 채우기 내용 변경 너비 및 높이 값 변경;
7. 특정 요소 속성 읽기: (offsetLeft/Top/Height/Width, clientTop/Left/Width/Height, scrollTop/Left/Width/Height, width/height, getCompulatedStyle(), currentStyle(IE))
다시 그리기 발생:
다시 그리기는 요소의 표시되는 모양이 변경될 때 발생하지만 레이아웃에는 영향을 주지 않습니다. 예를 들어 DOM 요소의 글꼴 색상만 수정합니다(레이아웃을 조정할 필요가 없기 때문에 Repaint만 수정)
다시 그리고 재배열하는 데 드는 비용: 시간이 많이 걸리고 브라우저 속도가 느려집니다.
1. 브라우저 자체 최적화: 브라우저는 대기열을 유지하고 리플로우 및 다시 그리기를 유발하는 모든 작업을 이 대기열에 넣은 다음 대기열의 작업이 특정 수에 도달하거나 특정 수에 도달할 때까지 기다립니다. 시간 간격에 따라 브라우저는 대기열을 비우고 일괄 처리를 수행합니다.
이렇게 하면 여러 리플로우 및 다시 그리기가 하나의 리플로우 및 다시 그리기로 전환됩니다.
2. 최적화에 주의를 기울여야 합니다. 다시 그리기 및 재배열을 줄이려면 렌더링 트리에서 작업을 줄여야 합니다. 그런 다음 여러 DOM 및 스타일 수정을 병합할 수 있습니다. 그리고 스타일 스타일에 대한 요청을 줄이세요.
(1) 요소의 클래스 이름을 직접 변경합니다.
(2) display: none; 먼저 요소를 표시: 없음으로 설정한 다음 페이지 레이아웃 및 기타 작업을 수행합니다. 설정이 완료되면 표시용 요소를 설정합니다. 이 경우 다시 그리기 및 재정렬만 실행됩니다.
(3) 필요한 경우 브라우저의 플러시 대기열 속성에 자주 액세스하지 마십시오. 액세스하면 캐시를 사용할 수 있습니다. 액세스된 값을 저장하면 후속 사용으로 인해 리플로우가 발생하지 않습니다.
//예를 들어 myElement 요소는 한 번에 한 픽셀씩 대각선으로 이동합니다. 500*500픽셀로 끝납니다. 타임아웃 루프 본문에서 이 작업을 수행할 수 있습니다.
//분명히 이 방법은 비효율적입니다. 이동할 때마다 오프셋을 쿼리해야 하므로 브라우저가 렌더링 대기열을 새로 고쳐야 하므로 최적화에 도움이 되지 않습니다. . 좋은 방법은 시작 위치의 값을 한 번 가져온 다음 이를 변수에 할당하는 것입니다. 다음과 같습니다.
(4) cloneNode(true 또는 false) 및 replacementChild 기술을 사용하여 리플로우를 트리거하고 다시 그립니다.
(5) 여러 번 재정렬해야 하는 요소의 경우 위치를 지정합니다. 속성 절대 또는 고정으로 설정하면 해당 요소는 문서 흐름에서 벗어나며 해당 변경 사항은 다른 요소에 영향을 주지 않습니다.
(6) 여러 DOM 노드를 생성해야 하는 경우 DocumentFragment를 사용하여 생성할 수 있습니다. 그것들을 한꺼번에 문서에 추가하세요.
(7) 테이블 레이아웃을 사용하지 마세요.
페이지가 다시 그려지거나 리플로우되는지 여부에 관계없이 성능에 영향을 미칩니다(가장 끔찍한 것은 리플로우이며 가능한 한 피해야 합니다)
DOM: 구조를 설명합니다. 페이지
렌더링: 페이지에서 DOM 노드(노드)가 렌더링되는 방법을 설명합니다.
DOM 요소의 속성(예: 색상)이 변경되면 브라우저에서 렌더링을 알립니다. 해당 요소를 다시 렌더링하는 과정을 다시 그리기라고 합니다.
변경 사항에 요소 레이아웃(예: 너비)이 포함된 경우 브라우저는 원래 속성을 삭제하고 결과를 다시 계산하여 렌더링하여 페이지 요소를 다시 그립니다. 이 프로세스를 리플로우라고 합니다.
이 두 프로세스는 브라우저 성능을 많이 소모하는데, 이는 IE 시리즈와 Chrome의 페이지 렌더링 속도 차이를 보면 렌더링 엔진이 해당 값을 계산하여 반드시 효율적이지는 않지만 각각 렌더링한다는 점을 알 수 있습니다. 렌더링 엔진이 요소를 조작할 때 Repaints나 Reflow가 발생하므로 DOM 상호 작용을 작성할 때 주의하지 않으면 페이지 성능이 저하될 수 있습니다.
페이지 렌더링 프로세스는 다음과 같습니다.
원문:
/sinat_37328421/article/details/54575638
/sophia_little/article/details/79613990
/qq_34255080/article/details /86235234