Skip to content

Latest commit

 

History

History
131 lines (89 loc) · 8.28 KB

what-forces-layout-reflow.md

File metadata and controls

131 lines (89 loc) · 8.28 KB

reflow를 일으키는 것들

리플로우를 작동시키는 자바스크립트 프로퍼티와 메서드를 소개합니다. 리플로우는 브라우저가 동기적으로 스타일과 레이아웃을 계산하게 합니다. 레이아웃 쓰레싱이라고도 하며, 흔한 성능 병목입니다.

일반적으로, 레이아웃을 동기적으로 측정하는 API에서 리플로우(또는 레이아웃)이 일어납니다. 자세한 설명과 예시는 아래에 나와있습니다.

Element API들

박스 크기 재기
  • elem.offsetLeft, elem.offsetTop, elem.offsetWidth, elem.offsetHeight, elem.offsetParent
  • elem.clientLeft, elem.clientTop, elem.clientWidth, elem.clientHeight
  • elem.getClientRects(), elem.getBoundingClientRect()
Scroll 관련
  • elem.scrollBy(), elem.scrollTo()
  • elem.scrollIntoView(), elem.scrollIntoViewIfNeeded()
  • elem.scrollWidth, elem.scrollHeight
  • elem.scrollLeft, elem.scrollTop과 이를 설정할 때
focus 설정
이외에..
  • elem.computedRole, elem.computedName
  • elem.innerText (출처)

window 차원 가져오기

  • window.scrollX, window.scrollY
  • window.innerHeight, window.innerWidth
  • window.visualViewport.height / width / offsetTop / offsetLeft (출처)

document

  • document.scrollingElement 스타일링만 발생시킵니다.
  • document.elementFromPoint

Forms: selection과 focus 설정하기

  • inputElem.focus()
  • inputElem.select(), textareaElem.select()

Mouse events: offset 데이터 읽기

  • mouseEvt.layerX, mouseEvt.layerY, mouseEvt.offsetX, mouseEvt.offsetY (출처)

getComputedStyle() 호출

window.getComputedStyle()은 스타일 재계산을 일으킵니다.

window.getComputedStyle()은 때로 리플로우를 일으킵니다..

`gCS()`가 리플로우를 일으키는 조건

window.getComputedStyle()는 다음 3개 중 하나의 조건이 만족하면 리플로우가 일어납니다:

  1. 요소가 그림자 트리에 있을 때
  2. 뷰 포트 관련 미디어 쿼리가 있을 때. 특히, 다음 중 하나일 때: (출처
    • min-width, min-height, max-width, max-height, width, height
    • aspect-ratio, min-aspect-ratio, max-aspect-ratio
    • device-pixel-ratio, resolution, orientation , min-device-pixel-ratio, max-device-pixel-ratio
  3. 요청한 프로퍼티가 다음 중 하나일 때: (source)
    • height, width
    • top, right, bottom, left
    • 마진이 고정인 경우 margin [-top, -right, -bottom, -left, 또는 축약표현]
    • 패딩이 고정인 경우 padding [-top, -right, -bottom, -left, 또는 축약표현]
    • transform, transform-origin, perspective-origin
    • translate, rotate, scale
    • grid, grid-template, grid-template-columns, grid-template-rows
    • perspective-origin
    • 옛날에 해당됐지만 지금은 아닌 것들: (18년 2월 이후): motion-path, motion-offset, motion-rotation, x, y, rx, ry

Range 차원 가져오기

  • range.getClientRects(), range.getBoundingClientRect()

SVG

많은 프로퍼티와 메서드가 레이아웃을 일으키지만 다 안 나와 있습니다:

  • SVGLocatable: computeCTM(), getBBox()
  • SVGTextContent: getCharNumAtPosition(), getComputedTextLength(), getEndPositionOfChar(), getExtentOfChar(), getNumberOfChars(), getRotationOfChar(), getStartPositionOfChar(), getSubStringLength(), selectSubString()
  • SVGUse: instanceRoot

아래의 크로미엄 소스 트리 링크에서 찾아보세요.

contenteditable

  • 이미지를 클립보드에 복사하는 것을 포함해서 많은 것들이 리플로우를 일으킵니다. (출처)

* 색인

  • 리플로우는 도큐먼트가 변경되고 스타일이나 레이아웃에서 뭔가가 잘못됐을 때만 비용이 발생합니다. DOM 변경(클래스 변경, 노드 추가/삭제, :focus 같은 의사 클래스 추가 등)으로 인한 비용 발생이 일반적입니다.
  • 리플로우를 방지하는 방법을 아래에 간단하게 소개합니다. 자세한 내용은 리플로우 더 알아보기를 참조하세요.
    1. for 내에서 리플로우와 DOM을 변경하지 마세요.
    2. 개발자 도구의 성능 패널에서 리플로우가 발생하는 곳을 찾아보세요. 생각보다 본인의 코드와 라이브러리에서 리플로우가 자주 발생해서 놀랄 수도 있습니다.
    3. DOM 읽고 쓰기를 한 번에 하세요.(FastDOM이나 가상 DOM을 사용). 프레임의 첫 부분에서 레이아웃을 측정하세요.(requesetAnimationFrame이나 스크롤 처리 함수의 시작 부분 등). 이 첫 부분이 최근 리폴로우가 끝났을 때와 숫자들이 같습니다.

Guardian으로 타임라인 추적한 사진. Outbrain이 계속 리플로우를 일으키는데 아마 루프 안이라서 그런 것 같습니다.

리플로우 더 알아보기


2020년 4월에 약간 업데이트 됐습니다.