webgl

12 개의 포스트

figma

Figma 렌더링: Web (새 탭에서 열림)

Figma는 기존 WebGL 렌더러를 WebGPU 기반으로 확장해 GPU 병렬 처리와 더 명확한 오류 처리, 새로운 렌더링 최적화 기회를 확보했다. 다만 단순히 API를 교체하는 방식으로는 성능 향상을 보장할 수 없었기 때문에, WebGL 호환성을 유지하면서 그래픽 인터페이스와 셰이더·버퍼 처리 방식을 함께 재설계했다. 이 과정은 성능 회귀와 기능 중단을 피하기 위해 단계적으로 진행됐다. ## WebGL에서 WebGPU로 전환한 배경 - Figma는 2015년부터 브라우저에서 무한 캔버스를 구현하기 위해 WebGL을 사용했다. - 당시 WebGL은 3D 중심 API였지만, Figma는 이를 복잡한 2D 디자인 도구에도 적용할 수 있다고 판단했다. - 2023년 Chromium에 WebGPU 지원이 추가되면서 WebGL에서는 어려웠던 최적화가 가능해졌다. - 특히 컴퓨트 셰이더를 활용해 CPU 작업을 GPU의 대규모 병렬 처리로 옮길 수 있다. - WebGPU는 WebGL의 전역 상태 중심 구조보다 오류 처리가 명확하고, 상태 관리로 인한 버그도 줄일 수 있다. ## 드로 콜 인자를 명시적으로 관리 - 기존 WebGL 방식은 버텍스 버퍼, 텍스처, 머티리얼, 프레임버퍼 등을 전역 바인딩 지점에 먼저 연결한 뒤 `draw()`를 호출했다. - 바인딩된 리소스는 이후에도 유지되므로, 일부 입력을 갱신하지 않아 이전 상태가 남는 문제가 발생할 수 있었다. - Figma는 다음처럼 드로 콜에 필요한 리소스를 함수 인자로 직접 전달하도록 인터페이스를 변경했다. ```cpp context->draw(vertexBuffer, framebuffer, {texture}, material, …); ``` - WebGL 구현에서는 필요한 경우에만 실제 바인딩을 갱신하도록 지연 업데이트를 적용했다. - 이 변경은 WebGPU 도입 전에도 입력 누락으로 발생하던 WebGL 렌더러의 버그를 해결했다. - 각 드로 콜의 의존성이 코드에 명확히 드러나므로 유지보수성과 안정성도 향상됐다. ## GLSL과 WGSL을 함께 지원하는 셰이더 처리 - 셰이더는 GPU에서 실행되어 최종 픽셀을 생성하는 프로그램이다. - WebGL은 GLSL을 사용하지만 WebGPU는 WGSL을 사용하므로, 기존 GLSL 셰이더를 모두 WGSL로 수동 변환하면 두 버전을 중복 관리해야 했다. - Figma의 기존 셰이더는 WebGL 1용 구형 GLSL 형식이어서 일반적인 변환 도구만으로는 처리하기 어려웠다. - Figma는 자체 셰이더 프로세서와 오픈소스 도구 `naga`를 조합했다. - 기존 GLSL을 파싱한다. - 최신 GLSL 구조에 맞게 필요한 변환을 수행한다. - `naga`를 이용해 WGSL로 변환한다. - 최종적으로 GLSL과 WGSL을 모두 생성한다. - 변환 과정에서 셰이더 입력 타입과 데이터 레이아웃 같은 메타데이터도 추출해 애플리케이션에서 활용한다. - 파일 include 기능도 제공해 셰이더 코드의 모듈화와 재사용성을 높였다. ## WebGPU에 맞춘 유니폼 버퍼 설계 - 유니폼은 셰이더에 전달되는 전역 변수와 같은 데이터로, 색상이나 변환 행렬 등을 전달하는 데 사용된다. - WebGL에서는 각 유니폼을 개별적으로 설정할 수 있었다. ```javascript gl.uniform1f(locationAlpha, alphaValue); gl.uniformMatrix3fv(locationTransform, false, transformValue); ``` - Figma의 기존 인터페이스도 이 모델을 따라 유니폼을 하나씩 설정했다. - 그러나 WebGPU에서는 유니폼을 개별 호출로 전달할 수 없고, 여러 값을 하나의 유니폼 버퍼에 기록한 뒤 GPU에 한 번에 업로드해야 한다. - 따라서 WebGL API를 그대로 흉내 내 WebGPU를 구현하면 호출 오버헤드와 데이터 업로드 비용 때문에 성능이 오히려 저하될 수 있다. - WebGPU 전환의 핵심은 API 이름을 바꾸는 것이 아니라, 버퍼 레이아웃과 데이터 업로드 방식을 GPU 친화적으로 재설계하는 데 있다. ## 실용적인 결론 WebGPU 도입은 단순한 렌더링 API 교체가 아니라 상태 관리, 셰이더 컴파일, 유니폼 버퍼 구조까지 재설계하는 작업이다. 기존 API와의 호환성을 유지하되 드로 콜의 입력을 명시적으로 만들고, 셰이더 변환을 자동화하며, GPU 버퍼 단위로 데이터를 처리해야 성능과 안정성을 함께 확보할 수 있다.

figma

딜런 필드가 전하는 (새 탭에서 열림)

Figma의 성장에는 창업자 Dylan Field의 다양한 경험과 우연한 계기, 그리고 실패에서 배우는 태도가 영향을 미쳤다. 아역 배우 시절의 경험, 수학적 사고를 키워준 멘토, 독특한 Thiel Fellowship 지원서, 초기 아이디어의 방황, 젊은 CEO로서의 시행착오가 Figma의 창업과 발전에 연결됐다. 글은 성공이 단번에 완성되는 것이 아니라 끈기와 실험, 성장 과정을 통해 만들어진다는 점을 보여준다. ## 배우 경험이 길러준 끈기 - Dylan은 1990년대 후반 캘리포니아 소노마 카운티에서 아역 배우로 활동했다. - Peter Pan 공연 중 무대에서 잠든 일은 본인이 꼽는 가장 당황스러운 연기 경험이었다. - 하지만 공연에서 얻은 와이어 비행 경험 덕분에 훗날 Windows XP 광고에 출연할 수 있었다. - 오디션 경험을 통해 “오랜 시간 계속 시도하는 사람이 결국 이긴다”는 태도를 배웠다. ## 학교 관리인이 키운 수학적 호기심 - Dylan은 6살 때부터 대수 문제를 풀 정도로 수학에 관심이 많았다. - 중학교 수업이 지루해 학교 관리인과 시간을 보내곤 했다. - 수학과 물리학에 관심이 많았던 관리인은 Dylan에게 여러 개념을 설명해 주었다. - 특히 단순 계산보다 증명이 중요하다며 집합론을 공부해 보라고 권했다. - 이 경험은 Dylan이 수학을 공식 암기가 아니라 논리와 구조를 탐구하는 학문으로 바라보는 데 영향을 주었다. ## 초콜릿에 대한 괴상한 답변과 Thiel Fellowship - Thiel Fellowship 지원서는 “대부분의 사람들이 무엇을 잘못 생각하고 있는가”를 물었다. - Dylan은 “초콜릿은 역겹다”라고 답하고, 그 주장을 진지하게 논증하는 에세이를 작성했다. - 일반적인 통념을 뒤집으면서도 유머와 논리를 결합한 답변이 심사위원의 관심을 끌었을 가능성이 있다. - Dylan은 이를 실리콘밸리의 반(反)주류 사고를 다시 뒤집은 “메타-contrarian” 접근이라고 설명했다. - Fellowship을 받으면서 Brown University를 중퇴하고 Evan Wallace와 함께 창업에 전념하게 됐다. ## WebGL을 활용하려다 만든 밈 생성기 - Dylan과 Evan은 WebGL을 이용해 웹에서 고성능 그래픽을 구현하는 디자인 도구를 만들고 싶어 했다. - 그러나 기술을 먼저 확보한 뒤 용도를 찾으려 하면서 방향을 잃었다. - 한때 WebGL이라는 “망치”에 맞는 “못”으로 밈 생성기를 고려했다. - Dylan은 밈 시장의 성장 데이터를 근거로 밈 제작 서비스를 만들자고 주장했다. - 이 아이디어는 약 5일간 이어졌지만, 두 사람은 곧 더 본질적인 제품을 만들어야 한다는 결론에 도달했다. - 이 짧은 방황은 Figma가 초기부터 명확한 제품 비전을 가지고 출발한 것은 아니었음을 보여준다. ## 스무 살 CEO로서의 성장통 - Dylan은 이전 직함이 인턴이었을 정도로 어린 나이에 CEO가 됐다. - 제품 경험의 세부 사항을 직접 고민해 왔기 때문에 초기에는 모든 일을 통제하려는 경향이 있었다. - 본인도 당시의 경영 방식을 “마이크로매니징”이라고 표현했다. - 빠르게 제품을 출시해야 한다는 압박감이 통제 욕구를 더욱 키웠다. - 이후 사무실에서의 긴장된 상황 등을 겪으며, 제품에 대한 높은 기준과 팀에 대한 신뢰 사이의 균형을 배워갔다. - 공개된 내용에서는 Figma의 UI를 만들기 위해 드롭다운, 컴포넌트, 효과 등을 화이트보드에 반복적으로 탐색한 과정도 소개된다. Figma의 사례는 창업자의 이력이 반드시 한 방향으로만 이어질 필요는 없다는 점을 보여준다. 낯선 경험에서 얻은 끈기와 논리적 사고, 과감한 실험, 초기의 실패를 인정하고 방향을 수정하는 태도가 새로운 제품을 만드는 데 실질적인 자산이 될 수 있다.

