Houdini - CSS 이해하기

CSS가 수행하는 작업의 양에 대해 생각해 본 적 있으신가요? 첫 번째 단어는 속성을 사용하다가 갑자기 전체 웹사이트가 다른 레이아웃으로 나타나게 됩니다. 그것은 마법처럼 말이죠. 지금까지 웹 개발자 커뮤니티는 오직 마법을 목격하고 관찰할 수 있었습니다. 이 모든 아이디어를 떠올리고 싶다면 어떻게 해야 할까요? 마술사가 되고 싶다면 어떻게 해야 할까요?

Houdini에 들어오세요!

Houdini 태스크 포스는 Mozilla, Apple, Opera, 마이크로소프트, HP, 인텔 및 Google이 함께 협력하여 공격의 특정 부분을 웹 개발자에게 CSS Engine을 제공합니다. 이 태스크포스에서는 수집된 초안을 만든 후 실제 웹이 될 수 있도록 W3C에서 승인을 얻어야 합니다. 있습니다. 몇 가지 개괄적인 목표를 세우고 그 목표를 이를 통해 일련의 지원 체계를 탄생시켰고, 하위 수준의 사양 초안도 볼 수 있습니다.

이러한 초안의 모음은 일반적으로 누군가가 'Houdini' 작성 시점의 초안 목록은 다음과 같습니다. 불완전하며 일부 초안은 자리표시자에 불과합니다.

사양

Worklet (spec)

Worklet 그 자체는 그다지 유용하지 않습니다. 인코더-디코더 아키텍처는 이후의 답안을 많이 만들 수 있습니다. 웹 워커를 생각할 때 "worklet"을 읽으면 틀린 것이 아닙니다. 이들은 개념적으로 많은 부분이 겹칩니다. 그렇다면 왜 새로운 것, 생각해야 할까요?

Houdini의 목표는 새로운 API를 노출하는 웹 개발자가 자체 코드를 CSS 엔진에 연결하고 배웠습니다. 이 중 일부가 매우 중요하다고 생각하는 것은 코드 프래그먼트를 실행해야 할 때마다 싱글입니다. 프레임을 지정합니다. 그중 일부는 있습니다. Web Worker 사양 인용:

<ph type="x-smartling-placeholder">

즉, 웹 작업자는 Houdini가 계획하는 일을 할 수 없습니다. 따라서 워크렛이 발명되었습니다. Worklet은 ES2015 클래스를 사용하여 메서드 모음이며, 이 컬렉션의 서명은 Worklet의 유형입니다. 가볍고 수명이 짧습니다.

CSS Paint API (사양)

Paint API는 Chrome 65에서 기본적으로 사용 설정됩니다. 자세한 내용은 자세한 소개를 참조하세요.

컴포지터 워크렛

여기에 설명된 API는 더 이상 사용되지 않습니다. 컴포지터 워크렛에는 의 디자인이 변경되었으며 이제 'Animation Worklet'으로 제안됩니다. 자세히 알아보기: API의 현재 반복 버전입니다.

컴포지터 워크렛 사양이 WICG로 이동되어서 제가 가장 흥미로운 사양입니다. 다소 유용함 작업은 CSS에 의해 컴퓨터의 그래픽 카드로 아웃소싱됩니다. 그래픽 카드와 장치에 따라 다를 수 있지만 일반.

브라우저는 일반적으로 DOM 트리를 취하며, 특정 기준에 따라 브랜치와 하위 트리에 자체 레이어를 제공하기로 결정합니다. 이러한 하위 트리는 그 위에 자신을 칠합니다 (예: 참조). 마지막 단계로, 이제 페인트된 모든 개별 레이어는 Z-지수, 3D 변환 및 화면에 보이는 최종 이미지를 생성합니다. 이 프로세스는 합성이라고 하며 컴포지터에 의해 실행됩니다.

