Phoenix LiveView 1.0.0 출시
(phoenixframework.org)- Phoenix LiveView 1.0.0은 첫 커밋 이후 6년 만의 안정 릴리스로, JavaScript를 직접 많이 쓰지 않고 서버 렌더링 기반의 동적 앱을 만들려는 목표를 1.0 단계로 끌어올림
- 서버가 상태 변경에 맞춰 템플릿을 다시 렌더링하고 Phoenix Channels로 클라이언트와 통신해 실시간 검증, 장바구니 수량 변경, 스트리밍 업데이트 같은 UI를 처리함
- 초기에는 전체 HTML을 다시 보내
innerHTML을 교체했지만, 정적/동적 템플릿 분리와 부분 diff, 최소 DOM diff로 네트워크와 렌더링 비용을 줄여옴 - HEEx 컴포넌트, 업로드,
stream,assign_async,start_async가 더해지며 컴포넌트 검증, 대용량 컬렉션, 비동기 작업, 업로드 진행 표시를 서버 중심 모델 안에서 다룰 수 있음 - 기존 앱은 changelog의 breaking changes를 확인해야 하며, 다음 작업은 collocated JavaScript hooks, Web Component 통합 강화, navigation guards 지원으로 이어짐
6년 만에 안정 릴리스가 된 LiveView
- LiveView 1.0.0은 첫 LiveView 커밋 이후 6년 만에 나온 릴리스임
- 출발점은 JavaScript를 직접 많이 쓰지 않고도 동적인 서버 렌더링 애플리케이션을 만드는 것이었음
- 기존 풀스택 개발에서는 실시간 폼 검증, 장바구니 수량 갱신, 실시간 스트리밍 업데이트를 위해 HTTP glue, GraphQL schema와 resolver, 검증 로직 공유 또는 중복, 로컬라이제이션 정보 전달, serializer, WebSocket과 IPC 연결, JavaScript 번들 크기 조정 등을 함께 다뤄야 했음
- LiveView는 렌더링과 동적 업데이트를 서버가 맡는 방식으로 HTTP 주변 작업을 줄이고, 적은 코드와 적은 고려사항으로 기능을 작성하는 모델을 지향함
- Elixir와 Phoenix는 상태 있는 실시간 서버 UI를 구현하기에 적합한 기반으로 활용됨
실시간 양방향 연결로 가능한 UI
- 모든 사용자와 UI에 실시간 양방향 기반이 기본으로 붙으면, 일반적인 풀스택 반복 작업보다 기능 구현에 더 집중할 수 있음
- LiveView로 구현할 수 있는 예시는 다음과 같음
- 개발 중 서버 로그를 JavaScript 콘솔로 실시간 전송
- CSS stylesheet, 이미지, 템플릿 변경 시 브라우저가 상태와 연결을 유지한 채 자동으로 다시 렌더링하는 프로덕션 hot code upgrade
- 전 세계에 배포된 앱에서 클러스터 전반의 작업 결과를 실시간으로 UI에 집계
- 예시 앱에서는 템플릿 마크업과 RPC 호출을 포함한 전체 LiveView가 350 LOC로 구성됨
서버 렌더링과 RPC 이벤트 모델
- LiveView의 개념적 목표는 React처럼 상태가 바뀌면 템플릿이 자동으로 다시 렌더링되고 UI가 갱신되는 모델을 서버에서 실행하는 것이었음
- LiveView는
render함수와mount시 초기 상태 설정을 갖고, 상태 변경이 생기면 새 상태로 렌더링해 UI를 갱신함 phx-click같은 상호작용은 클라이언트에서 서버로 RPC처럼 전송되고, 서버는 새 페이지 HTML로 응답할 수 있음- 클라이언트/서버 메시지는 Phoenix Channels를 사용하며, Phoenix Channels는 서버당 수백만 연결까지 확장된 벤치마크가 있음
- 첫
phoenix_live_view.js클라이언트는 서버에서 받은 전체 HTML을innerHTML로 교체했음- 동작은 했지만 작은 업데이트에도 전체 템플릿 재실행과 많은 HTML 전송이 필요했음
- 기본 프로그래밍 모델은 유지하되, 다음 과제는 이를 효율적으로 만드는 것이었음
diff 엔진과 렌더링 최적화
- LiveView의 diff 엔진은 두 가지 문제를 함께 해결함
- 이전 렌더와 비교해 실제로 바뀐 동적 템플릿 부분만 실행
- 클라이언트 업데이트에 필요한 최소 데이터만 전송
- 템플릿은 컴파일 시 정적 부분과 동적 Elixir 표현식으로 나뉨
- 정적 문자열은 변하지 않으므로 별도로 보관됨
- 각 표현식에는 접근하는 변수 기준으로 변경 추적이 붙음
mount시 클라이언트는 정적 값 배열과 인덱스별 동적 값을 받음- 이후 업데이트에서는 바뀐 동적 값만 알려진 인덱스로 전송됨
- 예를 들어 온도만
70℉로 바뀌면{1: "70℉"}같은 작은 payload만 내려감
- 단순
innerHTML교체는 UI 상태를 날리고 비용도 크기 때문에, LiveView도 클라이언트 프레임워크처럼 최소 DOM diff를 계산해 DOM을 갱신함 - React에서 Phoenix LiveView로 이전한 사례 중 LiveView 클라이언트 렌더링이 React 앱보다 빨랐던 경우가 있음
- 이후 fingerprinting, for comprehension, tree sharing 등 최적화가 추가됐으며, Dashbit 블로그에서 각 최적화 설명을 볼 수 있음
- 이 최적화는 상태가 있는 클라이언트/서버 연결 덕분에 자동 적용됨
- 다른 서버 렌더링 HTML 솔루션은 매 업데이트마다 전체 fragment를 보내거나 사용자가 수동으로 업데이트를 조정해야 하는 경우가 많음
지연시간과 서버 메모리 비용
- LiveView는 손으로 작성한 JSON API나 GraphQL query보다 작은 payload를 목표로 하며, 각 LiveView가 서버 연결을 유지해 페이지 이동도 live navigation으로 처리함
- TLS handshake와 현재 사용자 인증 등은 사용자 방문 기간 동안 한 번만 수행됨
- 페이지 이동은 단일 WebSocket frame으로 가능하며, 클라이언트 동작마다 데이터베이스 query와 왕복이 줄어듦
- 상태 있는 연결에는 서버 메모리 비용이 따름
- 기본적으로 channel connection 하나는 40KB 메모리를 사용함
- 1GB 서버는 이론적으로 약 25,000 concurrent LiveViews까지 가능함
- 저장하는 상태가 많을수록 메모리 사용량은 증가함
- 큰 컬렉션을 메모리에 모두 보관하지 않도록
streamprimitive를 제공함 - Elixir와 Erlang VM은 이런 상태 있는 시스템에 맞게 설계됐으며, WhatsApp, Discord, Phoenix 자체 벤치마크가 수백만 동시 사용자 확장의 예로 쓰임
HEEx 컴포넌트와 템플릿 개선
- LiveView의 변경 추적과 최소 diff 이후에도 HTML 템플릿의 조합성은 부족했음
- Surface project의 Marlus Saraiva가 HTML-aware component system 개발을 주도하고 LiveView 프로젝트에 기여함
- HEEx components는 선언적 컴포넌트 시스템, HTML 검증, 컴포넌트 attribute와 slot의 컴파일 타임 검사를 제공함
- HEEx 컴포넌트는 annotation이 붙은 함수이며, 예를 들어
<.button click="bad">처럼 정의되지 않은 attribute를 쓰면 컴파일 타임 경고가 발생함 slot은 호출자가 임의 콘텐츠를 전달할 수 있게 해, 시나리오별 partial template을 많이 만들지 않고도 컴포넌트를 확장할 수 있게 함
LiveView 1.0의 HEEx 문법 변화
- HEEx와 function component 도입 당시에는 태그 attribute 안에서
{}보간을 쓰고, 조건부 및 반복 렌더링을 위해:if,:for편의 문법을 제공했음 - 태그 본문에서는 기존 EEx
<%= %>보간을 사용했음 - LiveView 1.0은 HTML-aware
{}attribute 보간 문법을 태그 본문으로 확장함- 예:
<li :for={val <- @values}>Value {val}</li>
- 예:
- EEx
<%= %>는 계속 지원됨- 서로 다른 동적 마크업 block 생성에 필요함
<script>와<style>태그 안의 값 보간에도 필요함
HEEx 마크업 주석과 에디터 이동
- 중첩된 컴포넌트 호출을 거쳐 최종 HTML이 생성되면, 브라우저에서 본 HTML이 코드의 어디에서 나왔는지 추적하기 어려웠음
- HEEx는
debug_heex_annotations설정으로 이 문제를 다룸 - 설정하면 렌더링된 마크업에 다음 위치가 주석으로 붙음
- function component 정의의
file:line - component 호출 위치의
file:line
- function component 정의의
- 새
Phoenix.LiveReloader기능은 사용자가 정한 특수 키 시퀀스로 요소를 클릭할 때 에디터가 가장 가까운 caller 또는 definition의file:line으로 이동하게 함c를 누른 채 클릭하면<.button>호출 위치로 이동d를 누른 채 클릭하면 함수 정의 위치로 이동
업로드, 스트림, 비동기 작업
- LiveView는 몇 년 전 파일 업로드 문제를 다루며, 클라우드 직접 업로드와 서버 직접 업로드를 모두 위한 단일 추상화를 목표로 했음
- 몇 줄의 서버 코드로 drag and drop, 파일 진행률, 선택 pruning, 파일 preview 등을 제공할 수 있음
UploadWriterbehavior는 클라이언트가 chunking하는 raw upload stream에 접근할 수 있게 함- 이를 통해 다른 서버로 업로드 스트리밍 가능
- 업로드 중 비디오 transcoding 가능
- 업로드는 기존 LiveView 연결 위에서 일어나므로 진행률 반영이나 고급 파일 작업을 구현하기 쉬움
- 이후 큰 컬렉션을 서버 메모리에 보관하지 않고 효율적으로 다루기 위한
streamprimitive가 추가됨 assign_async와start_asyncprimitive는 비동기 작업 처리와 비동기 결과 렌더링을 단순화함- 외부 서비스 호출처럼 느리거나 불안정할 수 있는 작업을 새 프로세스로 넘길 수 있음
<.async_result>는 loading, success, failure 상태를 렌더링함- LiveView 연결이 끊기면 async process가 정리되어 더 이상 존재하지 않는 UI에 리소스를 쓰지 않음
서버 중심 UI 모델의 확산과 차이
- LiveView와 .NET Blazor는 비슷한 시기에 시작했으며, 이 프로그래밍 모델의 채택을 이끈 프로젝트로 볼 수 있음
- 이후 Go, Rust, Java, PHP, JavaScript, Ruby, Haskell 커뮤니티에서도 이 모델이 다양한 방식으로 받아들여짐
- 많은 구현은 LiveView의 선언적 모델을 제공하지 않음
- 개발자가 개별 element의 업데이트와 제거 방식을 annotation해야 함
- 이벤트마다 큰 payload를 보내거나 수동 최적화가 필요할 수 있음
- React도 React Server Components를 통해 React를 서버에 두는 아이디어를 채택했지만, RSC에서 실시간 이벤트 push는 외부 수단에 맡겨짐
- Elixir와 Erlang VM은 상태 있는 양방향 통신 계층에 잘 맞으며, LiveView 모델을 돋보이게 하는 요소임
- 글로벌 분산 클러스터링과 PubSub도 플랫폼에 내장되어 있음
시작 방법과 다음 작업
- 새 프로젝트는
new.phoenixframework.org로 몇 초 안에 Elixir와 첫 Phoenix 프로젝트를 시작할 수 있음 - macOS/Linux:
curl https://new.phoenixframework.org/myapp | sh
- Windows PowerShell:
curl.exe -fsSO https://new.phoenixframework.org/app.bat; .\app.bat
- 기존 애플리케이션은 changelog에서 breaking changes를 확인해 1.0에 맞춰야 함
- 다음 작업은 아래 항목에 집중함
-
collocated JavaScript hooks
- Web Component 통합 강화
- navigation guards 지원
- issue tracker에 정리된 추가 작업들
-
댓글과 토론
Hacker News 의견들
- Phoenix 만든 사람입니다. 드디어 Phoenix LiveView 1.0을 내보내게 되어 기쁩니다. Elixir/Phoenix/LiveView 관련 질문은 무엇이든 답할 수 있어요
블로그 글 안쪽에 새 설치 프로그램도 들어 있습니다. 한 줄 명령으로 Elixir를 설치하고 새 Phoenix 프로젝트를 생성합니다
osx/linux:$ curl https://new.phoenixframework.org/yourappname | sh
windows powershell:> curl.exe -fsSO https://new.phoenixframework.org/app.bat; .\app.bat
해당 URL을 직접 열어 스크립트가 무엇을 하는지 볼 수 있고, 공식 Elixir 사전 빌드 설치 프로그램 https://elixir-lang.org/install.sh 및 https://elixir-lang.org/install.bat을 확장한 것입니다
동작 예시는 https://x.com/chris_mccord/status/1864067247255306332에서 볼 수 있습니다
| sh가 싫다면 일반 설치 가이드도 있습니다: https://hexdocs.pm/phoenix/installation.html
이제 이게 나왔으니 새 데모 몇 개를 만들어보고 싶습니다. 어떤 걸 보고 싶은가요?- Elixir와 Ruby의 유사성은 피상적일 뿐이지만, Chris와 José의 작업은 Ruby와 Rails에서 시작된 흐름의 반영이자 진화처럼 보입니다
친절한 커뮤니티, 실제로 출시해야 하는 사람들을 위한 실용주의, Elixir와 Phoenix 프로젝트의 훌륭한 관리까지 포함해서요
2016년부터 전업 Elixir 개발자로 일하고 있고, 여전히 가장 좋아하는 프로그래밍 환경입니다. 최근에는 한 시간 만에 만든 대시보드가 얼마나 매끄러운지 클라이언트가 알아챘는데, 그걸 만들면서 JavaScript를 한 줄도 쓰지 않았다는 건 모릅니다 - 피드백을 남기기에 최적의 장소는 아닐 수 있지만, 이걸 보고 바로 시도해봤다가 잘 안 됐습니다. 첫 오류는
sh: line 1: Application: command not found였습니다
https://new.phoenixframework.org/test-elixir-app에 직접 들어가보니 올바른 출력은Application name must start with a letter and have only lowercase letters, numbers and underscore였습니다
그래서test_elixir_app으로 바꿨더니downloading https://github.com/elixir-lang/elixir/…다음에fedora is not supported가 나왔습니다
즉흥적으로 해본 거라 나중에 Ubuntu 머신 등에서 다시 시도할 수는 있겠지만, 초기 마찰이 아쉬웠습니다. 그래도 프로젝트 설치 데모 GIF는 훌륭해 보였습니다 - 초기부터 Phoenix로 클라이언트용 성공적인 앱을 꽤 많이 출시했고, 이제 그 위에 스타트업을 출시하려는 중입니다. 이 라이브러리는 제 커리어를 바꾼 정도가 아마 어떤 라이브러리보다도 큽니다
- Phoenix에 수년간 헌신하고 전 세계 개발자에게 가치를 제공해줘서 고맙습니다
별개로, 9년 된 성능 벤치마크 블로그 글을 업데이트할 생각이 있나요? 그리고 이제는 Cowboy보다 Bandit을 권장하나요?
https://www.phoenixframework.org/blog/the-road-to-2-million-... - 1.0 축하하고, 들어간 모든 작업에 정말 감사합니다. 더 보고 싶은 건 낙관적 UI 관련 데모입니다
작업량은 많겠지만, Remix의 Ryan Florence가 Remix로 Trello를 재현하는 전체 재생목록을 만든 적이 있습니다
특히 LiveView에서 보고 싶거나 구현 방법 데모가 있으면 좋겠는 기능은 낙관적 UI, 낙관적 추가, 끌어서 놓기입니다. 재생목록의 마지막 세 영상입니다
https://www.youtube.com/playlist?list=PLXoynULbYuED9b2k5LS44...
- Elixir와 Ruby의 유사성은 피상적일 뿐이지만, Chris와 José의 작업은 Ruby와 Rails에서 시작된 흐름의 반영이자 진화처럼 보입니다
- LiveView로 프로덕션 앱을 많이 만들었습니다. 설계상 앱을 효과적으로 쓰려면 어느 정도 안정적인 WebSocket 연결이 필요하다는 한계가 있지만, 그 대가로 여러 장점이 생깁니다
코드 생성 덕분에 실제로 쓸 만한 앱을 아주 빠르게 세울 수 있고, Elixir는 특히 웹에 훌륭한 언어이며, 프런트엔드를 렌더링할 때 언어의 힘과 HTML의 단순함을 동시에 누리는 느낌입니다. JavaScript는 거의 또는 전혀 쓰지 않아도 됩니다
서버 데이터가 갱신될 때 WebSocket으로 아주 작은 변경분만 보내기 때문에 효율적이고, 이미 WebSocket을 쓰고 있으니 채팅·알림·게임 상태 같은 실시간 기능을 추가하기도 쉽습니다
관례상 관심사를 분리해 비즈니스 로직을 Context에 두기 때문에, 먼저 LiveView로 웹앱을 만들고 나중에 네이티브 앱이나 API 소비자 같은 다른 클라이언트가 필요할 때 최소 변경으로 API를 제공하는 경로도 현실적입니다
Ecto를 검증에 쓰는 것도 좋고, 그걸 “프런트엔드” 코드에서도 쓸 수 있는 점이 즐겁습니다. 백엔드와 프런트엔드 테스트를 모두 Elixir로 할 수 있다는 것도 큽니다
1.0까지 오는 동안 버그와 함정을 몇 번 겪었지만, 오래전부터 안정적이고 잘 만들어진 라이브러리처럼 느껴졌고, 코드베이스를 단순하고 유지보수 가능하게 유지해 빠르게 움직일 수 있게 해줬습니다- LiveView는 LongPoll 전송 방식에서도 완전히 동작하고 기본으로 활성화되어 있으며, WebSocket이 어떤 이유로든 실패하면 자동으로 longpoll로 폴백합니다
그래서 일부 “기업 프록시”처럼 101 WebSocket 업그레이드는 허용해놓고 이후 트래픽을 허공에 버리는 이상한 환경에서도 괜찮아야 합니다. 제가 다루는 프로덕션 앱 기준으로는 요즘 트래픽의 1~2% 정도가 WebSocket 문제를 겪는 것 같습니다
물론 LiveView가 괜찮은 사용자 경험을 위해 어느 정도 안정적인 연결을 요구한다는 점은 맞지만, 이 주제에는 논의에서 자주 빠지는 뉘앙스가 많습니다. 앱은 서버에 가는 SPA와 대체로 비슷하게 저하되어야 합니다
불안정한 연결에서 탄탄한 사용자 경험을 내려면 오프라인/로컬 우선 SPA가 필요한데, 제 경험상 대부분의 SPA는 이걸 처리하지 않습니다. 그렇지 않으면 대부분의 SPA 프레임워크는 낙관적 UI와 롤백 부담을 개발자에게 떠넘기는 편이고, 나쁜 연결에서 꽤 형편없이 저하됩니다
직관과 달리 연결이 나빠도 LiveView는 사람들이 생각하는 것보다 잘 버팁니다. 이미 연결이 맺어져 있어 재연결 오버헤드를 겪지 않아도 되고, 페이로드도 대체로 더 작기 때문입니다
산길에서 불안정한 셀룰러 테더링으로 Facebook과 LiveView 앱을 둘러본 개인적 사례도 있습니다: https://x.com/chris_mccord/status/1799100642654638543/video/... - “필요”라는 말은 좀 강합니다. 지금은 주로 long polling으로 LV를 쓰고 있고, 유일한 단점은 JS 콘솔에서 클라이언트가 WebSocket 연결을 만들 수 없다고 투덜대는 정도입니다
- LiveView는 LongPoll 전송 방식에서도 완전히 동작하고 기본으로 활성화되어 있으며, WebSocket이 어떤 이유로든 실패하면 자동으로 longpoll로 폴백합니다
- 정말 좋은 소식입니다. 몇 년째 LiveView를 쓰고 있는데 더할 나위 없이 만족합니다. 작업하기 즐겁고, 웹 개발에 대한 애정을 다시 살려줬습니다
LV에서는 생산성이 너무 높아서 비현실적으로 느껴질 정도입니다
HN에서 너무 자기 홍보처럼 보이지 않으려 하지만, 이번 v1.0.0 릴리스를 계기로 LiveView를 배우고 싶어졌다면 제 강의 http://learnphoenixliveview.com를 조심스럽게 추천합니다. 코드HACKERNEWS로 20% 할인됩니다
처음 배울 때 좋은 학습 자료를 찾기 어려웠고, 그 문제를 바로잡아보려 했습니다. 더 많은 사람이 초기 학습 곡선을 넘도록 돕고 싶습니다. 이 훌륭한 프레임워크에 익숙한 사람이 많아질수록 모두에게 이득이라고 봅니다- 강의가 정말 좋았습니다. 계속 좋은 작업 부탁드립니다. Phoenix 폼에 대한 동반 심화 강의도 막 출시한 걸 봤는데 축하합니다
관계자는 아니고, 그냥 Arrowsmith Labs 자료를 즐겨 보는 사람입니다 - 좋은 학습 자료를 찾기 어려웠다는 게 궁금합니다. 그때 Pragmatic Studio가 없었거나 가격이 맞지 않았나요? 꽤 오래전부터 이 주제를 가르쳐온 걸로 봤습니다
Pragmatic Programmers 출판사도 수년간 관련 책을 많이 냈습니다. 아마 Pragmatic Studio의 온라인 강의만큼 이른 시기는 아니었겠지만요 - LiveView v1.0에 맞춰 강의를 업데이트할 계획인가요?
- 강의가 정말 좋았습니다. 계속 좋은 작업 부탁드립니다. Phoenix 폼에 대한 동반 심화 강의도 막 출시한 걸 봤는데 축하합니다
- 일반적인 웹앱에서 가장 비싼 부분은 프런트엔드와 백엔드 개발자 사이의 조율 비용입니다. 그래서 한 명이 풀스택을 구현하게 하는 게 합리적으로 보이지만, 그 대가로 양쪽을 모두 알아야 하는 지식 비용과 심한 문맥 전환이 생깁니다
어느 쪽도 이상적이지 않아서 대부분의 회사는 조율 비용을 받아들였습니다
그런데 LiveView는 이 문제들을 그냥 비껴가며, 무거운 비용 없이 풀스택을 구현하게 해줍니다. Elixir/Phoenix/LiveView는 한 명의 개발자가 갈 수 있는 거리를 극대화하는 도구 묶음입니다
더 적은 개발자가 더 많은 기능을 출시할 수 있다는 점은 많은 회사에서 강력한 판매 포인트가 될 것 같지만, 무거운 SPA 스택은 중간관리자가 더 큰 팀을 채용해야 한다고 합리화하기 좋습니다. LiveView는 출시를 위한 도구이지, 지연을 위한 도구가 아닙니다- 프런트엔드와 백엔드를 같은 코드베이스에 강제로 넣고 결합시키는 건 훌륭합니다. 프런트엔드 개발자와 백엔드 개발자라는 사일로가 생기는 걸 피하는 데 도움이 된다고 봅니다
진심입니다. 스택을 수직으로 쪼개기 어렵게 만드는 실제 장애물이 있는 게 좋습니다
- 프런트엔드와 백엔드를 같은 코드베이스에 강제로 넣고 결합시키는 건 훌륭합니다. 프런트엔드 개발자와 백엔드 개발자라는 사일로가 생기는 걸 피하는 데 도움이 된다고 봅니다
- 관여한 모두에게 축하를 보냅니다. LiveView는 발명됐다기보다 발견된 것처럼 보이는 물건 중 하나입니다
초기 Phoenix는 그냥 “더 나은 Rails”였지만, Ruby 한계 때문에 Rails가 제대로 다루기 어려웠던 멋진 “channels” 기능이 있었습니다. 그 “channels”가 점차 다듬어지더니 어느새 그 위에 LiveView 초기 버전이 만들어졌습니다
LiveView는 놀라웠지만, 더 표준적인 정적 뷰와는 좀 따로 노는 느낌이었습니다. 커뮤니티에서 종종 “dead” view라고 부르는 그 표현은 별로 좋아하지 않습니다
시간이 지나며 라이브 뷰와 정적 뷰 사이에서 코드를 공유할 수 있게 업데이트됐고, 마침내 Phoenix 1.7에서 웹앱을 만드는 완전히 새로운 레이아웃과 철학으로 이어졌습니다
Phoenix 1.7은 이전 버전들과 급진적으로 다르게 느껴지고, Rails 전통과도 깔끔히 결별한 느낌입니다. 하지만 그 모든 변화가 이해 가능한 방식으로 점진적으로 도달했습니다
Elixir가 만들어진 순간부터 웹앱을 구성하고 만드는 이 새로운 방식이 바위 속에 원래 있었고, 10년 동안 조금씩 깎아내 드러낸 것처럼 느껴집니다 - LiveView 1.0 릴리스에 대한 생각을 썼습니다: https://dockyard.com/blog/2024/12/03/phoenix-liveview-goes-1...
- 축하합니다. 이번 안정 릴리스는 큽니다
안타깝게 실패한 제 스타트업을 약 18개월 동안 LiveView로 만들었습니다. 실제로 작업하기 정말 좋았고, 제품 경험도 훌륭했습니다
특히 복잡하거나 성숙한 라이브러리인react-grid-layout, WYSIWYG 편집기 때문에 React도 함께 통합했습니다. 백엔드 LiveView와의 연결은 꽤 매끄러웠고, 가능한 한 모든 걸 LV에 두려고 했습니다
가장 큰 어려움은 React에서는 50번쯤 풀어본 문제를 LiveView에서는 처음부터 다시 풀어야 했다는 점입니다. 한 번 풀고 나면 쉽게 재사용할 수 있었습니다- 어떤 문제들이었고, 어떻게 해결했나요?
- 팀에게 축하를 보내고, 제 직업 생활을 더 쉽고 즐겁게 만드는 무언가를 만들어준 데 대해 아주 큰 포옹을 보내고 싶습니다
Elixir는 훌륭합니다. 언어가 저를 느리게 만든다고 느낀 적이 없습니다
필요한 도구들도 놀라울 정도로 뻔하고 바로 눈앞에 있습니다. Oban 백그라운드 작업, 인증, 암호화 등 필요한 게 갖춰져 있습니다
일상 도구들도 잘 다듬어져 있고 즉시 유용합니다.mix ecto.reset,seeds.exs,mix test,mix format, 경고를 보기 위한mix compile --force까지 전부 손끝에 있고 예상대로 동작합니다
성능은 크게 성공하기 전까지는 거의 걱정하지 않아도 될 정도입니다. 지금도 문자 그대로 275MB만 쓰며 여유롭고, 응답 시간은 100ms 미만입니다
결론적으로 Elixir와 Phoenix를 한번 시도해보세요. 2016년에 써보기로 한 건 제 커리어 최고의 결정이었습니다- “커리어 최고의 결정”이라는 건, 그걸로 일이 많이 들어온다는 뜻인가요?
- LiveView에서 자주 언급되지 않지만 좋아하는 점은 풀스택 비동기 프로세스를 아주 쉽게 만든다는 점입니다
백엔드에서 사용자의 브라우저로 비동기 이벤트를 보내는 게 터무니없이 쉬워서, 긴 프로세스가 끝날 때까지 브라우저에서 동기적으로 기다리려는 유혹을 피하게 됩니다
그 덕분에 백엔드에서 많은 문제를 일으킬 수 있는 긴 동기 호출 사슬을 만들지 않게 됩니다- React-Router/Remix에서도 비슷한 걸 느꼈습니다. Action/Fetcher 모델이 마음에 들고, 백엔드나 클라이언트 쪽 fetch 요청과의 통신을 단순화하는 좋은 방식입니다
하지만 오래 걸리는 작업을 도입하고 사용자에게 진행 상황을 알리거나 부분 결과를 제공하고 싶어지는 순간, 직접 알아서 해야 합니다
- React-Router/Remix에서도 비슷한 걸 느꼈습니다. Action/Fetcher 모델이 마음에 들고, 백엔드나 클라이언트 쪽 fetch 요청과의 통신을 단순화하는 좋은 방식입니다
- 팀에게 축하를 보냅니다. 한동안 지켜봐 왔고, 좋은 개발자 경험 이야기는 언제나 반갑습니다
LiveView 같은 기술을 채택하는 것과 JS 생태계의 커뮤니티 규모·확장성 사이의 트레이드오프에 대해 실제 사용자들의 설명을 듣고 싶습니다
예를 들어 JS 쪽은 ProseMirror 같은 라이브러리나 Loro, Automerge 같은 더 고급 CRDT 라이브러리의 혜택을 크게 봅니다. AI 쪽은 어떤가요?
이런 JS 기반 기술을 받아들이는 명확한 경로가 있나요? 아니면 필요 없나요? 양쪽 세계를 모두 살아본 사람들에게서 트레이드오프를 더 잘 이해하고 싶습니다- LiveView는 사실 Elixir 식당의 디저트 같은 거라 어렵습니다. 디저트만 먹고 살 수는 없습니다
React 같은 것들에 비하면 생태계가 적어도 한 자릿수 규모로 작고, 평균 라이브러리 품질은 매우 높지만 큰 프런트엔드 생태계처럼 모든 사용 사례에 대한 기성 해법을 찾을 수는 없습니다
JS와 LiveView의 상호운용은 놀라울 만큼 잘 되므로 ProseMirror가 불가능한 건 아니지만, 큰 프런트엔드 생태계에는 여전히 중요한 이점이 있다고 봅니다
다만 프런트엔드는 제쳐두고, 본식은 Erlang/Elixir의 간결하고 함수형이며 동시성 중심인 패러다임입니다. 이것도 발명됐다기보다 발견된 것처럼 느껴집니다
메시지 전달 액터를 생각하기 위해 기본으로 제공하는 구조는 얽힌 비동기 함수의 그물보다 훨씬 쉽습니다. 그래서 CRDT, API 호출, 다른 언어로 작업 실행, 실시간 통신이 모두 Elixir에서 잘 맞습니다
액터 모델은 어느 정도 가비지 컬렉션과 비슷한 패러다임 전환이라고 봅니다. 점점 복잡한 프로그램 때문에 제정신을 유지하려면 메모리 관리를 추상화해야 했고, 필요할 때만 직접 내려가 관리했습니다
웹 중심 세계에서는 제정신을 유지하기 위해 아주 작은 상태 있는 서비스, 즉 액터로 추상화하고, 필요할 때 순차 언어로 내려가게 됩니다 - JavaScript를 LiveView와 통합하고, 클라이언트에서 서버로 또는 서버에서 클라이언트로 이벤트를 주고받는 건 hooks를 쓰면 꽤 간단합니다: https://hexdocs.pm/phoenix_live_view/js-interop.html#client-...
AI 쪽은 주로 Nx 프로젝트를 중심으로 돌아갑니다: https://github.com/elixir-nx/ - 단점은 JS 생태계의 방대한 규모에 접근하지 못한다는 것입니다
장점은 JS 생태계의 방대한 규모에 접근할 필요가 없다는 것입니다. 그리고 JS를 훨씬 덜 쓰거나 아예 안 쓰게 됩니다
JavaScript에 스톡홀름 증후군이 없다면 그냥 LiveView로 옮기면 됩니다. Erlang/Elixir는 진지한 앱을 만들기에 편안하면서도 안전한 플랫폼입니다 - Automerge 관점에서는 ElectricSQL에 엄청난 노력이 들어가고 있습니다. Elixir로 작성됐고 Elixir 앱의 일부로도 실행할 수 있으니, 제가 아는 한 로컬 우선 클라이언트의 많은 이점을 얻을 수 있습니다
langchain 구현체도 꽤 성숙했고 확실히 프로덕션에서 쓰입니다. 실제로 그 작성자 핸들도 여기서 본 것 같습니다
langgraph 스타일 라이브러리도 있습니다. 제가 써본 것 중에는 Magus라는 게 있습니다. 다만 이 영역은 더 많은 노력이 들어갈 수 있어 보입니다
Elixir의 프로세스 모델을 쓰면 langgraph에 견줄 만한 것을 만드는 게 그리 어렵지 않고, 대부분의 Elixir 개발자는 아마 만들 수 있습니다. 하지만 “langgraph implementation in Elixir”를 검색하는 일반 사람에게는 그게 obvious하지 않은 게 아쉽습니다
langsmith 통합은 없지만 Erlang과 Elixir의 telemetry 구현은 정말 좋습니다. 체인과 그래프 실행 패턴이 공개적으로 어느 정도 자리 잡으면, langsmith 통합도 꽤 빠르게 진행될 것 같습니다. 자체 langgraph 대응물을 비공개 저장소로 구현한 회사들도 몇 군데 있을 거라고 봅니다
- LiveView는 사실 Elixir 식당의 디저트 같은 거라 어렵습니다. 디저트만 먹고 살 수는 없습니다