웹 프런트 엔드 성능 최적화 _ 레이어 및 재배치 다시 그리기

CSS 레이어

  브라우저가 페이지를 렌더링 할 때 페이지를 여러 계층으로 나누고 계층은 크고 작으며 각 계층에는 하나 이상의 노드가 있습니다.

DOM을 렌더링 할 때 브라우저가 수행하는 실제 작업은 다음과 같습니다 :
  1. DOM을 획득 한 후 여러 레이어로 나눕니다
  2. 각 레이어의 노드에 대한 스타일 결과 계산 (스타일 스타일 재 계산 다시 계산)
  3. 그래픽 생성 각 노드에 대한 위치 및 위치 (레이아웃 레이아웃, 재 배열, 리플 로우)
  4. 레이어 비트 맵에 각 노드를 페인트하고 채 웁니다 (Paint-redraw)
  5. 레이어를 GPU에 텍스처로 업로드
  6. 여러 조합 레이어를 페이지에 최종 화면 이미지 생성 (Composite Layers-layer 재구성)

레이어 생성 조건

다음 조건 중 하나라도 충족 되면 Chrome 브라우저 가 레이어를 생성합니다.
  1. 3D 변환이있는 CSS 속성이 있습니다
  . 2. 가속 비디오 디코딩 노드를 사용합니다.
  3. 노드
  4. CSS3 애니메이션 노드
  5. CSS 가속 속성이있는 요소 (변경 될 예정)

레이어 모델

레이어 모델

다시 칠하기

  다시 그리기는 윤곽선 및 배경색과 같은 속성 변경과 같이 요소의 모양이 변경 될 때 트리거되는 브라우저 동작입니다. 브라우저는 요소의 새 속성에 따라 다시 그려 요소에 새로운 모양을 부여합니다. 다시 그리는 것은 다시 레이아웃을 가져 오지 않으므로 반드시 재배치가 수반되는 것은 아닙니다.
  다시 그리기와 재정렬은 모두 레이어를 기준으로하며 레이어의 요소를 다시 그려야하는 경우 전체 레이어를 다시 그려야합니다.
  따라서 성능을 향상 시키려면 이러한 변경 사항 에 고유 한 레이어가 있어야
  하지만 다행스럽게도 대부분의 브라우저는 CSS3 애니메이션 노드에 자체 레이어를 자동으로 생성합니다.

재배치 (리플 로우라고도 함 : 리플 로우)

  렌더 객체가 생성되어 렌더 트리에 추가 될 때 위치 및 크기 정보가 포함되지 않습니다. 이러한 값을 계산하는 프로세스를 레이아웃 또는 재 배열이라고합니다.
  "다시 그리기"에는 반드시 "리플 로우"가 필요하지 않습니다. 예를 들어 웹 페이지 요소의 색상을 변경하면 "리플 로우"가 아닌 "다시 그리기"만 트리거됩니다. 레이아웃이 변경되지 않았습니다.
  "리플 로우"는 대부분의 경우 "다시 그리기"로 이어집니다. 예를 들어 웹 페이지 요소의 위치를 ​​변경하면 레이아웃이 변경되기 때문에 "리플 로우"와 "다시 그리기"가 모두 트리거됩니다.

다시 그리기를 트리거하는 속성

* color		         * background               * outline-color
* border-style		 * background-image		    * outline
* border-radius		 * background-position	    * outline-style
* visibility		 * background-repeat		* outline-width
* text-decoration	 * background-size		    * box-shadow

재 배열 (리플 로우)을 트리거하는 속성

* width             * top                * text-align
* height            * bottom             * overflow-y
* padding           * left               * font-weight
* margin            * right              * overflow
* display           * position           * font-family
* border-width      * float              * line-height
* border            * clear              * vertival-align
* min-height        * white-space

리플 로우를 트리거하는 일반적인 작업

  리플 로우 (재 배열) 에 비해 비용이 다시 그리기 (다시 그리기) 비용이 훨씬 더 높은
  리플 로우가 노드 가능성이 자식 노드, 심지어 리플 로우 부모 포인트와 피어 노드가 발생할 것입니다.
  일부 고성능 컴퓨터에서는 그다지 많지 않을 수 있지만 Reflow가 휴대폰에서 발생 하면 이 프로세스는 매우 고통스럽고 전력 소모가 많습니다 .

따라서 다음 작업은 상대적으로 비용이 많이 듭니다.
  DOM 노드를 추가, 삭제 또는 수정하면 Reflow 및 Repaint가 발생합니다.   CSS 스타일을 수정할 때
  DOM의 위치를 ​​이동할