합성 프로세스의 장점은 페이지를 조금 스크롤하면 요소가 스스로 다시 페인트됩니다. 대신 이전 프레임의 레이어를 다시 사용하고 단순한 함수로 컴포지터를 확인할 수 있습니다. 이렇게 하면 속도가 빨라집니다. 이를 통해 60fps에 도달할 수 있습니다.

컴포지터 워크렛.

이름에서 알 수 있듯이 컴포지터 워크렛을 사용하면 컴포지터에 연결할 수 있습니다. 이미 페인트된 요소의 레이어가 다른 레이어 위에 배치되고 레이어링됩니다

조금 더 획득하려면 구성 가능한 파일에 연결하려고 한다고 브라우저에 특정 DOM 노드에 대한 액세스를 요청하고, 스크롤 위치, transform 또는 opacity 이렇게 하면 이 요소가 각 프레임에서 코드가 호출됩니다. 레이어를 이동할 수 있습니다. 레이어를 조작하여 속성을 변환하고 변경 (예: opacity) 무려 60fps로 멋진 작업을 할 수 있습니다.

다음은 컴포지터를 사용한 패럴랙스 스크롤의 전체 구현입니다. Worklet의 일환입니다.

// main.js
window.compositorWorklet.import('worklet.js')
    .then(function() {
    var animator = new CompositorAnimator('parallax');
    animator.postMessage([
        new CompositorProxy($('.scroller'), ['scrollTop']),
        new CompositorProxy($('.parallax'), ['transform']),
    ]);
    });

// worklet.js
registerCompositorAnimator('parallax', class {
    tick(timestamp) {
    var t = self.parallax.transform;
    t.m42 = -0.1 * self.scroller.scrollTop;
    self.parallax.transform = t;
    }

    onmessage(e) {
    self.scroller = e.data[0];
    self.parallax = e.data[1];
    };
});

Robert Flack이 폴리필 사용해 볼 수 있습니다. 분명히 많은 부분이 성능에 미치는 영향을 최소화합니다

레이아웃 Worklet (사양)

첫 번째 실제 사양 초안이 제안되었습니다. 구현 해보면 좋을 것 같습니다.

다시 말하지만, 이에 대한 사양은 사실상 비어 있지만 개념은 레이아웃 직접 작성하기 레이아웃 Worklet을 사용하면 display: layout('myLayout')를 실행하고 JavaScript를 실행하여 노드의 하위 요소를 식별할 수 있습니다.

물론 CSS flex-box 레이아웃의 전체 JavaScript 구현을 실행합니다. 동등한 네이티브 구현을 실행하는 것보다 느리지만 절충하여 실적이 향상될 수 있는 시나리오를 상상해 보십시오. 상상해 보세요. 타일로만 구성된 웹사이트(Windows 10 또는 석재 스타일) 있습니다. 절대 및 고정 배치는 사용되지 않으며 z-index도 사용되지 않습니다. 요소가 겹치거나 모든 종류의 테두리 또는 오버플로가 있습니다. 건너뛸 수 있는 기능 이러한 모든 검사로 레이아웃 재배치를 하면 성능이 향상될 수 있습니다.

registerLayout('random-layout', class {
    static get inputProperties() {
        return [];
    }
    static get childrenInputProperties() {
        return [];
    }
    layout(children, constraintSpace, styleMap) {
        const width = constraintSpace.width;
        const height = constraintSpace.height;
        for (let child of children) {
            const x = Math.random()*width;
            const y = Math.random()*height;
            const constraintSubSpace = new ConstraintSpace();
            constraintSubSpace.width = width-x;
            constraintSubSpace.height = height-y;
            const childFragment = child.doLayout(constraintSubSpace);
            childFragment.x = x;
            childFragment.y = y;
        }

        return {
            minContent: 0,
            maxContent: 0,
            width: width,
            height: height,
            fragments: [],
            unPositionedChildren: [],
            breakToken: null
        };
    }
});

입력된 CSSOM (사양)