figma

개발자가 다시 크리에이 (새 탭에서 열림)

웹은 템플릿과 자동화 덕분에 누구나 쉽게 만들 수 있게 되었지만, 그 과정에서 사이트의 개성과 창의성이 약해졌다. 저자는 브라우저가 컨테이너 쿼리, OKLCH 색상, 고급 애니메이션과 레이아웃 등 훨씬 강력한 창작 기능을 갖추었으므로, 개발자들이 다시 창의적 코딩을 통해 웹의 표현 가능성을 확장해야 한다고 주장한다. 결론적으로 템플릿은 완성품이 아니라 출발점이며, 개발자는 실험과 표현을 통해 웹을 하나의 창작 매체로 되살려야 한다. ## 템플릿 이전의 창의적인 웹 - 2010년경 맞춤형 웹사이트는 개발자의 기술과 감각을 보여주는 디지털 명함이었다. - HTML5의 발전으로 다음과 같은 실험적인 작업이 가능했다. - 표현력 높은 인라인 SVG - GSAP 기반 타임라인 애니메이션 - WebGL 실험 - 복잡한 CSS 일러스트레이션 - 당시 개발자는 단순히 기능을 구현하는 것을 넘어, 독창적이고 유머러스한 경험을 직접 만들었다. ## 템플릿과 자동화가 가져온 변화 - Wix, Squarespace 같은 서비스는 애니메이션, 배경 영상, 패럴랙스, CMS를 누구나 사용할 수 있게 만들었다. - 웹 제작의 접근성이 크게 높아진 점은 긍정적이다. - 그러나 비슷한 템플릿이 반복되면서 사이트가 예측 가능해지고, 놀라움과 개성이 줄어들었다. - 저자는 “손으로 만든 것이 항상 더 낫다”는 감정적 주장만으로는 부족하며, 이제는 실제 웹의 창작 가능성을 다시 탐색해야 한다고 본다. ## 현대 브라우저의 숨은 가능성 - 브라우저는 과거보다 훨씬 정교한 기능을 지원하지만, 많은 디자이너와 개발자는 여전히 예전 방식에 머물러 있다. - 활용할 수 있는 현대 CSS 및 웹 기능은 다음과 같다. - 컨테이너 쿼리 - 고급 스코핑과 상속 제어 - 사용자의 선호도에 반응하는 스타일 - 동적 단위와 반응형 레이아웃 - 발전된 색상, 타이포그래피, 애니메이션 기능 - 디자인 도구의 기본 기능만 사용하는 대신, 브라우저 자체가 제공하는 표현력을 직접 활용해야 한다. ## 색상 공간과 디자인·개발의 융합 - 일반적인 RGB 그라디언트 외에도 CSS는 HSL과 OKLCH 같은 색상 공간을 지원한다. - 이러한 색상 공간은 더 생생하고 정밀한 색상 전환을 가능하게 한다. - 저자는 디자인 도구와 실제 CSS 사이의 차이를 줄이기 위해 `color-mix()`를 활용한 Figma 플러그인을 만들었다. - 디자인과 개발의 경계가 가까워질수록 개발자는 디자인 도구 안에서도 더 많은 창작 권한과 실험 공간을 가질 수 있다. ## 창의적 웹의 사례 - Henry Desroches는 인쇄물 같은 여백, 입체감, 의도적인 배치를 반응형 웹에 구현한다. - Sarah Drasner는 SVG 애니메이션과 웹 일러스트레이션의 가능성을 보여준다. - Tim Holman은 `Optical Toys`, `The Useless Web`처럼 실용성을 넘어선 실험적 프로젝트를 만든다. - Lynn Fisher는 브라우저 너비에 따라 일러스트레이션이 변하는 작업을 통해 화면 자체를 창작 매체로 활용한다. - 이 사례들은 템플릿이 최종 결과가 아니라, 창의적인 작업을 시작하기 위한 기반임을 보여준다. 웹사이트는 정보 전달이나 서비스 제공을 위한 그릇에만 머물 필요가 없다. 개발자는 최신 브라우저 기능을 적극적으로 실험하고, CSS·SVG·WebGL·애니메이션을 조합해 자신만의 표현 방식을 만들어볼 필요가 있다. નાના한 시각 효과나 인터랙션부터 시작해 템플릿 너머의 웹을 구축하는 것이 실용적인 출발점이다.

figma

역할이 규칙이 아닌 이유 (새 탭에서 열림)

