javascript

46 개의 포스트

cloudflare

에이전틱 인터넷의 좋은 행동과 나쁜 행동을 파헤치다 (새 탭에서 열림)

인터넷 트래픽은 인간과 봇으로 단순히 나눌 수 없으며, 한 세션 안에서 인간과 에이전트가 번갈아 행동하는 하이브리드 트래픽도 증가하고 있다. 따라서 사이트 운영자는 일회성 검사보다 세션 전체의 행동을 분석해 위험(Risk)과 신뢰(Trust)를 평가해야 한다. Cloudflare는 투명하게 자신을 밝히고 신뢰를 남용하지 않는 봇은 허용하되, 지속적인 행동 분석으로 악성 자동화 트래픽을 탐지하는 생태계를 구축하고 있다. ## 위험과 신뢰는 서로 다른 개념 - **위험(Risk)**은 특정 요청이나 행동이 해로울 가능성으로, 순간적이고 상황에 따라 달라진다. - **신뢰(Trust)**는 시간에 걸쳐 쌓이는 평판이며, 방문자의 행동 맥락을 바탕으로 형성된다. - 예를 들어 밤늦게 초인종을 여러 번 누르는 행동만 보면 위험해 보이지만, 방문자가 신뢰하는 친구라면 판단이 달라진다. - 인터넷에서도 “특정 시간대의 요청”이나 “일정 횟수 이상의 요청”만으로 차단하면 정상적인 사용자를 오탐할 수 있다. - Cloudflare는 악성 활동을 차단하는 것부터 안전한 참여를 장려하는 것까지, 신뢰를 중심으로 한 도구와 인센티브를 제공하려 한다. ## 투명성을 기반으로 한 정상 봇 - Cloudflare가 정의하는 검증된 봇과 에이전트는 다음 두 조건을 만족해야 한다. - 자신이 누구인지 정직하게 선언한다. - 획득한 신뢰를 악용하지 않는다. - 봇 운영자가 정체성과 데이터 사용 목적을 투명하게 공개하면, 사이트 운영자는 허용할 행동과 접근 범위를 더 쉽게 결정할 수 있다. - **BotBase**는 단순히 “좋은 봇 목록”을 제공하는 디렉터리가 아니라, 알려진 봇과 에이전트의 신원 및 행동 정보를 추적하는 시스템이다. - 검증된 봇이라도 Cloudflare 네트워크에서 신뢰를 남용하면 검증 상태를 잃을 수 있다. - 즉, 정상 여부는 고정된 신분이 아니라 실제 행동과 신뢰 유지 여부에 따라 계속 평가된다. ## 일회성 검사를 넘어서는 악성 봇 탐지 - **Precursor**는 CDN에서 JavaScript를 주입해 클라이언트 측 행동을 지속적으로 분석하는 시스템이다. - CAPTCHA나 한 번의 브라우저 검사는 특정 시점의 위험만 평가하므로, 이후 악성 행동을 시작하는 봇을 놓칠 수 있다. - Precursor는 페이지 이동을 포함한 전체 세션을 관찰해 인간답지 않은 행동 패턴을 탐지한다. - 주요 효과는 다음과 같다. - 세션 전체에 걸친 신뢰 기반 탐지 - 봇 개발자가 여러 페이지에 걸쳐 인간 행동을 모방해야 하도록 비용 증가 - 단 한 번의 검사만 통과한 자동화 트래픽에 지속적인 우회 기회를 주지 않음 - 이는 봇 개발자가 탐지 시스템을 우회하는 경제적 이점을 줄여, 공격자와 방어자 사이의 경쟁에서 방어 측에 유리하게 만든다. ## 세션 중간에 나타나는 의심스러운 행동 - 출시 후 24시간 동안 Precursor는 Cloudflare 네트워크의 73,438개 존에서 2억 600만 건의 평가 이벤트를 처리했다. - 분석 결과, 의심스러운 행동은 세션 시작 시점이 아니라 **세션 중간에 발생하는 경우가 많았다**. - 한 세션이 인간 행동에서 에이전트 행동으로, 다시 인간 행동으로 바뀌는 사례도 확인됐다. - 따라서 무조건 봇을 차단하기보다 다음 요소를 기준으로 분류해야 한다. - 트래픽의 사용 목적 - 요청의 의도 - 접근하는 데이터의 종류와 사용 방식 - 이 같은 하이브리드 트래픽을 정상적인 사용자 흐름과 구분하려면, 세분화된 봇·에이전트 분류 체계가 필요하며 BotBase 개편의 배경도 여기에 있다. ## Precursor Trace와 행동 신호 - **Precursor Trace**는 Precursor 탐지 방식 일부를 체험할 수 있는 인터랙티브 데모다. - 커서 움직임을 분석해 다음과 같은 특징을 보여준다. - 움직임의 가속과 감속 - 이동 중 수정이나 보정 - 커서 이동의 리듬과 질감 - 사람은 무의식적으로 이러한 불규칙성을 보이지만, 자동화 프로그램이 이를 여러 페이지와 긴 시간 동안 정확히 재현하기는 어렵다. ## 적응형 인텔리전스 - Cloudflare는 자동화 여부를 단순한 이진값으로만 판단하지 않고, 요청에 대한 평가 결과를 여러 단계로 구분하는 **Adaptive Intelligence**를 준비하고 있다. - 제공된 글의 본문은 이 기능의 구체적인 평가 단계와 출시 내용이 이어지기 전에 끝나 있어, 세부 사항은 확인할 수 없다. 사이트 운영자는 CAPTCHA 같은 단발성 방어책에만 의존하기보다 세션 전체의 행동, 봇의 신원 공개, 목적과 데이터 사용 방식을 함께 평가하는 것이 좋다. 정상적인 자동화는 투명성과 신뢰를 바탕으로 허용하고, 신뢰를 악용하거나 세션 중간에 비정상 행동을 보이는 트래픽은 지속적으로 재평가하는 접근이 적절하다.

cloudflare

Workers RPC, 이제 Python과 JavaScript 간에도 작동 (새 탭에서 열림)

Cloudflare Workers의 RPC가 이제 JavaScript/TypeScript와 Python 사이에서도 동작해, 서로 다른 언어로 작성된 Worker가 별도 API 스키마나 의존성 없이 메서드·객체·함수를 주고받을 수 있게 되었습니다. 개발자는 다른 언어의 Worker를 로컬 라이브러리처럼 호출할 수 있으며, 예외·비동기 반환값·콜백도 자연스럽게 전달됩니다. 이를 위해 Pyodide FFI와 사용자 정의 타입 변환 계층을 결합해 두 언어의 타입 체계를 연결했습니다. ## 언어 간 RPC 호출 - TypeScript Worker에서 정의한 `add(a, b)` 메서드를 Python Worker에서 `await rpc.add(42, 144)`처럼 호출할 수 있습니다. - 반대로 Python Worker의 메서드를 JavaScript/TypeScript에서 호출하는 것도 가능합니다. - 별도 패키지나 직렬화 스키마 없이 Service binding만 설정하면 됩니다. ```json { "services": [ { "binding": "RPC", "service": "ts-rpc-server", "entrypoint": "RpcService" } ] } ``` - RPC 대상은 Worker의 엔트리포인트 클래스에 정의된 메서드로 노출됩니다. ## 일반 함수처럼 동작하는 RPC - JavaScript/TypeScript에서는 Promise, Python에서는 Future처럼 비동기 결과를 받습니다. - 원격 메서드에서 발생한 예외는 호출한 쪽의 RPC 호출 지점에서 다시 발생합니다. - Structured Cloneable 타입을 인자와 반환값으로 전달할 수 있습니다. - JavaScript의 `Date`는 Python의 `datetime`으로 변환됩니다. - 숫자, 불리언, 객체, 배열 등 기본 타입도 대응되는 언어의 타입으로 변환됩니다. - 함수를 다른 Worker에 전달하거나 반환할 수 있습니다. - 상대 Worker가 해당 함수를 호출하면 원래 Worker로 역방향 RPC가 발생합니다. - 대부분의 Worker 간 RPC는 네트워크를 거치지 않고 동일한 스레드에서 실행되므로, 같은 Worker 내부 함수 호출에 가까운 성능을 제공합니다. - 구현은 `workerd`와 `workers-runtime-sdk`의 오픈 소스 코드로 제공됩니다. ## JavaScript와 Python의 호출 방식 차이 두 언어는 복잡한 인자를 표현하는 방식이 다릅니다. - JavaScript/TypeScript는 보통 객체를 전달합니다. ```ts myFunction({ key: "myKey", value: true, optional: 1 }); ``` - Python은 위치 인자와 키워드 인자를 사용합니다. ```python my_complex_function("myKey", True, optional=1) ``` - 목표는 호출자가 상대 언어의 내부 표현을 의식하지 않도록 만드는 것입니다. - Python에서 JavaScript 메서드의 옵션 객체를 다음 두 방식으로 모두 전달할 수 있습니다. ```python JSRPC.get("myKey", {"type": "text"}) JSRPC.get("myKey", type="text") ``` - Pyodide FFI가 두 호출을 JavaScript가 기대하는 옵션 객체 형태로 변환합니다. ## Pyodide FFI 기반 타입 변환 Pyodide는 WebAssembly로 컴파일된 CPython이며, Python과 JavaScript 사이의 기본 타입 변환 기능을 제공합니다. | Python 타입 | JavaScript 타입 | |---|---| | `int`, `float` | `Number` | | `bool` | `Boolean` | | `dict` | `Object` | | `list` | `Array` | - 직접 변환하기 어려운 사용자 정의 클래스나 함수는 Proxy 객체로 표현됩니다. - Proxy는 다른 언어의 속성 접근과 메서드 호출을 원격으로 전달합니다. - 이 방식으로 Python 함수를 JavaScript에 콜백으로 넘기는 등의 패턴을 구현할 수 있습니다. ## Cloudflare Workers 객체 처리의 과제 - `Request`, `Response`, `Blob`, `File` 같은 Cloudflare Workers의 Web API 객체는 일반 Python 타입과 달리 Pyodide가 자동 변환하지 못합니다. - 기본 동작에서는 이런 객체를 JavaScript Proxy로 전달합니다. - 기능적으로는 사용할 수 있지만, Python 개발자가 JavaScript 구현 세부사항과 Proxy를 계속 의식해야 하는 문제가 있습니다. - 따라서 언어 간 RPC를 완전히 자연스럽게 만들려면 표준 타입뿐 아니라 Workers 전용 객체에 대한 별도 변환 전략도 필요합니다. ## 실용적인 결론 언어별 강점을 활용해 하나의 Workers 애플리케이션을 구성하려는 경우, 이번 기능은 유용한 선택지입니다. Service binding만으로 TypeScript와 Python Worker를 연결할 수 있으므로, 공통 API 서버나 수동 직렬화 계층을 별도로 만들기보다 RPC를 통해 기능을 라이브러리처럼 분리하는 방식을 고려할 수 있습니다.

