source

"현대" 브라우저는 한 번에 몇 개의 HTML 요소를 처리할 수 있습니까?

goodcode 2023. 2. 14. 23:05
반응형

"현대" 브라우저는 한 번에 몇 개의 HTML 요소를 처리할 수 있습니까?

이 정의는 시간이 지남에 따라 변경될 수 있기 때문에 "현대적"입니다(특히 데스크톱 브라우저).

기계 구성/메모리에 따라 다를 수 있기 때문에 "핸들"은 일반적인 사용 사례를 의미합니다.


대규모 데이터셋과 관련하여 해결하려는 특정 문제에 대해 이 질문이 떠올랐습니다.

기본적으로 특정 데이터셋이 변경될 때마다 전체 데이터셋이 반환되고 이 데이터를 브라우저에서 렌더링해야 합니다.

예를 들어 웹 소켓을 통해 데이터셋이 변경되었음을 알려주는 푸시 이벤트가 발생하면 기존 DOM 요소를 가져와 복제하고 클래스 이름이나 다른 요소 식별자를 사용하여 이 세트의 데이터로 요소를 채운 다음 다시 DOM에 추가하여 이 데이터셋을 HTML로 렌더링해야 합니다.

이 데이터 집합의 모든 개체(JSON)에는 1000개 이상의 하위 개체가 있을 수 있고 10,000개 이상의 상위 개체가 있을 수 있으므로 반환된 데이터 집합이 1,000,000=> 10,000,000개 이상의 데이터 지점까지 상승하는 경우가 있을 수 있습니다.

이제 재미있는 건 이걸 렌더링해야 할 때야각 데이터 포인트에 대해 데이터를 렌더링 및 스타일링하는 데 사용되는 태그가 3개 또는 4개 있을 수 있으며, 이러한 태그 중 하나에 대한 이벤트 청취자가 있을 수 있습니다(위임을 사용하여 상황을 밝게 하는 경우 부모 컨테이너에 있을 수 있습니다).

요약하자면, 렌더링해야 하는 많은 정보가 있을 수 있으며, 저는 이 시나리오에 대처하기 위한 최선의 방법을 찾고 있습니다.

이상적인 것은 세트 전체를 다시 렌더링하는 것이 아니라 변경이 있는 단일 데이터 포인트의 변경만 렌더링하는 것입니다만, 백엔드의 설계 방법에 따라서는 이 옵션이 되지 않을 수 있습니다.

여기서의 주된 관심사는 브라우저/DOM의 한계를 이해하고 프런트엔드의 렌즈를 통해 이 문제를 보는 것입니다.백엔드에는 몇 가지 변경이 필요합니다(데이터 설계, 캐싱, 페이지 번호 부여). 그러나 여기서는 이 점에 초점을 맞추지 않습니다.

HTML/DOM의 일반적인 사용 사례는 아니지만 제한이 있다는 것은 알고 있습니다만, 정확히 어떤 것입니까?아직 3000~4000개 정도의 요소가 남아 있습니까?


이와 관련된 가지 서브질문이 있어 적극적으로 알아보고 있지만 스택오버플로우 커뮤니티의 다른 사람들과 의견을 나누고 이 문제에 대한 정보를 모아보는 것이 좋을 것 같습니다.

최신 브라우저가 저속/무응답 상태가 되기 전에 처리할 수 있는 DOM 요소의 '합리적인' 양은 어느 정도입니까?

브라우저로 처리할 수 있는 DOM 요소의 수를 벤치마크하려면 어떻게 해야 합니까?

렌더링해야 하는 대규모 데이터셋을 처리하기 위한 전략에는 어떤 것이 있습니까?

콧수염이나 핸들바와 같은 템플릿 프레임워크는 jQuery 또는 정규 표현을 사용하는 것보다 데이터/json에서 html을 렌더링하는 데 성능이 더 우수합니까?

정답은 100만 또는 수백만입니다.SO에 대한 유사한 질문의 답변을 복사/붙여넣습니다.

솔직히 말하면, 이 질문에 대한 절대적인 답이 필요하다면 디자인을 재고해 보는 것이 좋을지도 모릅니다.

어플리케이션 고유의 많은 요소에 따라 다르므로 여기에 제시된 답변은 정확하지 않습니다.예를 들어 CSS 사용률이 높은 경우와 적은 경우의 CSS 사용률, div 크기, div당 필요한 실제 그래픽 렌더링 양, 타깃 브라우저/플랫폼, DOM 이벤트 리스너 수 등입니다.

그렇다고 해서 그렇게 해야 하는 것은 아닙니다. :-"

돔이 느려지고 불안정해지기 전에 몇 개의 디바를 가질있나요?

이것은 정말 대답할 수 없는 질문이다. 너무 많은 요소들이 너무 많은 각도에서 있기 때문이다.단, 1페이지 로드에서는 1ms의 javascript set interval을 사용하여 ID가 1씩 증가하는 페이지에 새로운 div를 계속 추가했습니다.제 크롬 브라우저는 20,000이 넘었고 600MB 램을 사용하고 있습니다.