제품 개발이 협업 중심으로 바뀌면서 엔지니어의 역할은 정해진 요구사항을 구현하는 데서 벗어나, 무엇을 만들지까지 함께 결정하는 방향으로 확장되고 있다. 하지만 협업과 피드백을 항상 늘리는 것이 정답은 아니며, 다양한 의견을 탐색하는 단계와 결정을 내리고 추진하는 단계 사이의 균형이 중요하다. Figma는 역할을 고정된 규칙으로 보지 않고, 초기부터 폭넓게 협업하되 마일스톤을 통해 적절한 시점에 수렴하는 방식을 택한다. ## 엔지니어 역할의 확장 - 웹 기술의 발전과 Google Docs 같은 협업 도구의 확산, 원격·하이브리드 근무의 증가로 제품은 점점 “멀티플레이어 기본값”이 되었다. - 제품 개발은 더 이상 디자인에서 시작해 엔지니어링으로 끝나는 선형적인 과정이 아니다. - 엔지니어는 단순히 구현 방법(how)을 결정하는 사람이 아니라, 고객 피드백과 제품·디자인 동료의 의견을 바탕으로 만들 대상(what)도 함께 정의한다. - 따라서 직무의 경계를 엄격한 규칙으로 보기보다, 필요한 순간 서로의 영역을 넘나드는 협업 방식이 요구된다. ## 협업과 독립성 사이의 균형 - 다른 사람의 지식을 활용하는 것과, 방향 없이 계속 논의만 반복하는 것은 다르다. - 모든 작업에서 항상 최대한 많은 사람의 피드백을 받으면 품질이 높아질 것 같지만, 오히려 결정이 늦어지고 프로젝트가 제자리걸음할 수 있다. - 독립적으로 집중해야 하는 시기와 적극적으로 다른 팀을 끌어들여야 하는 시기는 작업마다 다르다. - 적절한 균형은 조직 문화, 제품의 특성, 팀이 최적화하려는 목표에 따라 달라진다. ## 초기 아이디어를 공개하는 방식 - 새로운 업무를 시작할 때는 가능한 한 이른 시점부터 다양한 관점을 반영한다. - 엔지니어는 완성된 설계가 아니라 초기의 생각과 가설을 문서로 작성해야 한다. - 문서는 “완성 후 검토”를 위한 산출물이 아니라, 작업 중인 상태에서 피드백을 받기 위한 협업 도구다. - 대부분의 프로젝트에 초기 생각을 기록하는 문서가 존재하지만, 각 팀이 바쁜 상황에서도 빠르게 피드백을 주고받을 수 있는 구조가 필요하다. ## 엔지니어링 크리트: 승인보다 피드백 - Figma는 디자인·엔지니어링 조직 간 정기적인 엔지니어링 크리트(crit)를 운영한다. - 크리트의 목적은 다음과 같다. - 기술 설계를 초기에 공유한다. - 다른 팀으로부터 자주 피드백을 받는다. - 전문적인 기술 지원과 문제 제기를 얻는다. - 크리트는 승인 회의가 아니다. - 회의에서 최종 결정을 내리거나 작업을 확정하지 않는다. - 작업 중인 상태(WIP)를 전제로 문제를 지적한다. - 설계 자체가 충분히 발전해 별도의 승인을 필요로 하지 않도록 돕는다. - Figma는 FigJam을 사용해 실시간으로 참여하고 의견을 시각적으로 공유한다. ## 너무 많은 의견이 만드는 정체 - 다양한 의견은 유용하지만, 입력이 지나치게 많거나 서로 충돌하면 프로젝트가 방향을 잃을 수 있다. - 특히 가격 정책처럼 불확실성과 중요한 트레이드오프가 많은 문제에서는 아이디어가 계속 추가되면서 결정을 내리지 못할 위험이 크다. - 탐색적이고 생성적인 논의만 계속하면 프로젝트가 앞으로 나아가지 못한다. - 협업의 목표는 모든 의견을 반영하는 것이 아니라, 더 나은 결정을 내릴 수 있을 만큼 설계를 발전시키는 데 있다. ## 마일스톤을 통한 수렴 - Figma는 프로젝트를 여러 마일스톤으로 나누어 탐색과 실행의 시점을 구분한다. - 마일스톤을 명확히 정의하고 공유하면 다음과 같은 효과가 있다. - 이해관계자의 기대치를 관리할 수 있다. - 현재 단계에서 무엇을 결정해야 하는지 분명해진다. - 계속 확장하기보다 수렴해야 할 시점을 알 수 있다. - 프로젝트가 진전되려면 다양한 가능성을 열어두는 단계와, 하나의 방향을 선택해 추진하는 단계가 모두 필요하다. - 추진력(momentum)이 유지되면 목표에 가까워지고 있다는 감각을 얻지만, 추진력을 잃으면 프로젝트의 방향과 목적 자체를 다시 의심하게 된다. ## 실용적인 적용 - 초기 설계와 가설을 완성되기 전에 문서로 공유한다. - 피드백 회의는 승인 절차가 아니라 문제를 조기에 발견하는 자리로 운영한다. - 모든 의견을 반영하려 하지 말고, 마일스톤마다 탐색을 멈추고 결정을 내릴 시점을 명확히 한다. - 역할과 책임을 고정된 경계로 보지 않되, 최종적으로는 누가 어떤 결정을 내리고 실행할지 분명히 해야 한다.

figma

60fps의 React: Figma (새 탭에서 열림)

Figma는 캔버스에서 댓글 핀이 이동할 때 발생하던 불필요한 React 렌더링을 줄여 스크롤 성능을 약 3배 개선했다. 댓글 수와 무관하게 편집기를 60fps에 가깝게 동작시키는 것이 목표였으며, Chrome Performance 도구와 React Profiler로 병목이 JavaScript 실행과 컴포넌트 재렌더링에 있음을 확인했다. 핵심 해결책은 뷰포트 변화에 실제로 영향을 받는 댓글 컴포넌트만 업데이트하고, 댓글 위치 계산과 변환 처리를 최적화하는 것이었다. ## 60fps를 목표로 한 댓글 스크롤 - Figma의 댓글은 캔버스 위 특정 위치에 고정된 “댓글 핀”으로 표시된다. - 사용자가 캔버스를 이동하거나 확대·축소하면 댓글 핀도 뷰포트에 맞춰 계속 위치를 다시 계산해야 한다. - 15fps나 30fps보다 60fps가 훨씬 부드러운 사용자 경험을 제공하므로, 댓글과 스레드가 많아져도 일정한 성능을 유지하는 것이 목표였다. - 댓글 사용량이 증가하면서 대규모 팀과 파일에서 캔버스 반응성이 저하되기 시작했다. ## WebGL 캔버스와 React 댓글 UI의 구조 - Figma 편집기는 WebGL과 WebAssembly를 사용하는 “브라우저 안의 브라우저”에 가까운 구조다. - 일부 사용자 인터페이스는 TypeScript와 React로 구현되어 있지만, 일반적인 정적 React 화면과 달리 댓글은 캔버스의 이동과 확대·축소에 따라 동적으로 움직인다. - 편집기의 뷰포트 정보는 Redux에 저장된다. - 댓글 핀 컴포넌트는 Redux에서 뷰포트 정보를 가져와 캔버스 좌표를 화면에 표시할 위치로 변환한다. - 뷰포트가 변경될 때마다 React 컴포넌트 트리 일부가 업데이트되므로, 업데이트 범위가 성능에 직접적인 영향을 준다. ## 성능 분석에서 발견한 병목 - Chrome Performance 도구에서 대부분의 프레임 시간이 렌더링이나 페인팅이 아니라 JavaScript 실행에 사용되는 것으로 나타났다. - 댓글 30개인 화면에서 프레임당 약 68ms가 JavaScript에 소비되었고, 실제 화면은 약 19fps로 렌더링됐다. - React Profiler에서는 댓글 화면 자체의 렌더링에는 약 1.8ms만 사용되고 있었다. - 대신 뷰포트 변화와 직접 관련 없는 다음 컴포넌트들이 함께 재렌더링됐다. - 왼쪽 패널 - 툴바 - 속성 패널 - 기타 고정 위치 UI - 즉, 댓글 내용 렌더링보다 “변화가 없는 컴포넌트까지 다시 렌더링하는 것”이 더 큰 비효율이었다. ## 불필요한 재렌더링 줄이기 - 뷰포트 업데이트는 댓글 핀의 위치에는 필요하지만, 화면에 고정된 패널이나 툴바에는 필요하지 않다. - 따라서 뷰포트 상태를 사용하는 컴포넌트의 범위를 댓글 영역으로 제한해야 한다. - React 애플리케이션이 커질수록 상위 컴포넌트의 상태 변화가 하위 전체로 전파되면서 불필요한 렌더링이 발생하기 쉽다. - React Profiler로 실제로 다시 렌더링되는 컴포넌트를 확인하면, 직관만으로 찾기 어려운 병목을 구체적으로 식별할 수 있다. - 성능 개선은 댓글 컴포넌트 자체를 빠르게 만드는 것뿐 아니라, 댓글과 무관한 컴포넌트가 업데이트되지 않도록 컴포넌트 구조와 상태 구독 방식을 조정하는 데서 시작됐다. ## 댓글 핀 위치 변환 최적화 - 댓글 핀은 뷰포트가 바뀔 때마다 캔버스 좌표를 화면 좌표로 변환해야 한다. - 이 변환 과정이 매 업데이트마다 React 렌더링과 결합되면 JavaScript 실행 비용이 커질 수 있다. - Figma는 불필요한 컴포넌트 업데이트를 제거한 뒤 댓글 핀의 변환 처리도 최적화해, 캔버스 이동 중 위치 계산과 화면 반영 비용을 줄였다. - 결과적으로 댓글 스크롤 FPS가 기존보다 약 3배 향상됐다. ## 실용적인 결론 - React 성능 문제에서는 먼저 “컴포넌트 하나의 렌더링 속도”보다 “불필요하게 다시 렌더링되는 컴포넌트가 무엇인지”를 확인하는 것이 효과적이다. - Chrome Performance 도구로 프레임별 JavaScript 비용을 확인하고, React Profiler로 재렌더링 범위를 분석하는 조합이 유용하다. - 자주 변하는 상태는 실제로 그 상태가 필요한 컴포넌트 가까이에 두고, 고정 UI가 동적 상태 변화에 구독되지 않도록 설계하는 것이 좋다.