cloudflare

Precursor 소개: 지속적인 클라이언트 측 신호를 통한 에이전트형 행동 탐지 (새 탭에서 열림)

Cloudflare의 Precursor는 개별 요청이나 챌린지 결과가 아니라 웹사이트 전체 세션에서 나타나는 행동 패턴을 지속적으로 분석해 인간과 봇·에이전트 트래픽을 구분하는 클라이언트 측 검증 시스템이다. Turnstile이 로그인·가입·결제 같은 특정 시점의 검증을 담당한다면, Precursor는 사용자 여정 전반의 신호를 수집해 탐지 정확도를 높이고 불필요한 챌린지를 줄인다. 봇이 실제 브라우저와 JavaScript를 사용하더라도 장시간 일관된 인간 행동을 모방하기는 어렵다는 점이 핵심이다. ### 기존 봇 탐지의 가시성 한계 - Cloudflare는 하루 1조 건이 넘는 요청과 인터넷의 20% 이상에서 얻은 네트워크 신호를 활용한다. - Turnstile은 CAPTCHA 대체 수단에서 위험 기반 관리형 챌린지로 발전했으며, 하루 약 30억 회 실행된다. - 하지만 로그인, 가입, 결제처럼 중요한 순간에만 검증하면 애플리케이션 전체 여정에서 사용자가 어떻게 행동했는지는 충분히 파악하기 어렵다. - Precursor는 이 공백을 메우기 위해 세션 전체의 상호작용을 지속적으로 관찰한다. ### Precursor의 역할 - 동적으로 삽입되는 JavaScript가 방문자의 행동 신호를 수집한다. - 수집된 신호는 실시간으로 Cloudflare의 봇 방어 시스템에 반영된다. - Turnstile을 대체하는 기능이 아니라, Enterprise Bot Management에서 선택적으로 함께 사용하는 보완 기능이다. - 짧은 시간 동안 정상적으로 보이는 자동화도 세션 전체의 일관된 행동 패턴에서는 이상 징후를 드러낼 수 있다. - 공격자는 전체 세션을 인간처럼 시뮬레이션해야 하므로 자동화 개발·유지·대규모 운영 비용이 증가한다. - 정상 사용자는 공격적인 챌린지를 덜 받으면서도 보호 수준을 유지할 수 있다. ### 인간 행동과 봇 행동의 차이 - 인간의 마우스 움직임은 단순한 무작위 노이즈가 아니라 물리적·인지적 제약을 따른다. - 손목과 팔의 회전 범위 때문에 움직임이 일정한 곡선이나 호 형태를 보인다. - 화면의 요소를 인지한 뒤 클릭하기까지 인지 처리 시간이 발생한다. - 손 떨림으로 인해 미세한 생리학적 진동이 나타난다. - 봇은 다음과 같은 패턴을 보이기 쉽다. - 두 지점 사이를 직선으로 이동한다. - 수학적으로 이상적인 베지어 곡선을 따른다. - 지나치게 정확하게 클릭한다. - 동일한 속도와 리듬으로 반복한다. - 마우스를 항상 원점으로 되돌리는 등 기계적인 동작을 보인다. - 개별 동작 하나만 보면 정상처럼 보일 수 있지만, 세션 전체에서 이동 경로·속도·대기 시간·수정 동작의 반복을 관찰하면 인간과 자동화의 차이가 커진다. - 마우스 이동 외에도 키보드 활동, 포커스 변화, 페이지 가시성 등이 함께 분석된다. ### 데이터 수집 및 전송 - Precursor가 활성화되면 Cloudflare가 네트워크를 통과하는 HTML 응답에 경량 스크립트를 자동 삽입한다. - 별도의 네트워크 설정이나 외부 임베드가 필요 없다. - 스크립트는 응답마다 동적으로 조립되고 난독화되며, 기존 애플리케이션 로직에 영향을 주지 않도록 설계된다. - 다음과 같은 이벤트를 수집한다. - 포인터 이동 - 키보드 활동 - 입력 요소의 포커스 변화 - 페이지 가시성 변화 - 이벤트는 압축된 형식으로 직렬화되어 메모리에 임시 저장된다. - 일정 간격으로 버퍼의 데이터가 평가 계층으로 전송된다. ### 엣지 기반 행동 평가 - Cloudflare 엣지 서버는 수신한 Precursor 데이터를 역직렬화해 행동 입력으로 변환한다. - 여러 평가기(evaluator)가 각자 필요한 데이터 스트림을 분석하고 탐지 레지스트리에 신호를 추가한다. - 평가기는 단일 이벤트보다 서로 다른 신호 간의 상관관계를 확인한다. - 포인터 활동이 실제 페이지 가시 시간과 일치하는지 검사한다. - 키보드 입력이 텍스트 필드 포커스 상태에서 발생했는지 확인한다. - 개별 평가 결과는 통합된 탐지 신호로 변환되어 세션의 봇 점수와 판정에 반영된다. ### 세션 단위 분석 - Precursor 데이터는 요청 단위가 아니라 세션 범위에서 누적된다. - 페이지를 새로고침하거나 새로운 챌린지를 시작해도 기존 행동 서명을 쉽게 초기화할 수 없다. - 세션 메타데이터는 다음과 같은 후속 분석에도 사용된다. - 섀도 모드 휴리스틱 - 세션 분석 - 예측된 완료 상태와 실제 완료 상태의 비교 - 세션 비정상 종료(delinqency) 관련 휴리스틱 - 엣지에서 관찰된 정보는 탐지 개선과 세션 봇 점수 조정에 활용된다. - Cloudflare는 요청별 분석에서 방문자 전체 여정을 보는 방식으로 확장하기 위해 Security Analytics에 세션 기반 뷰를 도입한다. ### 개인정보 보호 설계 - 자동화와 악성 행위를 식별하는 데 필요한 최소한의 신호만 수집한다. - 키보드 활동은 실제 입력한 키가 아니라 입력 시점의 타이밍과 리듬으로 기록된다. - 개별 행동 자체보다 여러 행동의 집계된 패턴을 평가한다. - 수집된 행동 신호는 Cloudflare 내부 봇 탐지 시스템에서 사용된다. - 고객 대시보드에 노출되지 않으며, 사용자 계정·로그인 신원·영구 프로필과 연결되지 않는다. ### 실용적인 결론 Precursor는 CAPTCHA를 더 복잡하게 만드는 접근보다, 사용자 세션 전체에서 축적되는 행동 일관성을 탐지 신호로 활용하는 방식이다. 봇 방어가 필요한 서비스는 Turnstile로 중요한 순간을 보호하면서 Precursor로 전체 여정을 분석하면, 정상 사용자에 대한 마찰을 줄이고 장기적으로 정교한 자동화 공격의 비용과 불안정성을 높일 수 있다.

toss

es-toolkit: 작은 내부 라이브러리가 글로벌 프로젝트가 된 이야기 (새 탭에서 열림)