때.   웹 페이지의 기본 글꼴을 수정할 때
  창 크기를 조정할 때 (모바일 터미널의 확대 / 축소가 레이아웃 뷰포트에 영향을주지 않기 때문에 모바일 터미널에는이 문제가 없습니다
.)
  [속성 (너비, 높이 ...)을 얻을 때! ! ! ! !
    참고 : display : none은 리플 로우를 트리거하고 visible : hidden은 위치 변경이 없기 때문에 리 페인트 만 트리거합니다.

최적화 계획 (재 작성 및 재정렬)

우리는 알고 있습니다 : 다음 브라우저 페이지 렌더링 및 세부 링크를 통해 이동 합니다.
  1. 노드 스타일에로드해야하는 결과를 계산합니다 (스타일 재 계산 스타일 재 계산)
  . 2. 각 노드에 대해 그래프와 위치를 생성합니다 (레이아웃 가중치 행 또는 리플 로우)
  3. 각 노드를 레이어로 채우기 (Paint-repaint)
  4. 페이지에서 레이어 결합 (복합 레이어-레이어 재구성)
 성능을 개선해야하는 경우 브라우저를 줄이는 것입니다. 런타임시 수행해야하는 작업은 가능한 한 1234 단계를 줄이는 것 입니다.

[특정 최적화 방식은 다음과 같습니다] :
  1. 요소 위치를 변환 할 때 CSS3 변환을 사용하여 왼쪽 상단 및 기타 작업을 대체하십시오. 변환
    및 불투명도는 레이어 조합에만 영향을 미칩니다
  2. [가시성 대신에 불투명도 사용]
    (1 가시성을 사용하면 리플 로우가 트리거되지 않지만 여전히 다시 그려집니다.
    (2) 불투명도를 직접 사용하여 다시 그리기 및 재 배열을 트리거합니다 (이것이 GPU의 기본 설계입니다!).
    (3) 불투명도는 레이어와 함께 사용되며 다시 그리기 나 재 배열이 실행되지 않음을 의미합니다.
    이유 :
    투명도가 변경되면 GPU는 효과를 얻기 위해 이전에 칠해진 텍스처의 알파 값을 줄이며 전체를 다시 그릴 필요가 없습니다.
    그러나 전제는 수정 된 불투명도 자체가 레이어 여야한다는 것입니다.
  3. [테이블 레이아웃 사용 안함]
    table-cell
  4. [스타일 속성을 변경하는 여러 작업을 하나로 결합] 작업
  DOM 스타일을 하나씩 수정하지 않고 미리 클래스를 정의한 다음 DOM의 className을 수정합니다.
  5. [오프라인 후 DOM 수정 변경 ]
  디스플레이 속성이 none 인 요소는 렌더 트리에 없으므로 숨겨진 요소에 대한 작업으로 인해 다른 요소가 재정렬되지 않습니다.
  요소에 대해 복잡한 작업을 수행하려는 경우 먼저 요소를 숨긴 다음 작업이 완료된 후 표시 할 수 있습니다. 이것은 숨겨지고 표시 될 때만 2 개의 재 배열을 트리거합니다.
  6. 【문서 조각 사용】 ​​------ Vue는 성능 향상을 위해이 방법을 사용합니다.
  7. [특정 DOM 노드의 속성 값을 루프에 변수로 넣지 마십시오]
    브라우저에서 일부 스타일 정보를 요청하면 브라우저는 다음과 같은 큐
      를 비 웁니다 . 1. offsetTop, offsetLeft, offsetWidth, offsetHeight
      2. scrollTop / Left / Width / Height
      3. clientTop / Left / Width / Height
      4. width, height
    위의 속성 중 일부를 요청할 때 가장 정확한 값을 제공하기 위해 브라우저를 새로 고쳐야합니다. 이러한 값에 영향을 미치는 작업이 대기열에있을 수 있습니다. 최근에 발생했거나 변경된 레이아웃 정보와 관련이없는 요소의 레이아웃 및 스타일 정보를 가져
    오더라도 브라우저는 렌더링 대기열을 강제로 새로 고칩니다.
  8. 애니메이션 구현 과정에서 GPU 하드웨어 가속을 활성화합니다. transform : tranlateZ (0)
  9. 애니메이션 요소에 대한 새 레이어를 만들고 애니메이션 요소의 Z- 색인을 늘 립니다
  . 10. 애니메이션을 작성할 다음 API를 사용해보십시오.

다시 그리는 비용

다시 그리기

requestAnimationFrame ---- 애니메이션 프레임 요청

1. window.requestAnimationFrame()
  설명 :이 메서드는 다음 다시 그리기 전에 지정한 함수를 호출하도록 브라우저에 지시합니다
    . 1. 매개 변수 :이 메서드는 콜백 함수를 매개 변수로 사용합니다.이 콜백 함수는 브라우저를 다시 그리기 전에 호출됩니다.
    콜백 함수는 requestAnimationFrame()콜백 함수가 트리거되는 현재 시간 을 식별하는 매개 변수 DOMHighResTimeStamp에 자동으로 전달됩니다.

반환 값 :
  긴 정수, 요청 ID, 콜백 목록에서 유일한 식별자입니다. 0이 아닌 값이며 다른 의미가 없습니다. 이 값을 window.cancelAnimationFrame()전달 하여 콜백 함수를 취소 할 수 있습니다 .

참고 :
  다음 브라우저를 다시 그리기 전에 애니메이션의 다음 프레임을 계속 업데이트하려면 콜백 함수 자체를 다시 호출해야합니다.window.requestAnimationFrame()

2. 메서드 window.cancelAnimationFrame(requestID)
  를 호출하여 이전 window.requestAnimationFrame()에 계획 추가 애니메이션 프레임 요청 을 취소합니다 .
  requestIDwindow.requestAnimationFrame()메소드가 이전 호출 되었을 때 반환되는 값이며 시간 식별자이며 사용법은 타이머의 ID와 유사합니다.

추천

출처blog.csdn.net/qq_43562262/article/details/108936503