figma

웹에서 플러그인 시스템 (새 탭에서 열림)

Figma는 서드파티 플러그인을 브라우저 기반 디자인 편집기 안에서 실행하면서도 보안·안정성·성능을 모두 확보해야 했다. 단순히 `eval(PLUGIN_CODE)`를 사용하는 것은 위험하고, 기존 플러그인처럼 플랫폼 성능을 저하시키거나 업데이트 때마다 깨지는 문제도 피해야 했다. 여러 접근을 검토한 결과, 당시에는 JavaScript `Realm` 기반 샌드박스를 선택했지만, 이후 보안 취약점 공개를 계기로 C로 작성된 JavaScript VM을 WebAssembly로 컴파일하는 방식으로 변경했다. ## 플러그인 시스템이 해결해야 할 제약 - 플러그인은 접근성 검사, 번역, 색상 도구, 이미지 가져오기 등 사용자가 작성한 임의의 코드를 실행한다. - 플러그인이 Figma 편집기의 내부 데이터와 기능을 사용해야 하므로, 단순한 외부 웹페이지처럼 완전히 격리할 수는 없다. - 동시에 플러그인이 다음 영역에 영향을 주면 안 된다. - Figma 문서나 다른 사용자의 데이터에 대한 무단 접근 - 편집기 UI와 실행 환경의 안정성 - CPU·메모리 등 시스템 자원의 과도한 사용 - Figma 업데이트에 따른 플러그인 호환성 저하 - Figma는 WebGL, WebAssembly, TypeScript, React, 실시간 협업 기능을 함께 사용하는 구조라 일반적인 웹 애플리케이션보다 실행 환경이 복잡했다. ## 시도 1: `<iframe>` 샌드박스 - 가장 표준적이고 검증된 웹 보안 기능인 `<iframe>`을 플러그인 실행 환경으로 검토했다. - iframe은 별도의 문서와 JavaScript 실행 컨텍스트를 제공해 플러그인 코드가 Figma의 전역 객체나 DOM에 직접 접근하지 못하게 할 수 있다. - `sandbox` 속성과 출처(origin) 분리를 사용하면 플러그인과 호스트 애플리케이션 사이의 경계를 강화할 수 있다. - 플러그인과 Figma 사이의 통신은 `postMessage` 같은 명시적인 메시지 전달 방식으로 제한할 수 있다. - 그러나 iframe 방식에는 중요한 한계가 있었다. - Figma 내부 데이터 구조에 대한 빠르고 자연스러운 접근이 어렵다. - 플러그인 API 호출을 위해 많은 객체와 요청을 직렬화·전달해야 한다. - 별도 브라우저 컨텍스트를 만들기 때문에 성능과 메모리 비용이 발생한다. - iframe 자체가 안전하더라도 플러그인이 CPU나 메모리를 과도하게 사용해 편집기를 느리게 만들 가능성은 남는다. - 따라서 일반적인 웹 위젯에는 적합하지만, Figma처럼 고성능 편집기와 긴밀하게 상호작용해야 하는 플러그인 환경에는 충분하지 않았다. ## 시도 2: JavaScript 인터프리터를 WebAssembly로 컴파일 - 두 번째 접근은 플러그인 코드를 브라우저의 JavaScript 엔진에서 직접 실행하지 않고, 별도의 JavaScript 인터프리터 안에서 실행하는 방식이었다. - 인터프리터를 WebAssembly로 컴파일하면 플러그인 코드는 Figma의 실제 JavaScript 환경과 분리된 가상 실행 환경에서 동작한다. - 이 방식의 장점은 다음과 같다. - 플러그인이 브라우저의 전역 객체, DOM, Figma 내부 구현에 직접 접근할 수 없다. - 노출할 API를 명시적으로 선택할 수 있다. - 실행 환경을 통제하고 향후 브라우저 변경의 영향을 줄일 수 있다. - 반면 별도의 JavaScript 인터프리터를 실행해야 하므로 일반 JavaScript보다 느릴 수 있다. - 표준 JavaScript 기능과 내장 객체를 정확하게 구현해야 하며, 언어 호환성 문제도 발생한다. - 인터프리터 자체의 구현 오류나 보안 취약점이 샌드박스를 무너뜨릴 가능성도 고려해야 했다. - 당시에는 성능과 구현 복잡성이 주요 장애물이었다. ## 시도 3: JavaScript Realm - 세 번째 접근은 별도의 전역 환경과 객체 영역을 만드는 `Realm` 개념이었다. - Realm은 플러그인이 Figma의 전역 객체와 분리된 JavaScript 환경에서 실행되도록 하면서도, 필요한 API만 선택적으로 제공할 수 있게 한다. - iframe보다 가볍고, 별도 JavaScript 인터프리터를 내장하는 방식보다 브라우저의 기본 실행 성능을 더 많이 활용할 수 있다. - Figma는 다음과 같은 형태의 경계를 구성할 수 있었다. - 플러그인에 필요한 API만 노출 - 호스트 객체와 플러그인 객체 사이의 직접 참조 제한 - 허용된 요청만 Figma 내부 기능으로 전달 - 플러그인 전역 환경과 Figma 전역 환경의 분리 - 이 접근은 보안, 성능, API 사용성 사이의 균형이 가장 좋다고 판단되어 원래 구현에 채택됐다. - 다만 Realm은 당시 표준 기능으로 완전히 지원된 것이 아니라 shim에 의존해야 했다. - JavaScript 객체 모델과 프로토타입 체인을 완벽하게 격리하는 것은 매우 어려워, shim의 작은 결함도 보안 취약점으로 이어질 수 있었다. ## 운영 과정에서 드러난 보안 문제와 변경 - 글 게시 후 Realm shim에서 보안 취약점이 비공개로 제보됐다. - 취약점은 공개되기 전에 shim 팀에 의해 수정됐고, Figma는 실제 악용 증거를 발견하지 못했다고 밝혔다. - 그러나 샌드박스의 핵심이 외부 라이브러리의 복잡한 JavaScript 격리에 의존한다는 점은 중요한 위험 요소였다. - Figma는 이후 C로 작성된 JavaScript VM을 WebAssembly로 컴파일하는 대안으로 구현을 변경했다. - 이 방식은 브라우저의 JavaScript 객체와 실행 컨텍스트를 더 강하게 분리해, Realm shim에 의존하는 공격 표면을 줄이는 방향이다. ## 설계에서 얻은 교훈 - 서드파티 코드를 안전하게 실행하는 문제는 단순히 `eval`을 다른 API로 바꾸는 문제가 아니다. - 격리 수준, API 호출 비용, 실행 성능, 자원 제한, 유지보수성을 함께 평가해야 한다. - “브라우저 기능을 사용하므로 자동으로 안전하다”거나 “샌드박스이므로 모든 문제가 해결된다”고 볼 수 없다. - 특히 샌드박스 구현 자체가 복잡한 경우, 해당 구현의 취약점과 업데이트 정책까지 시스템의 보안 경계로 봐야 한다. - 가장 현실적인 설계는 플러그인에 필요한 최소 API만 노출하고, 실행 환경과 호스트 애플리케이션 사이의 통신을 명확한 경계로 제한하는 것이다. 플러그인 시스템을 설계할 때는 iframe, 별도 인터프리터, Realm 같은 선택지를 보안·성능·호환성 관점에서 비교해야 한다. 또한 외부 샌드박스 라이브러리에 의존한다면 정기적인 보안 검토와 교체 가능한 구조를 마련하고, 높은 보안 수준이 필요할 경우 WebAssembly 기반 독립 VM처럼 더 강한 실행 격리를 고려하는 것이 바람직하다.