es-toolkit은 레거시 브라우저 지원과 비효율적인 구현으로 무거워진 lodash를 대체하기 위해 Toss 내부 유틸리티 라이브러리에서 출발했습니다. 최신 브라우저 API와 ECMAScript Modules를 활용해 불필요한 코드를 제거한 결과, 함수별 성능이 최소 2배에서 10배 이상 향상되고 번들 크기도 일부 경우 30배 이상 줄었습니다. 이후 국내외 개발자들의 참여와 오픈소스 생태계의 지원을 바탕으로 크게 성장했으며, 기존 lodash 사용자가 쉽게 전환할 수 있도록 `es-toolkit/compat`도 개발했습니다. ## lodash를 대체할 현대적인 유틸리티 라이브러리의 필요성 - 프론트엔드 개발에서는 `throttle`, `debounce`, `uniq` 같은 유틸리티 함수가 자주 필요했습니다. - 널리 사용되던 lodash는 다음과 같은 한계가 있었습니다. - 오래된 코드 구조를 유지함 - `Array#map`처럼 브라우저가 기본 제공하는 기능을 직접 재구현함 - Internet Explorer 등 레거시 브라우저를 위한 방어 로직을 포함함 - ECMAScript Modules를 지원하지 않아 tree-shaking이 어려움 - `lodash-es`는 ESM을 지원했지만 lodash의 오래된 내부 구현과 비효율성은 그대로였습니다. - Toss는 자체 라이브러리인 `@toss/utils`를 운영했지만, 모든 함수를 직접 구현하고 다양한 엣지 케이스를 관리하는 데 큰 부담이 있었습니다. ## es-toolkit의 시작과 성능 개선 - Toss 팀은 현대적인 웹 환경에 맞는 효율적인 유틸리티 라이브러리를 만들기로 했습니다. - 핵심 목표는 lodash의 불필요한 로직을 제거하고, 브라우저 내장 API를 적극 활용하는 것이었습니다. - 구현 결과: - 함수에 따라 성능이 최소 2배, 최대 10배 이상 향상 - 레거시 브라우저 지원 코드와 중복 구현을 제거해 일부 번들 크기가 30배 이상 감소 - 최신 모듈 시스템을 활용해 필요한 코드만 포함할 수 있는 기반 마련 ## 국내외 오픈소스 커뮤니티의 참여 - Toss Frontend의 소셜 미디어에 초기 결과를 공유한 뒤 예상보다 많은 사용자가 유입되었습니다. - 커뮤니티 구성원들은 다음과 같은 방식으로 프로젝트에 기여했습니다. - 누락된 함수 구현 - 버그 수정 - 미완성된 코드 최적화 - lodash를 es-toolkit으로 교체하는 번들러 플러그인 제작 - 유명 라이브러리의 의존성 교체 - Reddit 공유 이후 100개 이상의 추천과 수만 명의 저장소 방문이 발생했습니다. - 해외 블로그와 뉴스레터가 프로젝트를 소개하면서 국제적인 참여가 더욱 확대되었습니다. ## 오픈소스 기여가 개발자 성장으로 이어진 사례 - Dayong Lee는 es-toolkit을 계기로 한국에서도 영향력 있는 오픈소스 프로젝트가 나올 수 있다는 가능성에 주목했습니다. - Toss 직원이 아니었지만 공개 저장소에 작은 Pull Request부터 제출하며 기여를 시작했습니다. - 지속적인 코드 리뷰와 기여를 통해 프로젝트의 두 번째로 많은 기여자가 되었습니다. - 이 과정에서 다음을 학습했습니다. - 인터페이스 설계 원칙 - JavaScript 언어의 세부 동작 - 협업과 코드 리뷰 방식 - es-toolkit에서 쌓은 경험은 이후 Toss Bank에 합류하는 계기가 되었습니다. ## 기존 사용자의 전환 장벽 - 라이브러리가 빠르게 발전했지만, 기존 lodash 사용자가 es-toolkit으로 전환하는 속도는 상대적으로 느렸습니다. - lodash는 코드베이스 곳곳에서 다양한 함수를 사용하기 때문에 함수별로 하나씩 교체하는 작업은 큰 부담이었습니다. - 또한 lodash는 가능한 많은 입력과 예외 상황을 처리하는 반면, es-toolkit은 주요 사용 사례에 집중했습니다. - 따라서 동일한 이름의 함수를 단순히 교체하면 일부 상황에서 동작 차이로 런타임 오류가 발생할 수 있었습니다. ## `es-toolkit/compat`을 통한 점진적 마이그레이션 - es-toolkit 팀은 import 문만 바꿔도 사용할 수 있는 lodash 호환 계층의 필요성을 발견했습니다. - `es-toolkit/compat`은 lodash의 인터페이스와 실제 동작을 최대한 유지하면서 내부 구현만 현대화하는 방식으로 설계되었습니다. - 이를 통해 사용자는 대규모 코드 수정 없이도 다음 효과를 얻을 수 있습니다. - 기존 lodash 사용 방식 유지 - 더 빠른 내부 구현 활용 - 점진적으로 es-toolkit 표준 API로 마이그레이션 - 즉, 완전한 재작성보다 낮은 비용으로 성능과 번들 크기 개선을 먼저 경험하게 하는 전략입니다. ## 실용적인 결론 레거시 라이브러리를 교체할 때는 단순히 더 빠른 구현을 제공하는 것만으로는 충분하지 않습니다. 기존 API와 동작을 유지하는 호환 계층을 함께 제공하면 대규모 코드베이스의 전환 장벽을 크게 낮출 수 있습니다. 새로운 프로젝트에는 es-toolkit을 직접 사용하고, 기존 lodash 프로젝트에는 `es-toolkit/compat`을 활용한 단계적 마이그레이션을 고려할 수 있습니다.

toss

es-toolkit, 사내 작은 라이브러리가 전세계적인 라이브러리가 되기까지 (새 탭에서 열림)

es-toolkit은 오래되고 비효율적인 lodash를 현대 JavaScript 환경에 맞게 대체하기 위해 시작된 유틸리티 라이브러리입니다. 불필요한 호환 코드를 제거하고 핵심 사용 사례에 집중한 결과, 함수 성능은 최대 10배 이상 향상되고 번들 크기는 최대 30배 이상 줄었습니다. 이후 `es-toolkit/compat`과 오픈소스 커뮤니티의 기여를 통해 Yarn, Recharts, Storybook 등 다양한 프로젝트에 채택되며 주간 NPM 다운로드 2천만 회를 넘어섰습니다. ## lodash의 한계와 es-toolkit의 시작 - lodash는 오래된 브라우저와 Internet Explorer를 지원하기 위한 방어적 코드가 많이 포함되어 있습니다. - `Array#map`처럼 현대 브라우저가 기본 제공하는 기능도 직접 구현해 코드가 불필요하게 커졌습니다. - ECMAScript Modules를 지원하지 않아 Tree-shaking으로 필요한 코드만 포함하기 어려웠습니다. - `lodash-es`는 ESM만 추가했을 뿐, 기존 lodash의 낡고 비효율적인 구현 문제는 그대로였습니다. - 토스 내부에서도 `@toss/utils`를 직접 운영했지만, 유틸리티 함수의 다양한 엣지 케이스를 관리하는 데 부담이 있었습니다. - 이에 따라 “lodash의 불필요한 로직을 제거해 더 빠르고 작은 라이브러리를 만들자”는 목표로 es-toolkit이 시작되었습니다. ## 성능과 번들 크기 개선 - lodash의 핵심 함수인 `throttle`, `debounce`, `uniq` 등을 현대적인 방식으로 다시 구현했습니다. - 함수별로 차이는 있지만 불필요한 로직을 제거한 결과 성능이 최소 2배에서 최대 10배 이상 향상되었습니다. - 오래된 브라우저 지원 코드와 중복 구현을 제거해 번들 크기가 최대 30배 이상 감소했습니다. - 현대적인 모듈 구조를 활용해 사용하는 함수만 번들에 포함할 수 있도록 했습니다. - 핵심 유스케이스에 집중해 모든 예외 상황을 처리하는 대신, 일반적인 사용 환경에서 작고 빠르게 동작하도록 설계했습니다. ## 오픈소스 커뮤니티의 확산 - 토스 프론트엔드 SNS를 통해 첫 버전을 공개한 뒤 국내 개발자들의 관심과 기여가 이어졌습니다. - 기여자들은 누락된 함수 구현, 버그 수정, 성능 최적화 등을 Pull Request로 보완했습니다. - 해외 개발자 커뮤니티에 소개된 후 수만 명이 저장소를 확인하고, 구현 방식과 개선점에 대해 활발히 논의했습니다. - 커뮤니티에서는 lodash를 es-toolkit으로 바꾸는 번들러 플러그인과 다른 라이브러리의 의존성을 교체하는 작업도 자발적으로 진행했습니다. - 외부 기여자로 참여한 이다용 개발자는 지속적인 코드 리뷰와 기여를 통해 JavaScript 및 API 설계 경험을 쌓았고, 이후 토스뱅크 입사로 이어졌습니다. ## `es-toolkit/compat`을 통한 마이그레이션 - es-toolkit은 주요 사용 사례에 집중했기 때문에 lodash와 함수 동작이 다른 경우가 있었습니다. - 단순히 import 경로만 바꾸면 런타임 오류가 발생할 수 있어 기존 프로젝트의 마이그레이션 부담이 컸습니다. - 이를 해결하기 위해 lodash의 인터페이스와 동작을 최대한 호환하는 중간 계층인 `es-toolkit/compat`을 제공했습니다. - 기존 코드를 크게 수정하지 않고 import만 변경해도 내부 구현의 현대화 효과를 얻을 수 있도록 했습니다. - 이 접근 방식으로 Storybook, Mermaid, Yarn Berry, Recharts 등 대규모 오픈소스 프로젝트의 채택이 늘었습니다. - 결과적으로 es-toolkit은 주간 NPM 다운로드 2천만 회 이상을 기록했습니다. ## 앞으로의 확장 방향 - 더 많은 JavaScript 라이브러리가 es-toolkit을 사용해 번들 크기와 실행 성능을 개선하도록 지원할 계획입니다. - `Map`과 `Set`의 필터링처럼 기존 내장 자료구조에서 다루기 불편한 기능을 추가하려고 합니다. - Promise 기반 비동기 코드에서 자주 사용하는 `delay` 같은 실용적인 함수도 제공합니다. - 브라우저뿐 아니라 Node.js, Deno, Bun 등 서버 환경을 위한 유틸리티로 영역을 넓히고 있습니다. - 최근 추가된 `exec`처럼 필요한 기능은 유지하면서도 경쟁 구현보다 작은 함수를 제공하는 것을 지향합니다. - 앞으로도 “80% 이상의 유스케이스에 최적화된 작고 빠른 구현”이라는 원칙을 유지할 계획입니다. 기존 lodash를 사용 중인 프로젝트라면 먼저 `es-toolkit/compat`으로 점진적인 교체를 검토하는 것이 현실적인 접근입니다. 이후 호환성이 필요 없는 코드부터 순수 es-toolkit 함수로 전환하면 성능과 번들 크기를 줄이면서도 마이그레이션 위험을 낮출 수 있습니다.

figma

레이어 패널의 성능 개선 | Figma 블로그 (새 탭에서 열림)