<ph type="x-smartling-placeholder">

입력된 CSSOM (CSS Object Model 또는 Cascading Style Sheets Object Model)은 우리 모두가 경험한 문제였고 이제 막 참는 법을 배웠을 것입니다. JavaScript 코드 한 줄로 설명하겠습니다.

    $('#someDiv').style.height = getRandomInt() + 'px';

수학을 하고 있습니다. 숫자를 문자열로 변환하여 단위를 브라우저가 해당 문자열을 파싱하여 CSS 엔진에 맞게 다시 숫자로 변환합니다. 이는 JavaScript로 변환을 조작할 때 더 악화됩니다. 더 이상은 아닙니다. 이제 CSS를 입력하려고 합니다.

이 초안은 좀 더 완성도가 높은 초안 중 하나이며 폴리필은 작업을 진행 중입니다. (면책 조항: 폴리필을 사용하면 더 많은 컴퓨팅 오버헤드를 추가할 수 있습니다 요점은 이 과정이 얼마나 편리한지 있습니다.)

문자열 대신 요소의 StylePropertyMap에서 작업합니다. 여기서 각 CSS 속성에는 자체 키와 해당 값 유형이 있습니다. 특성 width의 값 유형은 LengthValue입니다. LengthValue는 모든 CSS 단위(예: em, rem, px, percent 등)의 사전을 제공합니다. 설정 height: calc(5px + 5%)LengthValue{px: 5, percent: 5}을 생성합니다. 다소 유용함 box-sizing 같은 속성에서는 특정 키워드만 허용하므로 KeywordValue 값 유형입니다. 그런 다음 이러한 속성의 유효성을 검사하고 런타임 시 사용할 수 있습니다

<div style="width: 200px;" id="div1"></div>
<div style="width: 300px;" id="div2"></div>
<div id="div3"></div>
<div style="margin-left: calc(5em + 50%);" id="div4"></div>
var w1 = $('#div1').styleMap.get('width');
var w2 = $('#div2').styleMap.get('width');
$('#div3').styleMap.set('background-size',
    [new SimpleLength(200, 'px'), w1.add(w2)])
$('#div4')).styleMap.get('margin-left')
    // => {em: 5, percent: 50}

속성 및 값

(사양)

CSS 맞춤 속성 (또는 비공식 별칭인 'CSS 변수')을 알고 있나요? 유형이 있습니다. 지금까지 변수는 문자열 값만 가질 수 있었고 간단한 찾기 및 바꾸기 방법을 사용했습니다. 이 초안을 사용하면 변수의 유형만 지정하고, 기본값 및 JavaScript API를 사용하여 상속 동작에 영향을 줄 수 있습니다. 기술적으로는 또한 표준 CSS 전환으로 맞춤 속성에 애니메이션을 적용할 수 있습니다. 사용할 수 있습니다.

["--scale-x", "--scale-y"].forEach(function(name) {
document.registerProperty({
    name: name,
    syntax: "<number>",
    inherits: false,
    initialValue: "1"
    });
});

글꼴 측정항목

글꼴 측정항목은 정확히 말 그대로입니다. 경계 상자 (또는 경계 상자)가 표시되는가? Google Cloud 콘솔로 ruby 주석을 사용한 적이 있나요? 이건 많은 요청이 있었고, Houdini는 마침내 이 소원을 들어줄 수 있습니다.

잠시만 기다려 주세요.

Houdini의 드래프트 목록에는 훨씬 더 많은 사양이 있지만 그 미래는 아이디어의 자리표시자에 불과한 것이 아닙니다. 커스텀 오버플로 동작, CSS 구문 확장 API, 확장 프로그램 등을 예로 들 수 있습니다. 유사한 야심찬 기능을 제공하여 웹 플랫폼에서는 불가능했던 일들이 가능해졌습니다.

데모

데모용 코드를 오픈소스로 제공했습니다. (폴리필을 사용한 라이브 데모).