figma

크롬북에서 처음 (새 탭에서 열림)

Chromebook에서도 클라우드 기반 도구를 활용하면 전문 디자이너의 업무를 처음부터 끝까지 수행할 수 있다는 글이다. 저자는 Figma와 웹 기반 생산성 도구 덕분에 성능이나 협업에서 큰 불편을 겪지 않았으며, 오히려 자동 저장·동기화와 비용 절감의 이점을 강조한다. 다만 사용자 정의 글꼴, 인터넷 연결, 영상·음원 편집처럼 로컬 환경이 필요한 작업에는 여전히 제약이 있다. ## Chromebook을 선택한 이유 - Square가 보안성, 저렴한 비용, 자동 백업 및 동기화를 이유로 일부 직원의 Chromebook 전환을 추진했다. - 저자는 내부 프레젠테이션 작업에서 Chromebook 사용자의 환경을 직접 이해하기 위해 Mac 대신 Chromebook을 선택했다. - 이미 Figma를 3년간 사용하고 있었기 때문에, 디자인 파일과 주요 작업이 클라우드에 저장되는 환경에 익숙했다. - 1년간 전문 디자이너로 Chromebook을 사용한 뒤, 다시 Mac으로 돌아갈 필요를 느끼지 못했다고 평가한다. ## Chrome OS에서 디자인할 때 알아둘 점 - **Figma의 클라우드 기반 구조** - Figma는 브라우저에서 실행되는 전문 디자인·프로토타이핑 도구다. - Chromebook에서 디자인하려면 사실상 Figma 같은 클라우드 기반 도구가 필수적이다. - **키보드 단축키** - Chrome OS의 `Control` 키가 macOS의 `Command` 키와 비슷한 역할을 한다. - `Search` 키는 Caps Lock 대신 배치되어 있으며, 보조 키로 사용할 수 있다. - 예를 들어 Figma에서 `Search + 드래그`를 사용하면 객체를 복제할 수 있다. - Figma의 단축키 메뉴는 현재 운영체제에 맞는 단축키를 표시하며, `Ctrl + Shift + /`로 열 수 있다. - **성능** - 저자가 사용한 세 대의 Chromebook에서 Figma 성능 문제를 경험하지 않았다. - Figma가 브라우저에서 빠르게 작동하기 때문에 고성능 데스크톱 환경이 반드시 필요한 것은 아니라고 설명한다. - **웹 기반 보조 도구** - Slack, Grammarly, 접근성 테스트 도구 Funkify, G Suite 등이 모두 웹에서 작동한다. - 따라서 디자인 외 업무도 대부분 Chromebook에서 처리할 수 있다. - **제약 사항** - 당시 Chrome OS에서는 사용자 정의 글꼴을 직접 설치할 수 없었다. - 대신 Google Fonts의 다양한 글꼴을 사용할 수 있다. - 인터넷 연결이 제한되면 일부 기능을 사용하기 어렵지만, Chromebook은 오프라인에서도 일정 수준의 기능을 제공한다. - **터치스크린** - 긴 문서나 Slack 대화를 스크롤하거나 Figma 캔버스를 탐색할 때 터치스크린이 유용했다. ## 디자이너에게 적합한 Chromebook 선택 - 저자는 HP Chromebook과 Samsung Pro를 거친 뒤 Google Pixelbook을 가장 선호하게 됐다. - Pixelbook은 당시 999달러부터 시작하는 고가 Chrome 기기였지만, 이전에 사용하던 MacBook Pro 가격의 3분의 1 이하 수준이었다. - 저렴한 Chromebook이나 HDMI 스틱형 컴퓨터인 85달러짜리 Chromebit도 선택지로 언급한다. - 최종적으로 Pixelbook을 선택한 이유는 키보드와 트랙패드의 품질이었다. - 디자인 작업에서는 화면뿐 아니라 입력 장치의 사용감도 장시간 작업 효율에 큰 영향을 준다는 점을 보여준다. ## 클라우드 기반 디자인 작업 흐름 ### 제작 - Figma: 디자인 및 프로토타이핑 - SuperHi: 웹사이트 코드 편집 - Google Slides, Figma, Paste: 프레젠테이션 제작 - Grammarly, Google Docs, Dropbox Paper: 문서 작성 및 교정 ### 업무 관리와 재무 - Asana, Google Tasks: 할 일과 프로젝트 관리 - Bonsai: 회계 업무 - Notion: 재무 관리 - 1Password X: 비밀번호 관리와 보안 ### 커뮤니케이션 - Signal, Telegram, Slack: 메시징 - Slack, Google Meet: 회의와 화상 통화 ### 음악과 멀티미디어 - Spotify, Pocket Casts: 음악과 팟캐스트 - 영상·음원 편집은 Final Cut Pro와 Logic Pro를 사용할 수 있는 Mac에서 처리했다. - 저자는 향후 영상·음원 편집도 웹 기반 대안으로 대체될 가능성이 높다고 전망한다. ## 소프트웨어가 웹으로 이동하는 이유 - 클라우드 도구를 사용하면 파일을 별도로 백업하거나 저장할 필요가 줄어든다. - 브라우저만 있으면 여러 장소와 기기에서 동일한 파일에 접근할 수 있다. - 작업물이 특정 컴퓨터에 묶이지 않으므로 기기 고장이나 분실에 따른 위험도 낮아진다. - 웹 기술의 발전으로 브라우저에서도 실시간 렌더링과 물리 효과 같은 고급 기능을 구현할 수 있게 됐다. - Figma는 WebGL을 활용한 실시간 3D 렌더링 실험에서 출발했으며, 이는 브라우저가 전문 소프트웨어를 실행할 수 있음을 보여주는 사례로 제시된다. - 웹은 운영체제나 앱스토어에 덜 종속되고, 누구나 접근하고 개발할 수 있다는 점에서 개방성과 접근성이 높다. Chromebook 전환을 고려한다면 Figma처럼 클라우드 기반인 핵심 도구와 Slack·Docs·Notion 같은 웹 서비스를 중심으로 업무 환경을 구성하는 것이 좋다. 반면 사용자 정의 글꼴이나 전문 영상·음원 편집이 중요하다면 해당 작업을 위한 별도 장비나 대체 도구를 함께 준비해야 한다.

figma

Electron용 BrowserView 소개 | Figma 블 (새 탭에서 열림)