Figma는 대규모 파일에서 레이어 패널의 느린 상호작용을 해결하기 위해 아키텍처를 전면 재설계했다. 행 목록 계산과 노드 상세 정보 계산을 분리하고, 파생 속성(derived properties)을 활용해 변경된 부분만 다시 계산한 결과, 가장 복잡한 파일에서 일부 상호작용이 30~50% 빨라졌다. 핵심은 보이지 않는 레이어까지 계산하지 않고, 필요한 데이터만 지연 계산·캐싱하는 것이다. ## 레이어 패널 성능 저하의 원인 - 레이어 패널은 Figma 파일의 노드 트리를 중첩된 목록으로 표현한다. - 초기 아키텍처는 파일의 각 노드에 대해 이름, 아이콘, 표시 여부, 잠금 상태 등 UI에 필요한 데이터를 하나의 큰 JavaScript 객체로 구성했다. - 레이어가 변경될 때마다 확장된 모든 노드에 대해 데이터를 처음부터 다시 계산했다. - 파일이 수만 개의 레이어를 포함하게 되면서 두 가지 문제가 발생했다. - **계산량 과다:** 화면에 실제로 보이는 행은 보통 20~30개뿐인데, 확장된 모든 노드의 데이터를 계산했다. - **재계산 빈도 과다:** 레이어 하나를 확장하거나 변경해도 전체 데이터를 다시 생성했다. ## 1단계: 두 번에 나누어 계산하기 - 데이터 수집 과정을 두 단계로 분리했다. - 첫 번째 단계에서는 패널에 표시될 **행 ID의 순서**만 계산한다. - 이 과정도 단순하지 않으며 다음과 같은 제품 규칙을 반영해야 한다. - 오토 레이아웃 프레임의 자식은 역순으로 표시될 수 있다. - 위젯이나 FigJam 스티키처럼 자식 노드를 패널에 표시하지 않는 노드가 있다. - 프로토타이핑 프레임의 고정 헤더와 스크롤 헤더는 자식을 두 영역으로 나눈다. - 최상위 프레임과 컴포넌트는 고정된 위치에 표시된다. - 두 번째 단계에서는 첫 단계에서 얻은 행 ID 중 현재 화면에 보이는 노드만 대상으로 상세 데이터를 계산한다. - 기존에도 화면 밖 항목을 렌더링하지 않는 윈도잉(windowing)을 사용했지만, 데이터 계산 자체는 모든 확장 노드에 대해 수행되고 있었다. - 새 구조에서는 이름, 아이콘, 잠금·표시 상태, 선택 상태 등을 실제로 필요한 수십 개 행에 대해서만 계산한다. - 그 결과 수십만 개 노드의 데이터를 계산하던 작업을 화면 주변의 작은 범위로 줄였다. ## 2단계: 파생 데이터 캐싱 - 변경되지 않은 레이어를 다시 그리거나 재계산하지 않고, 바뀐 부분만 갱신하도록 개선했다. - 이를 위해 Figma가 플랫폼 차원에서 개발한 **파생 속성(derived properties)** 기능을 사용했다. - Figma 노드는 직접 저장·조회할 수 있는 필드(fields)를 가진다. - 하지만 일부 속성은 직접 저장하지 않고 다른 필드와 속성으로부터 계산된다. - 예를 들어 노드는 부모 기준의 상대 위치만 저장하고, 절대 위치는 다음과 같이 계산할 수 있다. ```text Self.AbsolutePosition = Parent.AbsolutePosition + Self.RelativePosition ``` - 파생 속성 시스템은 이런 계산 관계를 명시적으로 선언하고, 의존하는 값이 바뀌면 최신 상태를 유지하도록 한다. - 시스템의 장점은 다음과 같다. - 각 파생 속성이 어떤 필드와 다른 파생 속성에 의존하는지 추적한다. - 의존 관계가 최적화된 그래프 형태로 컴파일된다. - 속도와 메모리 사용량 사이의 선택을 고려한 여러 캐싱 정책을 제공한다. - 기본적으로 지연 계산(lazy evaluation) 방식이어서 실제로 읽을 때만 계산한다. - 레이어 패널은 부모-자식 트리 구조를 갖기 때문에 파생 속성과 자연스럽게 결합된다. - 이전에는 트리 어디에서든 변경이 발생하면 노드 데이터를 전체적으로 다시 계산했지만, 새 구조에서는 의존 관계를 바탕으로 영향을 받은 데이터만 갱신할 수 있다. ## 성능 개선의 의미 - 대규모 Figma 파일에서 레이어 패널의 스크롤, 확장·축소, 선택 등의 상호작용이 더 빨라졌다. - 레이어 패널의 계산 비용이 줄어들면서 드래그나 텍스트 입력 같은 에디터의 다른 작업에도 영향을 주던 지연이 완화됐다. - 윈도잉만 적용하는 것보다, **계산 대상 자체를 가시 영역으로 제한하는 것**이 중요하다는 점을 보여준다. - UI 성능을 높이려면 다음 두 문제를 별도로 해결해야 한다. - 불필요한 항목까지 계산하는 문제 - 같은 항목을 반복해서 계산하는 문제 ## 실용적인 결론 대규모 트리형 UI에서는 렌더링만 가상화하는 것으로 충분하지 않다. 먼저 화면에 필요한 항목의 ID나 구조만 계산한 뒤, 실제 표시되는 항목의 상세 데이터만 지연 계산하고, 의존성이 변한 부분만 캐시를 무효화하는 방식이 효과적이다.

cloudflare

VoidZero가 Cloudflare에 합류합니다 (새 탭에서 열림)

VoidZero가 Cloudflare에 합류하지만 Vite, Vitest, Rolldown, Oxc, Vite+는 계속 MIT 라이선스의 오픈소스이자 벤더 중립적·커뮤니티 주도 프로젝트로 유지됩니다. Cloudflare는 프로젝트의 방향을 통제하기보다 개발 인력과 자원을 추가하고, Vite 생태계 기금에 100만 달러를 투자해 기반 도구와 기여자들을 지원할 계획입니다. 이번 합류는 Vite를 Cloudflare 전용 도구가 아니라 JavaScript 생태계 전체를 위한 공통 기반으로 더욱 확장하려는 움직임입니다. ## VoidZero의 Cloudflare 합류 - Vite, Vitest, Rolldown, Oxc, Vite+를 만든 VoidZero의 전 구성원이 Cloudflare에 합류합니다. - 해당 프로젝트들은 계속해서: - MIT 라이선스를 유지합니다. - 특정 클라우드나 호스팅 업체에 종속되지 않습니다. - 어디서나 실행할 수 있습니다. - 로드맵과 개발 과정을 공개적으로 운영합니다. - Evan You를 비롯한 기존 VoidZero 팀이 프로젝트 리드를 계속 맡습니다. - Cloudflare는 프로젝트를 자사 제품으로 전환하는 대신 엔지니어링 인력과 개발 자원을 투입합니다. ## Vite 생태계에 대한 투자 - Vite는 Vue, SvelteKit, Nuxt, Astro, Solid, Qwik, Angular, React Router, TanStack Start 등 다양한 프레임워크의 기반으로 자리 잡았습니다. - Next.js 역시 `vinext`를 통해 Vite 기반 구현을 제공하기 시작했습니다. - 따라서 Vite는 단일 프레임워크가 아니라 JavaScript 생태계 전반의 공유 기반으로 평가됩니다. - Cloudflare는 Vite의 핵심 채택 요인인 개방성, 이식성, 벤더 중립성에 대한 신뢰를 유지하는 것을 최우선 목표로 제시했습니다. - Vite 코어 팀이 관리하는 생태계 기금에 100만 달러를 출연해 유지보수자와 기여자를 지원합니다. - 앞서 Cloudflare에 합류한 Astro 역시 오픈소스와 멀티 플랫폼 배포를 유지하고 있다는 점을 선례로 들었습니다. ## Vite Environment API와 Cloudflare 연동 - Vite와 Cloudflare는 2024년부터 Vite Environment API를 함께 개발해 왔습니다. - Environment API를 사용하면 개발 중 서버 코드를 Node.js가 아닌 다른 런타임에서 실행할 수 있습니다. - Cloudflare Vite 플러그인을 사용하면 `vite dev` 실행 시 서버 코드가 프로덕션 Workers와 동일한 오픈소스 런타임인 `workerd` 안에서 동작합니다. - 로컬 개발 환경에서 다음 Cloudflare 기능을 프로덕션과 유사한 런타임 모델로 사용할 수 있습니다. - Durable Objects - D1, KV, R2 - Workflows - Workers AI - Agents - Service Bindings - Workers RPC - 특정 업체 전용 개발 서버를 강제하지 않고, Vite에 범용 확장 지점을 제공한 뒤 각 런타임이 구현하도록 설계한 점이 핵심입니다. - 이 구조를 통해 비-Node.js 런타임에서도 로컬 개발 경험이 프로덕션보다 크게 뒤처지는 문제를 줄일 수 있습니다. ## 급증하는 Vite와 Cloudflare 플러그인 사용량 - 글 작성 시점 기준 Vite는 주간 약 1억 2,900만 회 다운로드를 기록했습니다. - `@cloudflare/vite-plugin`도 주간 약 1,400만 회 다운로드에 도달했습니다. - 이는 Cloudflare 플러그인이 Vite 전체 다운로드의 10% 이상에 해당하는 규모입니다. - AI로 생성되는 소프트웨어가 급증하면서 애플리케이션을 빠르게 만들고 실행할 수 있는 기본 스택에 대한 수요도 커졌습니다. - AI가 작성한 애플리케이션이 Vite를 선택하고, 그중 일부가 Cloudflare에서 실행되면서 플러그인 사용량이 증가한 것으로 설명합니다. ## AI 에이전트 중심의 개발 루프 - 개발 서버, 번들러, 린터, 포매터, CLI는 더 이상 사람만 사용하는 도구가 아닙니다. - AI 에이전트도 다음 작업을 반복적으로 수행합니다. - 프로젝트 스캐폴딩 - 개발 서버 실행 - 오류 분석 - 테스트 작성 및 실행 - 린트와 포맷 적용 - 프리뷰 배포 - 결과 확인 후 재수정 - 에이전트 개발에서는 다음 특성이 특히 중요합니다. - 반복 횟수가 많으므로 빠른 빌드 - 지속적인 검증을 위한 빠른 테스트 - 코드 품질을 보장하는 빠른 린팅·포매팅 - 에이전트가 해석하고 조치하기 쉬운 구조화된 오류 - 불필요한 우회를 줄이는 일관된 CLI - Vitest, Rolldown, Oxc, Oxlint, Oxfmt는 각각 빠른 도구로 설계되었으며, 반복 실행이 많은 에이전트 작업에 적합합니다. - Vite+는 이 도구들을 하나의 CLI와 설정 모델로 통합해 사람과 에이전트 모두가 더 예측 가능하게 사용할 수 있도록 합니다. ## Cloudflare 내부에서의 실제 적용 - Cloudflare 대시보드는 Vite를 기반으로 구축되고 있습니다. - Cloudflare 코드베이스에서는 Oxlint가 엔지니어링 시간을 절약하는 데 사용되고 있습니다. - Astro 팀의 에이전트 하네스 프레임워크인 Flue도 Vite를 기반으로 전환 중입니다. - Flue는 Node.js, Cloudflare Workers, GitHub Actions, GitLab CI/CD 등 여러 환경에서 에이전트를 실행할 수 있습니다. - Cloudflare 대상 환경에서는 공식 Cloudflare Vite 플러그인과 `workerd` 통합을 사용합니다. - 결과적으로 Vite는 외부 생태계뿐 아니라 Cloudflare 내부 애플리케이션 개발의 기본 기반으로도 자리 잡고 있습니다. ## 실용적인 결론 이번 변화는 Vite 사용자가 Cloudflare를 선택해야 한다는 의미가 아니라, Vite를 계속 어느 환경에서나 사용할 수 있도록 지원이 강화된다는 의미에 가깝습니다. 기존 Vite 프로젝트는 플랫폼 종속성 없이 유지할 수 있고, Cloudflare Workers 기능이 필요하다면 공식 Vite 플러그인과 `workerd` 기반 로컬 개발 환경을 선택적으로 활용할 수 있습니다.

