웹 위젯:<10kB[WIP]에서 상태 레이아웃을 구축하는 라이브러리

10473 단어 htmlcssjavascript
참고: 본 문서에서 "ES"는 ECMAScript를 가리키며 "JavaScript"라고도 합니다.

데모


생산(동결): https://web-widgets.netlify.app/widget.freeze
개발(CSR): https://web-widgets.netlify.app/widget.render.dev
동결된 레이아웃은 100% 차단되지 않으며 무게는 7kB에 불과합니다.

웹 페이지 로드


웹 페이지를 불러올 때 서버에서 레이아웃의 원본 코드를 검색하고 브라우저가 해석합니다.여기에는 다음이 포함됩니다.

  • HTML 태그를 통한 구조 정보(페이지 내용)

  • CSS 스타일(사물의 외관)을 통해 제공되는 스타일 정보

  • ES 논리적 컴퓨팅 정보(사물의 기능)
  • 일반적인 웹 페이지는 CSS 스타일시트, ES 스크립트, 글꼴 등 네트워크를 통해 외부 자원을 불러옵니다. 보통 몇 가지 다른 요청을 통해 불러옵니다.또한 페이지에 포함된 ES 스크립트를 포함하여 이러한 리소스를 분석하고 실행해야 합니다.
    일반적으로 대부분의 웹 페이지는 성능에 맞추어 최적화되지 않았다.이것은 사용자 체험에 많은 영향을 미친다. 예를 들어 다음과 같다.

  • 웹 페이지가 더 커서 불러오는 시간이 더 길어짐

  • 대부분의 시간이 데드 코드 실행에 소요되기 때문에 필요한 ES 스크립트를 실행하는 속도가 느립니다
  • .

  • 첫 번째 프레임을 그리기 위해 다양한 스크립트와 스타일을 실행할 때 초기 페이지 렌더링 차단
  • 다음은 서버측 렌더링을 게시하는 Little Caesar's production Gatsby app의 Lighthouse 결과입니다.

    무엇이 네트워크 소부품입니까?


    웹 위젯은 이러한 문제점을 개선하기 위한 개념적 검증입니다.네트워크 위젯:
  • ES6 클래스로 작성하여 메타데이터 저장 및 처리 상태
  • 를 통해 구축해야 할 사항 정의
  • 실시간 DOM에 구현하여 개발
  • 평면으로 동결되고 뒤로 호환되는 HTML 표시로 생산에 사용됨(아래의'동결된 레이아웃이 무엇인지'부분 참조)
  • 정적 - 모든 컨텐츠를 미리 컴파일하고 최대 압축을 사용하며 CDN
  • 에서 서비스 제공

    무엇이 동결 배치입니까?


    동결된 레이아웃은 상태 레이아웃으로 브라우저에 전송될 때 자동으로 통합되어 자체 상태 논리를 시작합니다.

  • 크기 및 데드 코드 제거에 최적화
  • 레이아웃에 사용되는 스타일만 포함
  • 작은 위젯이 상태가 있으면 상태 논리에 삽입됩니다
  • .
  • 모든 CSS/ES6 클래스, 변수 등의 명칭이 축소되고 손상됨
  • 모든 불필요한 데이터 제거

  • 그리기 준비 – 즉, 초기 페이지 렌더링(0밀리초의 저지 시간)을 막지 않으며, 브라우저는 첫 번째 그리기를 그리기 위해 불필요한 계산을 할 필요가 없습니다.
  • AsyncStylesheet 작은 위젯은 non-render blocking manner에 글꼴을 삽입하는 데 사용됩니다
  • 모든 삽입식 CSS 스타일과 컴파일된 ES 상태 논리는 비동기적
  • 요컨대 이 개념은 UI를 통해 레이아웃을 순수 ES로 코드화하고 기존 기술을 주로 사용하는 알고리즘을 개발하여 레이아웃을 크기 최적화 상태로 동결시킬 수 있음을 증명한다. 주로 패킷 컴파일러의 최적화와 압축에 의해 있는 CSS 클래스와 내부 구성 요소의 상태 논리에 의존한다.
    프레젠테이션에 있어서 하나의 단추와 하나의 계수기로 구성되어 있으며, 누르면 계수기가 증가합니다. (제목과 평범하지 않은 ScrollIndicator. 동결된 출력 문서의 무게는 약 7kB gzip입니다.

    구문


    위젯 클래스는 다음과 같은 최상위 수준의 속성을 가진 UI 구성 요소 유형을 지정합니다.
  • tag, DOM 노드string를 덮어쓰는 tagName, 네이티브 브라우저 기능 계승용
  • styles, 하나array<string>로 이런 작은 위젯과 관련된 CSS 스타일을 지정하는 데 사용한다.및
  • attributes, 속성object<string, string> 키 값 매핑
  • 작은 위젯은 다음과 같습니다.
  • 구조 함수를 계승하는 정적tag, stylesattributes 필드를 실례 속성으로 한다
  • 개발 모드에서 그들의 클래스 이름을 계승하여 그들의 태그 이름으로 삼는다(즉, class CustomWidget extends Widget {…}는 기본적으로 <customwidget attr="val">와 같은 태그로 삼는다)
  • 생산 모델에서 계승w을 그 표기명(재작성되지 않는 한class Link { static tag = 'a'; }은 정확하게 구축<a> 요소)으로 삼아 최대 군더더기를 제거한다.및
  • 사용setState() {...}소부품상태를 수정하는데 영감은 떨림에서 나온다.
  • 예를 들어, 아래CounterView, 하나StatefulWidget를 참조하십시오. 여기에는 하위 부품이 포함된 작은 부품SpaceEvenly이 있습니다.
    /**
     * A layout containing a number that increments when a button is pressed.
     */
    export class CounterView extends StatefulWidget {
      /** Initializes state when constructor is called. */
      initState() {
        this.state.count = 0;
      }
      /** Builds the widget to render. */
      build() {
        return new SpaceEvenly(
            new ExtraLargeText(this.state.count),
            new SimpleButton('PRESS ME').on(
                'click',
                this.setState(() => this.state.count++),
            ),
        );
      }
    }
    

    구축 및 컴파일

    new CounterView().render() 다음과 같은 DOM 노드를 구축합니다.
    <spaceevenly class="SpaceEvenly Expanded Flex Widget">
        <extralargetext class="ExtraLargeText Widget" style="user-select: none">0</extralargetext>
        <button class="SimpleButton Button Widget">PRESS ME</button>
    </spaceevenly>
    
    상태 논리를 포함하여 HTML 문자열로 동결할 수 있습니다new CounterView().freeze().
    <spaceevenly class="SpaceEvenly Expanded Flex Widget">
        <extralargetext class="ExtraLargeText Widget" style="user-select: none">0</extralargetext>
        <button class="SimpleButton Button Widget">PRESS ME</button>
        <script async="true">(function(){var el=document.currentScript.parentNode;requestAnimationFrame(function(){CounterView.from(el).render();});})();</script>
    </spaceevenly>
    
    운영 중단의 경우 다음과 같이 컴파일됩니다.
    <w class="T F D w"><w class="Y w" style="user-select:none">0</w><button class="xa S w">PRESS ME</button><script async="true">(function(){var el=document.currentScript.parentNode;requestAnimationFrame(function(){Z.a(el).h();});})();</script></w></w>
    
    태그 이름, CSS 클래스, 상태 논리 (있을 경우) 가 클립 컴파일러에 의해 축소되고 삽입되었습니다.

    각주


    React의 '서버 쪽 렌더링' 출력은 렌더링 트리를 구축하는 데 오래 걸리기 때문에 렌더링을 막지 못하기 때문에 서버에서 렌더링을 하지 않기 때문에 이 용어의 사용이 부적절하다.
    ²생산동결출력은 구글의 클립 컴파일러를 사용하여 컴파일하는데 이 컴파일러는 명칭 손상, 사코드 제거 및 기타 최적화를 처리하여 가능한 한 빠르고 최소한의 ES5 출력을 생성한다.
    클로즈업 컴파일러는 CSS 클래스를 포함하여 프로덕션 동결 프로세스의 모든 이름 변경을 수행합니다.CSS 클래스 이름은 ES6 클래스 이름에서 생성되었고 작은 위젯이 자신을 나타낼 때 이런 방식으로 인용되기 때문에 이것은 자연적으로 발생한 것으로 별도의 설정이 없습니다.
    삽입식 상태 논리에서 Z 라는 최고급 함수가 호출되었다. Z.a(el).h()CounterView.from(el).render() 의 컴파일된 버전이다.Z (레이아웃에 있는 모든 다른 작은 위젯) 의 컴파일 스타일과 함수 정의가 <head> 요소에 삽입됩니다.

    좋은 웹페이지 즐겨찾기