Figma는 Electron에서 원격 웹 앱을 임베드할 때 사용하던 `<webview>`의 성능·안정성 문제를 해결하기 위해 `BrowserView`를 개발했다. `BrowserView`는 DOM 계층이 아닌 운영체제 창 계층에서 웹 콘텐츠를 관리해 Chrome 탭에 가까운 성능과 안정성을 제공한다. 다만 HTML/CSS 기반의 자동 배치와 레이어링을 사용할 수 없어 위치와 겹침을 직접 관리해야 하며, Figma는 이를 데스크톱 앱 2.0에 적용했다. ## Electron과 Figma의 웹 기반 데스크톱 전략 - Figma는 접근성이 뛰어난 웹을 주요 플랫폼으로 선택했다. - 파일 공유가 링크 하나로 가능하다는 점이 큰 장점이다. - 웹 앱의 성능을 네이티브 애플리케이션 수준으로 끌어올리기 위해 다음 기술을 활용했다. - WebGL 기반 캔버스 렌더링 - WebAssembly를 통한 앱 로딩 시간 개선 - 데스크톱 앱에는 웹 기술로 크로스플랫폼 애플리케이션을 만들 수 있는 Electron을 사용했다. - Figma는 Electron의 성능과 버그를 개선하기 위해 Chromium 및 Electron 프로젝트에도 지속적으로 기여했다. ## `<webview>` 기반 임베딩의 한계 - Electron 창에서 원격 웹 앱을 삽입하는 기존 표준 방식은 `<webview>`였다. - `<webview>`는 `<iframe>`과 유사하지만, 콘텐츠를 별도 프로세스에서 렌더링한다. - 일반 iframe보다 성능, 보안, 안정성 측면에서 유리하다. - 그러나 Figma가 실제 사용 과정에서 다음 문제를 겪었다. - 드래그 앤 드롭 같은 기본 기능의 버그 - Chrome에 미치지 못하는 전반적인 성능 - 시간이 지날수록 증가하는 호환성과 안정성 문제 - `<webview>`는 Chromium 내부에서 구현되므로 Electron 측에서 직접 근본 문제를 해결하기 어려웠다. - Chromium을 크게 수정하는 것은 현실적으로 부담이 크기 때문에, Electron 팀과 Figma는 `<webview>`를 우회하는 대안을 선택했다. ## `BrowserView`의 구조와 장점 - `BrowserView`는 웹 콘텐츠를 DOM 계층에 포함하지 않고 운영체제의 창 계층에 배치한다. - 구조적으로 Chrome이 브라우저 탭을 관리하는 방식과 유사하다. - 이 방식의 장점은 다음과 같다. - `<webview>`에 특화된 버그를 상당 부분 피할 수 있다. - Chrome 탭과 동일한 렌더링 경로를 활용해 웹 앱이 Chrome 수준의 속도로 동작한다. - Chrome에서 중요하게 취급되는 창·탭 관련 문제를 더 빠르게 수정할 수 있다. - 결과적으로 Electron 앱 안에서 원격 웹 앱을 더 빠르고 안정적으로 실행할 수 있다. ## 레이아웃과 레이어링의 trade-off - `BrowserView`는 DOM 요소가 아니므로 일반적인 HTML/CSS 레이아웃 기능을 사용할 수 없다. - CSS의 위치 지정 - DOM 기반의 자동 크기 조정 - 요소 간 z-index 및 레이어링 - 애플리케이션이 직접 다음 작업을 처리해야 한다. - 각 `BrowserView`의 위치와 크기 계산 - 여러 뷰의 겹침 순서 관리 - 창 크기 변경에 따른 수동 레이아웃 갱신 - 복잡한 위치 배치나 레이어 구성이 핵심인 애플리케이션에서는 이 제약이 큰 단점이 될 수 있다. - 반면 Figma처럼 구조가 비교적 명확한 앱에서는 전환 작업이 충분히 실용적이었다. ## 출시와 향후 계획 - `BrowserView`는 당시 최신 Electron 베타 버전에 실험적 API로 포함됐다. - Figma는 이를 적용한 Figma Desktop 2.0을 출시했다. - Figma는 Electron과 BrowserView가 아직 완벽하지 않지만 빠르게 발전하고 있다고 평가했다. - 다른 기업과 개발자들도 Electron 개선에 참여하고 있으며, Figma는 더 많은 앱이 BrowserView로 이전하기를 기대했다. 실용적으로는 원격 웹 앱을 Electron에 임베드하면서 `<webview>`의 성능이나 버그가 문제가 된다면 `BrowserView`를 검토할 수 있다. 다만 도입 전 수동 레이아웃과 레이어링 구현 부담, 당시 실험적 API라는 안정성 문제를 함께 평가해야 한다.

figma

피그마는 웹어 (새 탭에서 열림)

WebAssembly 도입으로 Figma는 애플리케이션 초기화, 디자인 파일 다운로드, 첫 렌더링을 포함한 전체 로드 시간을 약 3배 단축했다. 특히 C++ 기반 코드를 브라우저에서 실행할 때 asm.js보다 전송·파싱·네이티브 코드 변환·캐싱 측면에서 유리했다. 다만 압축 후 다운로드 크기 감소 효과는 작았고, 당시에는 브라우저별 구현 및 캐싱 지원 차이로 적용 범위가 제한됐다. ## WebAssembly의 특징과 asm.js와의 차이 - WebAssembly는 브라우저 실행을 위해 설계된 바이너리 형식의 머신 코드다. - 기존에는 C++ 코드를 asm.js라는 JavaScript 부분집합으로 변환해 실행했다. - 숫자와 포인터만 사용할 수 있으며, 포인터는 숫자 배열의 인덱스로 표현된다. - DOM 조작이나 네트워크 연결 등 브라우저 기능은 JavaScript를 호출해야 한다. - WebAssembly도 asm.js와 동일한 제약과 브라우저 샌드박스를 공유하지만, 실행 형식이 더 효율적이다. - C++처럼 이미 LLVM으로 최적화된 코드는 브라우저가 별도 최적화를 많이 수행하지 않고 네이티브 코드로 변환할 수 있다. ## WebAssembly가 빠른 이유 - **작은 바이너리 형식** - 동일한 코드의 JavaScript보다 네트워크 전송에 유리하다. - 다만 압축하면 asm.js와 WebAssembly의 크기 차이는 크게 줄어든다. - **빠른 파싱** - 사람이 작성하는 JavaScript에는 문법과 중복 정보가 많다. - WebAssembly는 브라우저가 빠르게 해석하도록 설계되어 asm.js보다 약 20배 빠르게 파싱된다. - **효율적인 네이티브 코드 변환** - LLVM이 사전에 C++ 코드를 최적화하므로 브라우저의 런타임 최적화 부담이 작다. - **변환 결과 캐싱** - 브라우저가 WebAssembly 모듈의 네이티브 코드 변환 결과를 쉽게 캐시할 수 있다. - 같은 애플리케이션을 다시 열 때 변환 시간이 거의 사라질 수 있다. - **64비트 정수 지원** - WebAssembly는 64비트 정수를 직접 지원한다. - JavaScript는 정수 정밀도가 53비트로 제한되어 64비트 정수를 에뮬레이션해야 한다. ## Figma에서의 적용과 성능 개선 - Figma는 C++로 작성된 대규모 2D WebGL 렌더링 엔진을 사용한다. - 측정한 로드 시간에는 다음 과정이 모두 포함됐다. - 애플리케이션 초기화 - 디자인 파일 다운로드 - 디자인의 최초 전체 렌더링 - WebAssembly로 전환한 뒤 문서 크기와 관계없이 로드 시간이 3배 이상 개선됐다. - 큰 디자인 문서를 자주 만들고 전환하는 Figma 사용자에게 특히 큰 효과가 있었다. - 앱을 한 번 실행한 뒤에는 WebAssembly의 네이티브 변환 결과가 캐시되므로, 이후 로드 시간은 애플리케이션 코드 크기에 덜 영향을 받는다. ## 다운로드 크기와 실제 개선의 차이 - WebAssembly로 전환하면 전송 크기도 크게 줄어들 것으로 예상했지만 실제 감소 폭은 작았다. - asm.js 코드도 압축하면 WebAssembly와 비슷한 크기까지 줄어들기 때문이다. - 따라서 Figma에서 가장 큰 이점은 파일 크기 감소가 아니라 파싱, 코드 변환, 캐싱에 따른 실행 및 로드 시간 단축이었다. ## 브라우저 지원의 한계 - 당시 WebAssembly는 Firefox와 Chrome에서 기본 활성화되어 있었다. - Edge와 Safari는 아직 구현 중이어서 브라우저별 지원 상황을 확인해야 했다. - Figma는 Chrome에서도 WebAssembly를 사용할 수 있었지만, 구현상의 문제 때문에 실제로는 Firefox에서만 활성화했다. - 특히 Chrome의 네이티브 변환 코드 캐싱 방식이 Firefox와 달라 페이지를 열 때마다 애플리케이션 전체를 다시 변환해야 하는 문제가 있었다. WebAssembly는 대규모 C/C++ 코드베이스를 웹으로 옮길 때 특히 효과적이다. 단순히 다운로드 용량을 줄이는 기술이라기보다, 빠른 파싱과 네이티브 코드 변환, 실행 결과 캐싱을 통해 초기 로드 시간을 줄이는 기술로 보는 것이 적절하다.