gitlab

GitLab 패치 릴리스: 18.11.3, 18.10.6, 18.9.7 | GitLab 문서 (새 탭에서 열림)

GitLab은 2026년 5월 13일 보안 및 버그 수정이 포함된 18.11.3, 18.10.6, 18.9.7 패치 버전을 출시했으며, 모든 자체 관리형 설치 환경에 즉시 업그레이드를 권고했습니다. 이번 릴리스에는 인증된 사용자가 악성 JavaScript를 실행할 수 있는 XSS, 인증 없이 서비스를 마비시킬 수 있는 DoS, 권한 검증 오류 등이 수정되었습니다. GitLab.com은 이미 패치가 적용되었고, GitLab Dedicated 고객은 별도 조치가 필요하지 않습니다. ## 릴리스 대상과 업그레이드 권고 - 대상 버전: - GitLab 18.11.3 - GitLab 18.10.6 - GitLab 18.9.7 - CE와 EE 모두에 해당하는 수정이 포함되었습니다. - Omnibus, 소스 설치, Helm 차트 등 특정 배포 방식이 명시되지 않은 취약점은 모든 배포 유형에 영향을 줍니다. - 지원되는 버전을 운영 중인 자체 관리형 GitLab은 가능한 한 빨리 최신 패치 버전으로 업그레이드해야 합니다. - GitLab 패치 릴리스는 매월 둘째·넷째 수요일의 정기 릴리스와, 심각도가 높은 취약점에 대응하는 비정기 긴급 패치로 나뉩니다. - 보안 취약점의 상세 이슈는 패치된 릴리스 후 30일이 지나면 공개됩니다. ## XSS 취약점 수정 - **CVE-2026-7481 — Analytics 대시보드 차트 렌더링** - GitLab EE에 영향. - Developer 권한의 인증된 사용자가 입력값 검증 부실을 악용해 다른 사용자의 브라우저에서 임의 JavaScript를 실행할 수 있었습니다. - CVSS 8.7. - 16.4 이상에서 18.9.7, 18.10.6, 18.11.3 이전 버전에 영향. - **CVE-2026-5297 — 전역 검색** - GitLab CE/EE에 영향. - 인증된 사용자가 조작된 입력을 통해 다른 사용자의 브라우저에서 JavaScript를 실행할 수 있었습니다. - CVSS 8.7. - 15.11 이상에서 수정 버전 이전까지 영향. - **CVE-2026-6073 — Duo Agent 출력 렌더링** - GitLab EE에 영향. - Duo Agent 출력 처리 과정의 입력값 정제 부족으로 XSS가 발생할 수 있었습니다. - CVSS 8.7. - 18.7 이상 버전 중 수정 버전 이전에 영향. - **CVE-2026-7377 — 사용자 지정 Analytics 대시보드** - GitLab EE에 영향. - 인증된 사용자가 대시보드 입력을 조작해 다른 사용자의 브라우저 컨텍스트에서 임의 JavaScript를 실행할 수 있었습니다. - CVSS 8.7. - 18.7 이상 버전 중 수정 버전 이전에 영향. ## 인증 없이 악용 가능한 DoS 취약점 - **CVE-2026-1659 — CI/CD 작업 업데이트 API** - 특수하게 조작된 요청과 불충분한 입력 검증을 이용해 인증 없이 서비스 거부를 일으킬 수 있었습니다. - GitLab CE/EE에 영향. - CVSS 7.5. - **CVE-2025-14870 — Duo Workflows API** - 조작된 JSON 페이로드를 전송해 인증 없이 서비스 거부를 유발할 수 있었습니다. - GitLab CE/EE에 영향. - CVSS 7.5. - **CVE-2025-14869 — 내부 API 엔드포인트** - 특정 API 엔드포인트에 악성 페이로드를 보내 서비스 거부를 일으킬 수 있었습니다. - GitLab CE/EE에 영향. - CVSS 7.5. - **CVE-2026-1184 — Insights 구성** - GitLab EE에서 조작된 파일 업로드와 부적절한 검증을 통해 서비스 거부가 발생할 수 있었습니다. - CVSS 6.5. - 일부 설명에서는 인증 요구 수준이 명시되어 있으므로 외부 파일 업로드 경로를 특히 점검해야 합니다. ## 권한 및 접근 제어 취약점 - **CVE-2026-1322 — GraphQL 토큰 범위 적용** - `read_api` 범위만 가진 OAuth 애플리케이션이 비공개 프로젝트에 이슈를 생성하거나 댓글을 추가할 수 있었습니다. - 인증 및 권한 검증 오류가 원인이었습니다. - GitLab CE/EE에 영향. - CVSS 6.8. - **CVE-2026-4524 — Issues API** - 공개 프로젝트의 기밀 이슈 내용이 적절한 권한 확인 없이 노출될 수 있었습니다. - GitLab CE/EE에 영향. - CVSS 6.5. ## 공개되지 않은 추가 수정 사항 - 글 마지막에는 **CVE-2026-8280 — direct transfer CSV 파서의 DoS 취약점**이 언급되지만, 제공된 본문이 해당 항목 중간에서 끝나 구체적인 영향 버전과 CVSS 점수는 확인할 수 없습니다. 자체 관리형 GitLab 운영자는 먼저 현재 버전을 확인하고 18.9.7, 18.10.6, 18.11.3 중 지원되는 최신 버전으로 업그레이드하는 것이 가장 안전합니다. 특히 외부에 노출된 API, 검색·분석 대시보드, OAuth 토큰, 파일 업로드 기능을 사용하는 환경은 패치 전까지 접근 통제를 강화해야 합니다.

cloudflare

동적이며 신원 기반의 안전한 샌드박스 인증 (새 탭에서 열림)