이것은 통계적으로 정통한 답변만이 정확하고 포괄적일 수 있는 질문이다.

왜죠

적절한 방정식은 다음과 같습니다.여기서 N은 노드 수, 바이트는N DOM에서 그것들을 나타내기 위해 필요한 총 바이트 수, 노드 인덱스 범위는 다음과 같습니다.n ∈ [0, N), 최소 애트리뷰트 으로 내부 가 없는 노드에 Overhead는 절대 최소 속성 설정으로 내부가 없는 노드에 사용되는 메모리 양입니다.HTML "bytes Content" "Bytes Content" "Bytes Content" "Bytes Content" "Bytes Content" "Bytes Content" "Bytes Content" "Bytes Content" "Bytes Content" "Bytes Content"

bytesN = " N(bytesn Content + bytesOverheadn)

질문에서 요구하는 값은 최악의 경우 핸드헬드 디바이스, 운영체제시스템, 브라우저 및 운영상태에서 N의 최대값입니다.각 치환에 대한 N의 해결은 간단하지 않습니다.위의 방정식은 세 가지 종속성을 나타내며, 각각이 답을 크게 바꿀 수 있습니다.

의존 관계

  1. 노드의 평균 크기는 UTF-8 텍스트, Atribute 이름과 값, 캐시된 정보 등 콘텐츠를 유지하기 위해 사용되는 각 평균 바이트 수에 따라 달라집니다.
  2. DOM 오브젝트의 평균 오버헤드는 각 문서의 DOM 표현을 관리하는 HTTP 사용자 에이전트에 따라 달라집니다.W3C의 Document Object Model FAQ에는 "모든 DOM 구현은 상호 운용이 가능해야 하지만 코드 크기, 메모리 요구량 및 개개의 운용 퍼포먼스에 따라 크게 다를 수 있습니다."라고 기재되어 있습니다.
  3. DOM 표현에 사용할 수 있는 메모리는 기본적으로 사용되는 브라우저(브라우저 핸드헬드 디바이스 벤더 또는 사용자에 따라 다를 수 있음), 기본 브라우저의 사용자 덮어쓰기, 운영체제시스템 버전, 핸드헬드 디바이스의 메모리 용량, 일반적인 백그라운드 작업 및 기타 메모리 소비량에 따라 달라집니다.

엄격한 솔루션

핸드헬드 디바이스에서 사용되는 공통 http 사용자 에이전트 각각에 대해 (1)과 (2)를 결정하기 위한 테스트를 실행할 수 있습니다.특정 사이트의 사용자 에이전트 배포는 HTTP_USER_AGENT가 기본적으로 존재하지 않는 경우 HTTP_AGENT를 배치하도록 웹 서버의 로깅 메커니즘을 설정한 후 로그에서 해당 필드를 제외한 모든 필드를 제거하고 각 값의 인스턴스를 카운트함으로써 얻을 수 있습니다.

문자당 바이트 수는 Attribute 값과 UTF-8 내부 텍스트(또는 부호화)의 양쪽 모두에 대해 테스트해야 합니다(1)를 계산하는 계수의 명확한 쌍을 얻을 수 있습니다.

사용 가능한 메모리는 다양한 공통 조건 하에서 테스트해야 하며, 이는 그 자체로 중요한 연구 프로젝트입니다.

실제 최악의 경우를 처리하려면 선택한N의 특정 값이 0이어야 합니다.따라서 콘텐츠, 노드 구조 및 실행 시간 조건의 일반적인 경우에서 일정 비율을 선택합니다.예를 들어, 어떤 형태의 현장 랜덤화(정상 환경 조건 내) 연구를 사용하여 사례의 표본을 추출하여 해당 사례의 95%를 충족하는 N을 찾을 수 있습니다.

아마도 일련의 사례를 위의 방법으로 테스트하고 결과를 표에 정리할 수 있을 것이다.그것은 당신의 질문에 대한 직접적인 답변이 될 것입니다.

적절한 결과를 얻으려면 수학, 특히 통계에 대한 지식을 갖춘 고급 모바일 소프트웨어 엔지니어가 5주 동안 풀타임으로 작업해야 합니다.

보다 실용적인 평가

최악의 경우를 짐작할 수 있다.며칠간의 조사와 몇 가지 개념 증명 앱으로 이 제안을 개선할 수 있을 것이다.그럴 시간이 없다면, 여기 좋은 첫 번째 추측이 있다.

통상적인 동작 조건에서는 상기의 목적을 위해4 GB 중 3 GB가 사용되기 때문에, DOM 에 1 GB 를 허가하는 휴대 전화에 대해 검토해 주세요.대략적인 수치를 얻기 위해 노드의 평균 메모리 소비량은 다음과 같다고 가정할 수 있다.

  • 노드당 40자의 내부 텍스트에 대해 문자당 2바이트
  • 10자씩 4개의 속성 값에 대해 문자당 2바이트
  • 4개의 Atribute name(각 4글자)에 대하여
  • 효율이 낮은 경우 C/C++ 노드 오버헤드의 경우 160바이트