figma

Emscripten으로 데이터 (새 탭에서 열림)

Figma의 저장 파일이 간헐적으로 손상되는 문제는 재현이 어려운 비결정적 이벤트와 C++의 메모리 안전성 문제 때문에 장기간 해결되지 않았다. 일반적인 메모리 디버깅 도구로 원인을 찾지 못한 뒤, 키보드·마우스 입력을 생성하는 퍼저로 이벤트를 반복 실행해 문제를 재현하는 데 성공했다. 최종 수정은 FlatBuffers의 잘못된 메모리 접근을 고치는 세 줄짜리 커밋이었지만, 원인을 추적하는 과정에서 Emscripten과 브라우저의 메모리 모델까지 분석해야 했다. ## 간헐적으로 발생한 저장 파일 손상 - Figma는 때때로 다시 읽을 수 없는 잘못된 저장 파일을 생성했다. - 당시 저장 형식은 다음 구조였다. - ZIP 파일 - 내부에 Google FlatBuffers로 인코딩된 문서 - 파일의 전체 바이트 구조는 대체로 정상처럼 보였지만, 뒤쪽 데이터를 가리키는 일부 오프셋이 0으로 변해 있었다. - 데이터가 원래 위치가 아닌 곳에 기록된 현상은 다음과 같은 메모리 안전성 위반을 의심하게 했다. - 초기화되지 않은 메모리 사용 - 해제된 메모리 접근(use-after-free) - 배열 범위를 벗어난 읽기·쓰기 ## C++ 메모리 오류의 추적 난이도 - Figma 에디터는 C++로 작성되어 있었다. - C++는 다음과 같은 장점 때문에 그래픽 소프트웨어에 적합하다. - FreeType, HarfBuzz, Skia 같은 저수준 라이브러리 활용 - 하드웨어와 직접 연결되는 언어 기능 - 성숙한 디버깅 및 최적화 도구 - 높은 성능과 세밀한 메모리 제어 - 반면 C++는 언어 자체가 메모리 안전성을 보장하지 않는다. - 복잡한 언어 설계, 오류가 발생하기 쉬운 표준 라이브러리 API, C에서 물려받은 레거시가 결합되어 대규모 프로젝트에서 메모리 오류를 완전히 피하기 어렵다. ## 일반적인 디버깅 방법의 한계 개발팀은 다음과 같은 방법을 시도했지만 문제를 발견하지 못했다. - 메모리를 해제하지 않아 use-after-free 가능성 제거 - macOS의 malloc 디버깅 옵션 활성화 - Valgrind가 보고한 모든 문제 수정 - 컴파일러 업그레이드 - Clang 정적 분석기가 발견한 문제 수정 이런 도구들은 많은 오류를 찾아내지만, 실행 조건에 따라 드물게 발생하거나 특정 메모리 배치에서만 나타나는 문제까지 항상 잡아내지는 못한다. ## 이벤트 기록과 퍼징으로 재현성 확보 - 문제의 핵심은 비동기 타이머와 네트워크 이벤트 등 웹 앱의 비결정성이었다. - 해결 전략은 다음과 같았다. - 사용자 이벤트를 기록한다. - 동일한 이벤트를 순서대로 재생한다. - 문제가 발생할 때까지 세션을 반복 실행한다. - 이벤트를 무작위로 제거하면서도 문제가 유지되는 최소 테스트 케이스를 만든다. - 실제 사용자 세션에는 너무 다양한 이벤트가 포함되므로, 범위를 키보드와 마우스 이벤트로 제한했다. - 실제 세션을 수집하는 대신 퍼저가 무작위 키보드·마우스 입력을 생성하도록 했다. - 며칠 동안 실행한 결과 여러 건의 저장 실패를 재현할 수 있었고, 이후 반복 가능한 입력 시퀀스를 기반으로 본격적인 디버깅이 가능해졌다. ## Emscripten이 C++를 브라우저에서 실행하는 방식 - Figma는 플러그인 없이 브라우저에서 실행되는 웹 앱이다. - C++ 코드는 Emscripten을 통해 JavaScript로 컴파일된다. - JavaScript는 기본적으로 메모리 안전성과 가비지 컬렉션을 제공하지만, WebGL과 Typed Arrays 덕분에 C의 메모리 모델을 흉내 낼 수 있다. - Typed Array의 특징은 다음과 같다. - 고정된 크기를 가진다. - 모든 원소가 같은 타입이다. - 여러 Typed Array가 하나의 ArrayBuffer를 공유할 수 있다. - 같은 메모리를 `Float32Array`와 `Uint8Array` 등 서로 다른 타입으로 해석할 수 있기 때문에 C/C++의 포인터 캐스팅과 유사한 동작을 구현할 수 있다. ## Emscripten의 포인터와 메모리 변환 Emscripten은 C++의 주요 요소를 JavaScript 구조로 변환한다. - 포인터 읽기: Typed Array 읽기 - 포인터 쓰기: Typed Array 쓰기 - 레지스터: JavaScript 지역 변수 - 스택: `STACKTOP`이라는 스택 포인터로 관리 - 타입 변환: 동일한 ArrayBuffer를 공유하는 Typed Array를 통해 구현 - 생성된 코드는 asm.js라는 제한적인 JavaScript 부분집합을 사용해 JIT 컴파일러가 타입을 추론하고 빠르게 최적화하도록 한다. - 예를 들어 `+$value`는 값을 double로 취급하도록 JIT에 힌트를 주며, 비트 연산은 정수 연산으로 최적화될 가능성을 높인다. ## 실용적인 결론 재현이 어려운 데이터 손상 문제는 도구를 하나씩 추가하는 것만으로 해결되지 않을 수 있다. 비결정적 입력을 통제하고, 퍼징과 이벤트 재생으로 실패 조건을 반복 가능하게 만드는 것이 핵심이며, 컴파일된 실행 환경에서는 원본 언어뿐 아니라 Emscripten의 메모리 모델과 런타임 동작까지 함께 이해해야 한다.

figma

웹에서 전문적인 디자인 도구 (새 탭에서 열림)