AI 에이전트와 같은 신뢰할 수 없는 워크로드를 안전하게 실행하기 위해서는 샌드박스 환경이 필수적이지만, 외부 서비스와의 통신 시 보안과 편의성을 동시에 확보하는 것은 어려운 과제였습니다. 이를 해결하기 위해 도입된 '아웃바운드 워커(outbound Workers)'는 프로그래밍 가능한 이그레스 프록시를 통해 샌드박스 내부로 비밀 키를 노출하지 않고도 안전하고 유연한 인증을 구현합니다. 이 방식은 제로 트러스트 원칙을 준수하면서도 개발자에게 강력한 통제권과 관찰 가능성을 제공하여 AI 워크로드의 보안 수준을 획기적으로 높여줍니다. ### 샌드박스의 핵심 가치와 아웃바운드 워커의 역할 * 샌드박스는 마이크로VM 기술을 활용해 신뢰할 수 없는 사용자나 LLM이 호스트 시스템이나 다른 워크로드를 침해하지 못하도록 격리하는 보안 기능을 제공합니다. * 단순한 격리를 넘어, 사용자가 이전 상태를 빠르게 복구할 수 있는 속도와 플랫폼이 샌드박스 내부 동작을 제어할 수 있는 통제권이 핵심입니다. * 아웃바운드 워커는 샌드박스에서 나가는 모든 트래픽을 가로채는 프록시 역할을 하며, 이를 통해 외부 서비스 연결, 로깅 추가, 동적 인증 주입 등을 프로그래밍 방식으로 처리합니다. ### 기존 에이전트 인증 방식의 문제점 * **표준 API 토큰:** 환경 변수나 파일로 토큰을 직접 주입하는 방식은 가장 단순하지만, 샌드박스가 탈취되거나 에이전트가 실수로 토큰을 노출할 경우 보안에 치명적입니다. * **워크로드 ID 토큰(OIDC):** 보안성은 높으나 많은 외부 서비스가 이를 직접 지원하지 않아, 토큰 교환을 위한 별도의 서비스를 구축해야 하는 등 통합의 유연성이 떨어집니다. * **커스텀 프록시:** 높은 유연성을 제공하지만 모든 트래픽을 효율적이고 동적으로 가로채는 시스템을 직접 설계하고 운영하는 것은 기술적 난이도가 매우 높습니다. ### 아웃바운드 워커를 통한 지능형 인증 매커니즘 * **제로 트러스트 구현:** 샌드박스 내부의 에이전트에게 토큰을 절대 전달하지 않습니다. 대신 프록시 계층에서 요청을 가로채 인증 헤더(예: `x-auth-token`)를 안전하게 삽입합니다. * **세밀한 통제와 관찰:** 자바스크립트 코드를 통해 특정 호스트(예: `github.com`)에 대해서만 인증을 적용하거나, GET 요청 이외의 동작을 차단하고 로깅하는 정책을 손쉽게 설정할 수 있습니다. * **성능과 투명성:** 프록시가 샌드박스와 동일한 머신에서 실행되므로 지연 시간이 거의 없으며, 샌드박스 내부의 워크로드는 프록시의 존재를 모른 채 평소처럼 통신하면 됩니다. * **동적 정책 변경:** 런타임 중에 인증 규칙이나 접근 권한을 즉시 변경할 수 있어, 에이전트의 작업 단계에 따른 유연한 권한 관리가 가능합니다. AI 에이전트가 외부 도구와 상호작용해야 하는 환경을 구축한다면, 에이전트에게 직접 권한을 부여하기보다 아웃바운드 워커와 같은 투명한 프록시 계층을 활용하는 것이 권장됩니다. 이를 통해 보안 사고의 위험을 원천 차단하면서도 개발 복잡성을 획기적으로 줄일 수 있습니다.

github

Diff 라인 성능 개선을 위한 험난한 여정 (새 탭에서 열림)

GitHub는 대규모 풀 리퀘스트에서도 **Files changed** 탭의 반응성과 안정성을 유지하기 위해 단일 해결책이 아닌 여러 최적화 전략을 적용했다. 특히 diff 라인마다 생성되는 DOM 요소, React 컴포넌트, 이벤트 핸들러를 줄여 메모리 사용량과 입력 지연을 낮추고, 가장 큰 변경 사항에는 가상화를 적용해 렌더링 범위를 제한하는 방향을 택했다. 핵심 교훈은 작은 구조적 최적화도 수천 개의 diff 라인에 누적되면 큰 성능 개선으로 이어진다는 것이다. ## 대규모 풀 리퀘스트에서 성능이 어려운 이유 - GitHub의 풀 리퀘스트는 한 줄 수정부터 수천 개 파일과 수백만 줄을 포함하는 변경까지 규모 편차가 매우 크다. - 일반적인 풀 리퀘스트는 빠르게 동작했지만, 대규모 변경에서는 다음 문제가 발생했다. - JavaScript 힙이 극단적인 경우 1GB를 초과 - DOM 노드 수가 40만 개 이상으로 증가 - 페이지 상호작용이 매우 느려지거나 사실상 사용할 수 없게 됨 - 입력 후 다음 화면이 표시되기까지의 시간인 INP가 허용 수준을 초과 - 모든 기능과 브라우저의 기본 동작을 유지하면서 최악의 경우까지 해결하는 단일 기법은 현실적인 한계가 있었다. ## 풀 리퀘스트 규모별 최적화 전략 GitHub는 변경 규모와 복잡도에 따라 서로 다른 전략을 조합했다. - **diff 라인 컴포넌트 최적화** - 대부분의 풀 리퀘스트에서 기본 diff 화면을 빠르게 유지 - 중간 및 대규모 리뷰에서도 브라우저의 기본 `find-in-page` 같은 동작을 보존 - **가상화를 통한 점진적 성능 저하** - 가장 큰 풀 리퀘스트에서는 한 번에 렌더링하는 콘텐츠 양을 제한 - 모든 내용을 동시에 DOM에 올리지 않아 응답성과 안정성을 우선 - **기반 컴포넌트와 렌더링 개선** - 특정 모드에 관계없이 모든 크기의 풀 리퀘스트에 누적 효과를 제공 - 렌더링 구조 자체를 단순화해 메모리와 상호작용 비용을 줄임 ## 초기 목표와 측정 지표 최적화 작업의 목표는 단순히 평균 속도를 높이는 데 그치지 않았다. - JavaScript 힙 크기와 메모리 사용량 감소 - DOM 노드 수 감소 - 평균 INP 개선 - 특히 최악의 사용자 경험을 나타내는 p95와 p99 INP 대폭 개선 - 이를 위해 상태, HTML 요소, JavaScript 코드, React 컴포넌트 수를 전반적으로 줄이는 단순화 전략을 채택 ## v1의 문제: diff 라인당 높은 렌더링 비용 React로 처음 diff 화면을 구현한 v1은 작은 재사용 컴포넌트를 많이 조합하는 구조였다. - unified 뷰의 diff 한 줄에는 최소 약 10개의 DOM 요소가 필요했다. - split 뷰에서는 한 줄당 약 15개의 DOM 요소가 필요했다. - 구문 강조를 적용하면 추가 `<span>` 요소가 더해져 DOM 수가 증가했다. - React 계층에서도 다음과 같은 컴포넌트가 생성됐다. - unified 뷰: 한 줄당 최소 8개 컴포넌트 - split 뷰: 한 줄당 최소 13개 컴포넌트 - 댓글, hover, focus 등 추가 상태가 활성화되면 컴포넌트 수는 더 늘어났다. - 작은 컴포넌트마다 React 이벤트 핸들러를 5~6개씩 연결하는 경우가 많았다. - 결과적으로 diff 한 줄에 20개 이상의 이벤트 핸들러가 붙을 수 있었고, 이를 수천 줄에 적용하면서 비용이 급격히 커졌다. v1의 한 줄당 최소 구조는 다음과 같았다. - DOM 요소 10~15개 - React 컴포넌트 8~13개 - React 이벤트 핸들러 20개 이상 - 다수의 작은 재사용 컴포넌트 이 구조는 일반적인 규모에서는 문제가 없었지만, 데이터 크기가 사실상 제한되지 않는 대규모 풀 리퀘스트에서는 변경 줄 수가 늘수록 INP와 JavaScript 힙 사용량이 함께 악화됐다. ## v2의 방향: 작은 변경을 대규모로 누적 v2에서는 눈에 띄지 않는 HTML 구조까지 점검해 diff 라인당 비용을 줄였다. - 줄 번호 셀에 불필요하게 포함되어 있던 `<code>` 태그를 제거했다. - diff 한 줄에서 DOM 노드 2개를 줄이는 것은 개별적으로는 작은 개선처럼 보인다. - 그러나 10,000줄을 렌더링하면 DOM 노드 20,000개를 제거하는 효과가 발생한다. - 이처럼 줄 단위의 사소한 최적화도 대규모 데이터에서는 메모리 사용량과 렌더링 비용에 크게 누적된다. - 성능 개선에서는 큰 기능 변경만큼 불필요한 태그, 컴포넌트, 이벤트 핸들러를 하나씩 제거하는 작업도 중요하다. ## 실용적인 결론 대규모 목록이나 코드 diff를 렌더링할 때는 처음부터 최악의 데이터 규모를 고려해야 한다. 컴포넌트를 잘게 나누는 구조가 유지보수에는 유리할 수 있지만, 각 요소에 상태와 이벤트 핸들러를 추가하면 수천 개 항목에서 큰 비용이 된다. 따라서 DOM 구조를 단순화하고, 항목별 렌더링 비용을 측정하며, 극단적인 규모에는 가상화를 적용하는 조합이 효과적이다.

figma

Figma Make에서 더 많은 맥락과 제어력으로 빌드하기 | Figma Blog (새 탭에서 열림)

