기능 비하인드:
Figma의 오토세이브는 단순히 파일 전체를 주기적으로 디스크에 저장하는 기능이 아니다. 브라우저 기반 실시간 협업 환경에서는 대용량 문서, 단일 스레드 실행, 동시 편집, 충돌 해결이 서로 얽히기 때문에 전체 파일 대신 오프라인 이후의 변경분(delta)을 저장하는 방식이 적합하다. Figma는 이 변경분을 IndexedDB에 보관했다가 문서를 다시 열 때 최신 문서에 적용하고 서버로 업로드한다. ## 오프라인 작업에서 발생하는 데이터 손실 - 온라인 상태에서는 Figma가 변경 사항을 서버로 즉시 전송한다. - 하지만 인터넷 연결이 끊기면 변경 사항을 서버와 동기화할 수 없다. - 기존에는 브라우저 탭이나 컴퓨터가 종료되면 오프라인 상태에서 작업한 내용이 사라질 위험이 있었다. - 확장된 오토세이브 시스템은 문서가 서버와 연결되지 않은 시점부터 변경 사항을 디스크에 저장한다. - 이후 문서를 새 탭에서 열면 저장된 변경 사항을 복원하고 서버에 업로드한다. ## 전체 파일 저장 방식의 한계 - 가장 단순한 방법은 메모리에 있는 scenegraph 전체를 직렬화해 백업 파일로 저장하는 것이다. - Figma 문서는 레이어 노드 트리인 **scenegraph**로 표현된다. - 큰 파일은 압축된 바이너리 기준 수십 MB, 메모리상에서는 수백 MB까지 커질 수 있다. - 전체 scenegraph를 직렬화하는 데 수 초가 걸릴 수 있으며, 저장할 때마다 사용자가 지연을 경험하게 된다. - 직렬화 시간을 10~20배 줄여 100ms 수준으로 만들어도 브라우저 환경에서는 충분하지 않다. - JavaScript와 WASM이 기본적으로 단일 스레드에서 실행되기 때문이다. - 사용자는 저장 시마다 약 100ms의 끊김을 느낄 수 있다. - 작업을 여러 프레임에 나누어 실행할 수 있지만, 직렬화 중 사용자가 문서를 수정하면 어떤 상태를 저장해야 하는지 문제가 발생한다. - 변경되지 않는 immutable scenegraph를 사용하면 해결할 수 있지만, 애플리케이션 전반의 대규모 구조 변경이 필요하고 메모리 사용량과 쓰기 성능 저하라는 비용도 따른다. ## 실시간 협업이 만드는 저장 문제 - Figma 파일은 클라우드에 저장되고 여러 사용자가 동시에 편집할 수 있다. - 오프라인 백업 파일 전체를 서버의 기존 파일로 덮어쓰면, 다른 사용자가 이후에 만든 최신 변경 사항을 잃을 수 있다. - 백업 파일을 별도 복사본으로 남기는 방법도 충분하지 않다. - 일부 파일은 디자인 시스템의 버튼이나 모달 같은 공유 컴포넌트의 원본이기 때문이다. - 복사본을 만드는 순간 공유 자산의 원본과 실제 작업 내용이 분리될 수 있다. - 따라서 오토세이브는 단순한 파일 복구가 아니라, 협업 시스템의 변경 병합 및 충돌 해결 방식과 함께 설계되어야 한다. ## 전체 문서가 아닌 변경분 저장 - Figma는 전체 파일 대신 사용자가 오프라인이 된 이후 발생한 변경 사항만 저장한다. - 이 변경분은 기존 멀티플레이어 편집 시스템에서 이미 서버 전송 및 확인을 위해 관리하던 데이터다. - 전형적인 흐름은 다음과 같다. - 사용자가 문서를 불러온다. - 서버 연결이 끊긴다. - 사용자의 변경 사항이 메모리의 pending changes buffer에 쌓인다. - 일정한 간격으로 버퍼의 내용이 디스크에 저장된다. - 문서나 브라우저 탭이 예기치 않게 종료된다. - 사용자가 문서를 다시 연다. - 저장된 변경분을 역직렬화한다. - 최신 문서 위에 변경분을 적용한다. - 복원된 변경 사항을 서버에 업로드한다. - 최신 문서에 변경분을 적용하므로, 오래된 전체 백업으로 최신 서버 상태를 덮어쓰는 문제를 피할 수 있다. ## IndexedDB를 활용한 브라우저 저장 - 브라우저에서 대용량 데이터를 저장하기 위해 IndexedDB를 사용한다. - IndexedDB는 다음 요구사항에 적합하다. - 많은 양의 데이터 저장 - 데이터를 작은 단위로 나누어 저장 - 인덱스를 통한 빠른 접근 - 트랜잭션을 통한 데이터 무결성 보장 - pending changes는 파일별, 노드 또는 레이어별 속성 변경 집합으로 저장된다. - 노드 단위의 세분화는 저장 공간과 불필요한 입출력 사이의 균형을 맞춘다. - 변경 사항을 지나치게 잘게 나누면 각 레코드의 관리 오버헤드가 커진다. - 반대로 모든 노드의 변경 사항을 하나의 객체에 넣으면 일부 변경만 발생해도 전체 변경 집합을 다시 기록해야 하므로 불필요한 I/O가 증가한다. ## 실용적인 결론 대용량 실시간 협업 애플리케이션의 오토세이브는 전체 상태를 반복 저장하기보다 변경 로그나 delta를 안정적으로 보관하는 방식이 효과적이다. 특히 저장 데이터의 단위, 트랜잭션 처리, 최신 서버 상태에 변경분을 재적용하는 복구 절차를 함께 설계해야 성능 저하와 협업 데이터 덮어쓰기를 모두 줄일 수 있다.
원문 읽기(새 탭에서 열림)