이 경우worst_case N(최악의 경우 최대 노드)

= 1,024 X 1,024 X 1,024
  / (2 X 40  +  2 X 4 X 10  +  1 X 4 X 4  +  160)

= 3,195,660 . 190,476.

그러나 나는 피할 수 있다면 300만 개의 DOM 노드를 가진 브라우저에 문서를 작성하지 않을 것이다.아래의 보다 일반적인 관행을 채용하는 것을 검토해 주십시오.

일반적인 프랙티스

가장 좋은 해결책은worst_case N보다 훨씬 낮은 수준을 유지하고 표준 HTTP 설계 기술을 사용하여 노드의 총 수를 가능한 한 줄이는 것입니다.

  • 특정 페이지에 표시되는 크기와 복잡성을 줄여 시각적 및 개념적 선명도를 향상시킵니다.
  • 서버로부터 최소한의 데이터를 요구해, 윈도우 설정 기술을 사용해 아직 표시되지 않는 컨텐츠를 지연시키거나, 응답 시간과 메모리 소비량의 밸런스를 적절히 조정합니다.
  • 위의 미니멀리즘을 지원하려면 비동기 콜을 사용합니다.

구글의 돔 사이즈 추천:

돔사이즈 권장사항


"

최적의 DOM 트리:

  • 총 노드가 1500개 미만입니다.
  • 최대 32노드의 깊이입니다.
  • 60개가 넘는 하위 노드를 가진 상위 노드가 없습니다.

일반적으로 필요한 경우에만 DOM 노드를 생성하고 더 이상 필요하지 않은 경우에는 폐기하는 방법을 찾습니다.

서버가 큰 DOM 트리를 출하하고 있는 경우는, 페이지를 로드해, 표시되는 노드를 수동으로 기록해 주세요.로드된 문서에서 표시되지 않은 노드를 제거하고 스크롤 또는 단추 클릭과 같은 사용자 제스처 후에만 노드를 작성할 수 있습니다.

런타임에 DOM 노드를 작성하는 경우 하위 트리 수정 DOM 변경 중단점을 통해 노드가 생성되는 시기를 정확하게 파악할 수 있습니다.

큰 DOM 트리를 피할 수 없는 경우 렌더링 성능을 향상시키는 또 다른 방법은 CSS 셀렉터를 단순화하는 것입니다.스타일 계산의 범위 및 복잡도 감소를 참조하십시오.

"

DOM 요소가 너무 많아지는 원인은 여러 가지가 있습니다.다음은 많은 요소를 렌더링하고 DOM의 한계를 실감하기 위해 사용한 React + d3 컴포넌트입니다.

export const App = React.memo((props) => {
  const gridRef = React.useRef(null);
  React.useEffect(() => {
    if (gridRef.current) {
      const table = select(gridRef.current);
      table
        .selectAll("div")
        .data([...new Array(10000)])
        .enter()
        .append("div")
        .text(() => "testing");
    }
    if (props.onElementRendered) {
      props.onElementRendered();
    }
  }, []);
  return <div ref={gridRef} />;
});

Chrome을 실행하는 16GB의 메모리를 탑재한 2021 Macbook Pro에서는 약 30,000개의 요소부터 시작하는 심각한 지연이 발생하고 있습니다(페인트 단계).

데이터 포인트를 하나 더 추가하려고요.2064K 바이트라고 주장하는 GNU Bison 매뉴얼을 한 장 로드했습니다.콘솔에 다음과 같이 입력했습니다.document.querySelectorAll('*')답은 22183노드로 구글이 주장하는 '최적의 크기'를 다소 웃돌았다.

페이지 로드 지연은 검출되지 않았습니다(50Mb 이더넷 연결).로드 후 내부 링크 클릭, 스크롤 등의 지연이 전혀 검출되지 않았습니다.

이것은, 비교적 큰 처리 능력을 가지는 데스크탑 머신에 탑재되어 있습니다.갤럭시 노트4에서도 같은 시도를 했다(고대 와이파이 접속, 50Mb가 아님).이번에는 (놀랄 일도 아니다)로드될 때까지 몇 초(<5)를 기다려야 했습니다.그 후 링크를 클릭하거나 스크롤을 하는 것은 제 눈에 보이는 한 순간이었습니다.

React의 3만 개의 노드가 문제를 일으킬 수도 있고, 프레임워크가 필요 없는 단순한 HTML 노드 수보다 훨씬 더 많은 노드를 문제없이 보유할 수도 있다는 것은 의심의 여지가 없습니다.1500개 이상의 노드를 고려해야 한다는 생각은 말도 안 되지만 YMMV는 확실합니다.

언급URL : https://stackoverflow.com/questions/21611822/how-many-html-elements-can-modern-browsers-handle-at-once

반응형