Figma Make가 **Make kits**와 **Make attachments**를 통해 디자인 시스템과 실제 프로젝트 자료를 반영한 프로토타입을 생성하도록 개선됐다. Make kits는 코드 패키지나 Figma 라이브러리의 컴포넌트·스타일·토큰과 사용 지침을 제공하고, attachments는 데이터·법률 문구·스크린샷 등 프로젝트별 맥락을 전달한다. 이를 통해 범용적인 초안에서 출발해 반복적으로 수정하는 대신, 실제 제품 구조와 제약에 가까운 결과물을 더 빠르게 만들 수 있다. ## AI 초안이 실제 제품과 어긋나는 문제 - 기존 AI 생성 UI는 레이아웃과 인터랙션은 그럴듯하지만 다음과 같은 문제가 있었다. - 팀의 실제 디자인 시스템 컴포넌트를 사용하지 않음 - 카피가 placeholder로 남음 - 예외 상황과 중요한 edge case가 반영되지 않음 - 프로덕션 코드의 구조와 다른 방식으로 구현됨 - 그 결과 초기 생성 속도는 빨라도, 리뷰 전에 디자인 시스템에 맞게 다시 작성하고 조정하는 데 많은 시간이 필요했다. - Figma는 이 문제의 원인을 생성 품질 자체가 아니라 **팀이 실제 개발에 사용하는 맥락의 부족**으로 설명한다. ## Make kits: 디자인 시스템을 학습시키는 패키지 - Make kit은 디자인 시스템의 컴포넌트나 스타일과, 이를 어떻게 사용해야 하는지 설명하는 세부 가이드라인을 하나의 재사용 가능한 패키지로 결합한다. - 다음과 같은 소스를 사용할 수 있다. - 공개 npm 레지스트리의 JavaScript 패키지 - Figma의 보안 비공개 레지스트리에 저장된 코드 패키지 - Figma 라이브러리의 스타일과 디자인 토큰 - 가이드라인은 단순히 “어떤 컴포넌트가 존재하는가”뿐 아니라 다음까지 전달한다. - 컴포넌트를 어떤 상황에 사용해야 하는지 - 컴포넌트가 어떤 구조와 패턴을 따라야 하는지 - 디자인 시스템의 규칙을 프로토타입에 어떻게 적용해야 하는지 - 따라서 Make는 일반적인 UI 요소를 조합하는 대신, 팀의 코드베이스와 가까운 구조로 프로토타입을 시작할 수 있다. ## Make kits가 팀 협업에 주는 효과 - 폼, 대시보드, 설정 화면, 온보딩 플로우 등 여러 팀이 공유하는 화면에서 일관성이 높아진다. - 여러 팀이 동시에 프로토타입을 제작해도 디자인 시스템에서 벗어날 가능성이 줄어든다. - 리뷰 전에 spacing, 컴포넌트 선택, UI 패턴을 다시 맞추는 작업이 감소한다. - 엔지니어 입장에서는 익숙한 컴포넌트와 코드 패턴을 바로 확인할 수 있다. - “이 부분은 커스텀 구현인가?”와 같은 확인 질문이 줄어들어, 디자인을 코드로 번역하는 시간보다 제안 자체를 검토하고 개선하는 데 집중할 수 있다. - Figma는 향후 Figma 라이브러리의 컴포넌트 구조를 더욱 정확히 재현하는 방향으로 Make kits를 발전시킬 계획이다. ## Make attachments: 프로젝트의 실제 맥락 반영 - 디자인 시스템만으로는 각 프로젝트의 고유한 요구사항을 모두 설명할 수 없다. - 실제 프로젝트에는 다음과 같은 정보가 추가로 필요하다. - 실제 사용자 데이터 - 마이그레이션 제약 - 예외 처리와 edge case - 규정 및 컴플라이언스 요구사항 - 브랜드 콘텐츠와 법률 문구 - Make attachments는 이런 자료를 긴 프롬프트로 요약하지 않고 원본 파일 형태로 Make에 전달한다. - 지원되는 자료에는 다음이 포함된다. - PDF와 Markdown 문서 - CSV·JSON 데이터셋 - 스크린샷과 이미지 - 브랜드 가이드라인 - 법률 문구 - 미디어 파일과 SVG - 코드 및 관련 프로젝트 파일 ## 실제 데이터와 제약을 반영하는 프로토타이핑 - 예를 들어 디지털 제품의 전체 온보딩 플로우를 만들 때는 다음 정보가 동시에 필요할 수 있다. - 실제 사용자 데이터 - 법률상 반드시 표시해야 하는 문구 - 여러 입력 검증 상태 - 정상 흐름 외의 예외 상황 - 첨부 파일 없이 프롬프트만 사용하면 Make가 법률 문구를 임의로 줄이거나, 검증 상태를 단순화하거나, 이상적인 정상 흐름만 생성할 수 있다. - 원본 PDF, 데이터셋, 스크린샷 등을 첨부하면 Make가 프로젝트 자료를 직접 참조하므로, 보다 현실적인 콘텐츠와 제약을 포함한 프로토타입을 만들 수 있다. ## 디자인 시스템과 프로젝트 자료의 결합 - Make kits는 **제품 전반에 공통으로 적용되는 규칙**을 제공한다. - Make attachments는 **특정 프로젝트에만 존재하는 데이터와 제약**을 제공한다. - 두 기능을 함께 사용하면 다음과 같은 흐름이 가능하다. - Make kits로 실제 코드 또는 Figma 라이브러리 기반의 컴포넌트 사용 - attachments로 실제 데이터, 콘텐츠, 법률 요구사항, 시각 자료 반영 - 생성 결과를 프로덕션 구조에 가깝게 유지하면서 프로젝트의 세부 조건까지 검증 - 결과적으로 프로토타입 제작은 “일반적인 UI 초안 생성”에서 “실제 제품 조건을 반영한 탐색과 검증”으로 이동한다. 실무에서는 공통 컴포넌트와 토큰을 Make kit으로 정리하고, 기능별 요구사항·데이터·법률 문구·예외 상태는 attachments로 함께 제공하는 방식이 효과적이다. 이렇게 하면 생성 후 대규모 수정에 쓰는 시간을 줄이고, 초기 단계부터 개발·디자인 리뷰에 적합한 프로토타입을 만들 수 있다.

cloudflare

Cloudflare 클라이언트 측 보안: 더 스마트해진 탐지, 이제 누구나 이용 가능 (새 탭에서 열림)

Cloudflare는 클라이언트 사이드 보안(Client-Side Security) 기술을 모든 사용자에게 개방하고, 고도화된 스키밍 공격을 탐지하기 위해 대규모 언어 모델(LLM)을 결합한 새로운 AI 탐지 시스템을 도입했습니다. 이번 업데이트를 통해 셀프 서비스 고객도 'Advanced' 기능을 사용할 수 있게 되었으며, 특히 오탐지(False Positive)를 획기적으로 줄이면서도 복잡한 자바스크립트 공격에 대응할 수 있는 다중 방어 체계를 구축한 것이 핵심입니다. **클라이언트 사이드 보안의 작동 원리** * **브라우저 보고 기반 탐지:** 별도의 스캐너나 애플리케이션 수정 없이, 브라우저의 콘텐츠 보안 정책(CSP) 보고 기능을 활용해 신호를 수집하므로 지연 시간이 발생하지 않습니다. * **폭넓은 접근성:** 모든 무료 플랜 사용자에게 도메인 기반 위협 인텔리전스를 제공하며, 유료 셀프 서비스 고객은 코드 변경 모니터링 및 능동적 차단 규칙이 포함된 Advanced 기능을 즉시 사용할 수 있습니다. * **컴플라이언스 지원:** 지속적인 코드 변경 탐지 기능을 통해 PCI DSS v4(요구사항 11.6.1)와 같은 최신 보안 규정을 준수할 수 있도록 돕습니다. **추상 구문 트리(AST)와 의도 분석** * **데이터 규모와 변동성 관리:** 기업당 평균 2,200개의 고유 스크립트가 존재하며 그중 33%가 매달 업데이트되는 환경에서, 단순한 수동 승인이 아닌 스크립트의 '의도'를 파악하는 방식에 집중합니다. * **구조적 패턴 분석:** 자바스크립트 코드를 AST로 분해하여 논리적 구조를 분석함으로써, 변수명 변경이나 코드 난독화 여부와 관계없이 공격자의 패턴을 식별합니다. **GNN과 LLM을 결합한 하이브리드 탐지 아키텍처** * **GNN 기반 1차 선별:** 그래프 신경망(GNN)이 AST의 구조적 특성을 학습하여 제로데이 위협을 높은 재현율(Recall)로 빠르게 걸러냅니다. * **LLM 기반 2차 검증:** 0.3% 미만의 낮은 오탐율조차 일일 35억 건의 데이터 규모에서는 막대한 노이즈가 되므로, Cloudflare Workers AI에서 실행되는 LLM이 2차 판단을 내립니다. * **계층적 분류 알고리즘:** 모든 스크립트를 LLM으로 분석하는 대신, GNN이 의심스럽다고 판단한 항목만 LLM에 전달하는 '계단식 구조'를 통해 성능 최적화와 정확도 향상을 동시에 달성했습니다. **오탐지 해결을 위한 시맨틱 이해** * **복잡한 코드 구분:** 봇 차단 솔루션이나 광고 트래킹 스크립트처럼 난독화되어 있지만 정상적인 코드를 LLM의 심층적인 문맥 이해력을 통해 공격 코드로 오인하지 않도록 분류합니다. * **보안 팀의 피로도 감소:** 정확도가 낮은 경보를 획기적으로 줄임으로써, 보안 담당자가 실제 위협적인 침해 사고에만 집중할 수 있는 환경을 제공합니다. 웹사이트를 운영하는 조직은 Cloudflare의 새로운 Advanced 기능을 활용해 PCI DSS v4 준수 요건을 충족하는 동시에, 복잡해지는 공급망 공격(Supply Chain Attack)으로부터 사용자 데이터를 보호할 수 있습니다. 특히 난독화된 서드파티 스크립트가 많은 환경이라면, LLM 기반의 고도화된 탐지 엔진을 적용해 보안과 운영 효율성을 모두 확보할 것을 권장합니다.

cloudflare

추상 구문 트리(AST)를 사용하여 워크플로 코드를 시각적 다이어그램으로 변환하는 방법 (새 탭에서 열림)