Figma는 전문 디자이너가 받아들일 수 있는 고품질 편집 경험을 웹 브라우저에서 제공하기 위해, 사실상 “브라우저 안의 브라우저”를 구축했다. 웹 플랫폼의 제한적인 추상화 대신 WebGL·asm.js 같은 저수준 기술을 활용하고, C++ 기반 편집기와 자체 메모리·렌더링 시스템으로 성능과 플랫폼 간 일관성을 확보했다. 특히 Emscripten을 통해 네이티브에 가까운 성능과 예측 가능한 프레임률을 달성하는 것이 핵심 전략이다. ## 웹에서 전문 디자인 도구를 만들기 어려운 이유 - 웹은 원래 문서 표시를 위해 설계되었고, 애플리케이션 개발 기능은 이후 개별 API 형태로 덧붙여졌다. - 따라서 특정 기능은 제공하지만, 개발자가 이를 조합해 새로운 동작을 구현할 수 있는 범용적인 저수준 primitive가 부족하다. - CSS는 복잡한 텍스트 배치 알고리즘을 제공하지만: - 알고리즘을 직접 커스터마이즈하기 어렵고 - 브라우저가 계산한 결과를 읽어 다른 알고리즘에 재사용하기도 어렵다. - 브라우저의 GPU 컴포지터는 고성능이지만: - 렌더링 과정에 직접 개입하기 어렵고 - 사용자 정의 블렌드 모드나 애플리케이션 특화 최적화를 추가할 수 없다. - 이미지 디코더는 하드웨어 가속과 비동기 처리를 지원하지만: - EXIF 방향 정보를 어떻게 처리할지 지정하기 어렵고 - 디스플레이 색 공간을 이미지 데이터에 미리 반영하지 않도록 제어하기 어렵다. - WebGL과 asm.js의 등장으로 개발자가 브라우저에 기능 추가를 기다리지 않고 하드웨어에 가까운 수준에서 필요한 기능을 직접 구현할 수 있게 되었다. ## Emscripten으로 C++ 편집기 실행 - Figma 편집기는 C++로 작성하고 Emscripten으로 JavaScript로 크로스 컴파일했다. - Emscripten은 asm.js를 대상으로 하며, asm.js는 JIT가 예측 가능하고 compact한 기계어를 생성하기 쉬운 JavaScript 부분집합이다. - 이 방식의 장점: - 메모리 배치를 직접 제어할 수 있어 64비트 부동소수점 중심인 JavaScript보다 32비트 float나 byte를 효율적으로 사용할 수 있다. - 객체를 미리 할당한 typed array 영역에 배치해 JavaScript 가비지 컬렉터의 개입을 피한다. - GC 중단으로 인한 프레임 저하를 줄여 60fps 달성에 유리하다. - LLVM 최적화와 C++ 템플릿 특수화를 활용해 네이티브 성능의 약 2배 이내 수준까지 접근할 수 있다. - asm.js에는 일반 JavaScript의 JIT 추론에 따른 deoptimization 지점이 없어 실행 성능이 더 예측 가능하다. ## 대용량 메모리와 브라우저 제약 대응 - Emscripten은 전체 메모리 공간을 하나의 큰 typed array에 담기 때문에 연속된 주소 공간을 충분히 확보해야 한다. - 특히 32비트 Chrome on Windows에서는 ASLR이 주소 공간을 파편화해 256MB typed array조차 할당하지 못하는 문제가 있었다. - Figma는 대형 이미지·기하 버퍼를 주 힙 외부의 별도 typed array에 저장하고, 이를 C++에서 참조하는 `IndirectBuffer` API를 만들었다. - 이 방식은: - 장시간 실행 시 메모리 파편화를 줄이고 - 32비트 브라우저의 제한된 주소 공간을 더 효율적으로 사용하며 - 64비트 브라우저의 31비트 typed array 크기 제한을 우회한다. - 해당 `IndirectBuffer` 구현은 오픈소스로 공개되었다. ## asm.js 이후의 발전 방향 - WebAssembly는 asm.js 코드를 바이너리 형식으로 표현해 JavaScript 파싱 시간을 크게 줄이는 것을 목표로 한다. - 당시 웹의 멀티스레딩은 Web Worker와 메시지 전달 방식에 의존했다. - Shared Typed Array가 도입되면 여러 실행 흐름이 메모리를 공유하는 진정한 공유 메모리 기반 멀티스레딩이 가능해질 것으로 전망했다. ## 자체 렌더링 엔진 - 브라우저의 그래픽 기능을 그대로 사용하는 대신, 콘텐츠를 빠르고 플랫폼 간 일관되게 표시하기 위해 자체 렌더링 엔진을 구현했다. - 이는 브라우저마다 다른 그래픽 구현과 동작 차이를 통제하고, 전문 디자인 도구에 필요한 고성능 렌더링을 직접 최적화하기 위한 선택이다. - 제공된 글 내용은 자체 렌더링 엔진의 필요성을 설명하는 부분에서 끝나므로, 구체적인 렌더링 구조와 최적화 기법은 확인할 수 없다. 브라우저 기반 고성능 그래픽 애플리케이션을 만들 때는 DOM과 일반 JavaScript API만으로 해결하려 하기보다, C++/WebAssembly 계열의 실행 모델과 명시적인 메모리 관리, 자체 렌더링 계층을 고려하는 것이 효과적이다. 특히 60fps가 중요한 편집 도구라면 가비지 컬렉션과 브라우저별 렌더링 차이를 구조적으로 줄이는 설계가 중요하다.

figma

디자인, 인터넷을 만나 (새 탭에서 열림)

Figma는 브라우저에서 작동하는 실시간·협업형 인터페이스 디자인 도구로 소개되었다. 창업자들은 WebGL의 발전으로 브라우저에서도 고성능 그래픽 작업이 가능해졌다고 보고, 디자인의 제작부터 공유·댓글·저장까지 하나의 온라인 환경에서 해결하려 했다. 2015년 프리뷰 출시와 함께 1,800만 달러의 투자 유치 사실도 공개했다. ## 브라우저 기반 디자인 도구의 가능성 - 창업자 Dylan Field와 Evan Wallace는 2011년 WebGL을 활용한 이미지 처리 실험에서 브라우저 기반 창작 도구의 가능성을 발견했다. - 당시에는 브라우저 성능이 부족해 창작 소프트웨어를 온라인으로 구현하기 어려웠지만, WebGL을 통해 고성능 그래픽 렌더링이 가능해졌다. - Figma는 벡터 렌더링, 폰트 레이아웃, 다양한 성능 문제를 해결하며 브라우저에서 안정적인 그래픽 도구를 구현했다. ## 디자이너 협업의 문제 - 디자이너는 다른 디자이너와 에셋을 공유하고, 마케팅 문구를 수정하며, 엔지니어에게 디자인 명세를 전달하는 등 여러 직군과 협업한다. - 엔지니어를 위한 협업 도구는 발전했지만, 디자이너의 협업 과정은 상대적으로 분절되어 있었다. - 디자인 제작, 댓글, 공유, 저장을 각각 다른 도구에서 처리해야 했으며, 전체 워크플로를 통합하는 도구가 부족했다. - Figma는 이러한 문제를 디자이너가 조직의 여러 역할을 연결하는 중심에 있다는 관점에서 해결하려 했다. ## Figma가 제공하는 협업 방식 - 링크를 통한 디자인 공유로 파일 전달 과정을 단순화한다. - 디자인 맥락에 직접 피드백을 남길 수 있다. - 팀이 함께 사용할 브랜드 색상과 같은 공유 자산을 관리할 수 있다. - 브라우저 기반 서비스이므로 별도 설치나 파일 버전 관리 없이 온라인에서 작업할 수 있다. - 내부에서 18개월 동안 실제로 사용하고 알파 고객과 협력하며 제품의 안정성과 사용성을 검증했다. ## 출시와 향후 계획 - Figma는 2015년 12월 팀을 대상으로 한 Preview Release를 시작했다. - 초기에는 사용료보다 사용자 피드백을 통해 제품 로드맵을 발전시키는 데 초점을 맞췄다. - Greylock, Index, OATV 및 여러 엔젤 투자자로부터 총 1,800만 달러를 유치했다. - 2016년 계획으로 다음 기능들이 제시되었다. - Slack 연동 강화 - 팀용 공유 에셋 라이브러리 구축 - 여러 사용자가 동시에 편집하는 멀티플레이어 기능 Figma의 출시는 디자인 도구를 데스크톱 애플리케이션에서 온라인 협업 플랫폼으로 전환하려는 시도였다. 이 글은 단순히 브라우저에서 디자인할 수 있다는 점보다, 실시간 공유와 협업을 통해 디자인 업무 전체를 통합하려는 방향이 핵심임을 보여준다.