Cloudflare Workflows는 코드로 작성된 복잡한 실행 로직을 추상 구문 트리(AST) 분석을 통해 시각적인 다이어그램으로 변환하여 제공합니다. 기존의 선언적 방식(JSON, YAML)과 달리 자유로운 코드 작성이 가능한 동적 실행 모델을 채택하고 있어, 정적 분석을 통해 비동기 관계와 실행 흐름을 파악하는 것이 핵심입니다. 이를 통해 개발자는 병렬 처리, 루프, 조건문이 포함된 복잡한 워크플로우의 구조를 대시보드에서 한눈에 파악하고 검증할 수 있습니다. ### 동적 실행 모델과 시각화의 도전 과제 * Cloudflare Workflows는 순차적인 정적 실행이 아닌, 런타임이 코드를 읽으며 단계를 만날 때마다 엔진에 실행을 넘기는 동적 모델을 따릅니다. * `await`를 사용하지 않은 단계(step)들은 기본적으로 병렬로 실행되며, 엔진은 실행 시점에 전체 경로를 미리 알 수 없기 때문에 시각화를 위한 별도의 분석이 필요합니다. * 개발자가 작성한 유연한 제어 흐름(Promise.all, 루프, 중첩 함수 등)을 정확한 그래프 형태로 표현하기 위해 정적 분석 기술이 도입되었습니다. ### AST를 활용한 코드 파싱 및 그래프 생성 * 워크플로우 배포 시점에 스크립트를 캡처하여 추상 구문 트리(AST)로 파싱하고, 전체 구조를 분석하는 과정을 거칩니다. * 코드 내에서 `Promise`와 `await` 사이의 관계를 추적하여, 어떤 작업이 블로킹(Blocking)되는지 또는 병렬로 연결되는지를 식별합니다. * 내부 서비스를 통해 `WorkflowEntrypoints`와 각 단계(step) 호출을 연결하는 중간 그래프를 생성한 뒤, 이를 기반으로 최종 다이어그램을 렌더링합니다. ### 번들링 및 압축된 코드의 처리 * 배포되는 코드는 보통 esbuild와 같은 번들러에 의해 압축(Minify) 및 변형되어 가독성이 매우 낮은 상태가 됩니다. * 난독화된 JavaScript 코드 내에서도 `step.do`와 같은 핵심 호출 패턴을 정확히 찾아내어 워크플로우의 논리적 단계를 복구합니다. * 번들러마다 다른 압축 방식에도 대응할 수 있도록 AST 기반의 탐색 로직을 최적화하여, 복잡한 비동기 에이전트 로직도 정확하게 시각화합니다. 개발자는 이제 AI 에이전트나 복잡한 데이터 파이프라인을 코드로 작성한 후, 대시보드에서 자동으로 생성된 다이어그램을 통해 로직의 의도대로 흐름이 구성되었는지 즉시 확인할 수 있습니다. 시각화된 그래프는 코드 가독성을 보완하며, 특히 비동기 병렬 작업이 많은 워크플로우의 디버깅과 관리에 유용합니다.

cloudflare

AI 에이전트 샌드박싱, 100배 더 빠르게 (새 탭에서 열림)

Cloudflare는 AI 에이전트가 생성한 코드를 안전하고 신속하게 실행할 수 있는 'Dynamic Worker Loader' API를 공개했습니다. 이 기술은 기존 컨테이너 방식보다 100배 빠른 실행 속도와 뛰어난 메모리 효율성을 제공하여, 수백만 명의 사용자를 대상으로 하는 대규모 AI 에이전트 서비스의 보안 및 성능 문제를 해결합니다. 개발자는 이를 통해 AI가 작성한 코드를 독립된 V8 Isolate 환경에서 즉시 실행하고, TypeScript 인터페이스를 통해 효율적으로 도구(Tool)를 연동할 수 있습니다. ### 기존 컨테이너 기반 샌드박스의 한계 * AI가 생성한 코드를 직접 실행(eval)하는 것은 보안상 매우 위험하므로 격리된 샌드박스 환경이 필수적입니다. * 기존의 리눅스 기반 컨테이너 샌드박스는 부팅에 수백 밀리초(ms)가 소요되고 수백 메가바이트(MB)의 메모리를 점유하여 비용이 많이 듭니다. * 지연 시간을 줄이기 위해 컨테이너를 미리 띄워두는 방식은 자원 낭비가 심하며, 컨테이너를 재사용할 경우 보안성이 취약해지는 딜레마가 있습니다. ### V8 Isolate 기반의 'Dynamic Worker Loader' * Cloudflare는 구글 크롬에서 사용하는 V8 엔진의 격리 기술인 'Isolate'를 활용해 런타임에 워커를 즉시 생성하는 API를 제공합니다. * Isolate 기술은 실행에 단 몇 밀리초만 소요되며 수 메가바이트의 메모리만 사용하므로, 컨테이너 대비 속도는 100배 빠르고 메모리 효율은 10~100배 더 뛰어납니다. * 모든 유료 워커 사용자는 이 API를 통해 요청마다 독립된 샌드박스를 생성하고, 실행이 끝나면 즉시 폐기하는 방식을 비용 효율적으로 구현할 수 있습니다. ### 무한한 확장성과 제로 레이턴시 * 동적 워커 로더는 전역 동시 실행 수나 생성 속도에 제한이 없어, 초당 수백만 건의 요청이 발생하는 대규모 트래픽도 안정적으로 처리할 수 있습니다. * 샌드박스가 코드를 호출한 워커와 동일한 머신 혹은 동일한 스레드 내에서 실행되므로, 전 세계 어느 지역에서든 네트워크 지연 없이 즉각적인 코드 실행이 가능합니다. * 특정 API에 대한 접근 권한을 부여하거나 외부 인터넷 접속을 차단하는 등 세밀한 보안 제어가 가능합니다. ### AI 친화적인 TypeScript 도구 정의 * AI 에이전트는 이미 자바스크립트와 타입스크립트에 능숙하며, 이러한 언어들은 태생적으로 웹 샌드박스 환경에 최적화되어 있습니다. * 장황한 OpenAPI 명세 대신 간결한 TypeScript 인터페이스를 사용하여 에이전트에게 API 도구를 설명함으로써 토큰 사용량을 80% 이상 절감할 수 있습니다. * `env.LOADER.load()` 함수를 통해 생성된 워커에 RPC(Remote Procedure Call) 스텁을 전달하여 에이전트가 안전하게 외부 기능을 호출하도록 설계되었습니다. 대규모 AI 에이전트 서비스를 구축하려는 개발자에게 Cloudflare의 Dynamic Worker Loader는 최적의 선택지입니다. 기존의 무거운 컨테이너 방식에서 벗어나 V8 Isolate 기반의 가벼운 샌드박스를 채택하고, 도구 정의를 TypeScript로 전환함으로써 성능 최적화와 비용 절감을 동시에 달성할 수 있습니다.

cloudflare

립트에는 더 나 (새 탭에서 열림)

현재의 WHATWG 스트림 표준(Web Streams)은 설계된 지 10년이 지나 현대적인 JavaScript 개발 방식과 동떨어져 있으며, 심각한 사용성 및 성능 문제를 안고 있습니다. 비동기 반복문(`for await...of`)이 도입되기 전에 수립된 이 API는 불필요하게 복잡한 리더/라이터 모델과 잠금(locking) 메커니즘에 의존하고 있어, 현대적 언어 기능을 활용한 대안적인 접근 방식을 통해 최대 120배까지 성능을 개선할 수 있다는 것이 핵심 주장입니다. **역사적 배경과 설계의 시대적 한계** - Web Streams 표준은 2014~2016년 사이에 개발되었으며, 이는 JavaScript의 비동기 반복문(`for await...of`)이 등장(2018년)하기 훨씬 전의 일입니다. - 당시에는 비동기 시퀀스를 처리하는 관용적인 방법이 없었기 때문에, 표준은 리더와 라이터를 획득하고 관리하는 독자적인 모델을 구축해야만 했습니다. - 결과적으로 Node.js와 같은 서버 사이드 런타임들은 호환성을 위해 나중에 이 복잡한 표준을 도입하게 되었고, 이는 현대적인 JavaScript 개발 흐름과 충돌하는 원인이 되었습니다. **과도한 상용구 코드와 사용성 저하** - 스트림을 끝까지 읽는 단순한 작업조차 리더 획득, `read()`의 반복 호출, `{ value, done }` 프로토콜 처리, 그리고 `finally` 블록을 통한 명시적인 잠금 해제 등 복잡한 과정을 거쳐야 합니다. - 나중에 비동기 반복문이 지원되기는 했으나, 이는 기존의 복잡한 구조 위에 덧씌워진 형태에 불과하여 BYOB(Bring Your Own Buffer) 같은 세부적인 기능을 제대로 활용할 수 없는 한계가 있습니다. - 개발자들은 여전히 내부의 리더, 잠금, 컨트롤러 구조를 이해해야 하며, 문제 발생 시 추상화 뒤에 숨은 복잡성 때문에 디버깅에 어려움을 겪습니다. **수동 잠금(Locking) 모델의 치명적 결함** - Web Streams는 다중 소비자의 간섭을 막기 위해 독점적 잠금 모델을 사용하지만, 이를 관리하는 방식이 매우 위험합니다. - `getReader()`를 통해 잠긴 스트림은 반드시 `releaseLock()`을 호출해야 하며, 이를 잊을 경우 스트림이 영구적으로 잠겨 파이프나 취소 등 다른 모든 작업을 수행할 수 없게 됩니다. - 잠금 상태(`locked`)에 대한 정보는 제공되지만, 누가 왜 잠갔는지 혹은 잠금이 유효한지에 대한 구체적인 맥락을 알 수 없어 운영 환경에서의 실수를 유발하기 쉽습니다. **현대적 대안을 통한 비약적인 성능 향상** - 저자가 제시하는 대안적인 접근 방식은 JavaScript 언어 자체의 원시 기능을 활용하며, 기존 Web Streams 대비 모든 런타임(Node.js, Deno, Bun, 브라우저 등)에서 2배에서 최대 120배 빠른 성능을 보입니다. - 이러한 성능 차이는 단순한 최적화의 결과가 아니라, 10년 전의 낡은 설계 결정을 현대적인 JavaScript 패턴에 맞게 근본적으로 다시 설계함으로써 얻어진 결과입니다. 개발자들은 이제 기존 Web Streams의 복잡한 수동 관리 방식에서 벗어나, 현대적인 비동기 반복 기반의 더 직관적이고 효율적인 스트림 API로의 전환을 논의해야 할 시점에 와 있습니다.