1P by GN⁺ 2시간전 | ★ favorite | 댓글 1개
  • Ladybird는 4월에 35명 기여자의 333개 PR을 병합했고, Human Rights Foundation의 50,000달러와 Jakub Stęplowski의 1,000달러 후원을 새로 받음
  • 인라인 PDF 뷰어, 방문 기록 기반 주소창 자동완성, GTK4/libadwaita Linux 프런트엔드, about:bookmarks 관리 UI가 추가되어 브라우징 기능과 데스크톱 UI가 확장됨
  • HTML 파서는 응답 본문을 점진적으로 파싱하고 추측 파서가 리소스를 미리 가져오며, JavaScript 최상위 컴파일은 백그라운드 스레드로 이동해 YouTube 로딩에서 약 200ms의 메인 스레드 시간을 줄임
  • JavaScript 엔진은 for-in 캐시, O(1) 레지스터 할당기, zero-copy 식별자 공유, lazy JS::Substring, typed-array view cache 개선 등으로 Speedometer와 실제 사이트 로딩 성능이 개선됨
  • Cache/CacheStorage, image-set(), CSS anchor positioning, 비동기 DNS, dmabuf 기반 GPU 페인팅, mimalloc 기본화, Rust 필수화가 포함됐고 WPT 점수는 2,003,537에서 2,067,263으로 상승함

개발 규모와 후원

  • 4월 Ladybird는 35명 기여자의 333개 PR을 병합했고, 이 중 7명은 Ladybird에 처음 커밋함
  • 신규 후원자로 Human Rights Foundation이 “AI for Individual Rights” 프로그램을 통해 50,000달러, Jakub Stęplowski1,000달러를 후원함
  • Ladybird는 오픈 웹을 지지하는 기업과 개인의 후원으로 전액 운영됨

브라우징 기능과 프런트엔드

  • 인라인 PDF 뷰어

    • PDF가 번들된 pdf.js 뷰어를 통해 인라인 렌더링됨(#9132)
    • pdf.js는 JavaScript, HTML, CSS만으로 작성된 PDF 뷰어이며 페이지 탐색, 텍스트 선택, 확대/축소, 문서 내 검색을 제공함
    • Intel ISA Manual을 pdf.js로 로딩하는 과정에서 typed-array view cache와 :has() 무효화 개선 지점이 드러남
  • 방문 기록과 주소창 자동완성

    • 주소창 입력 시 방문 기록 기반의 풍부한 추천이 표시되며, 이전 방문 페이지의 파비콘과 제목, 검색 엔진 바로가기, 일반 URL 완성을 포함함(#8933)
    • SQLite 기반 HistoryStore가 모든 탐색의 제목, 파비콘, 방문 횟수, 마지막 방문 시각을 저장함
    • 개인정보 설정 페이지에 “Clear browsing history”가 연결됐고, Qt와 AppKit UI 모두 새 리치 행을 렌더링함
  • GTK4 / libadwaita 프런트엔드

    • Ladybird에 GTK4와 libadwaita 기반의 새 Linux 프런트엔드가 추가됐으며 기존 Qt 프런트엔드와 나란히 제공됨(#8691)
    • GNOME Web(Epiphany)에서 영감을 받았고 GNOME 설계 지침에 따라 메뉴바 없이 햄버거 메뉴와 AdwTabView 탭을 사용함
    • URL 바 자동완성 및 보안 아이콘, 페이지 내 찾기, 전체화면, 콘텍스트 메뉴, alert/confirm/prompt/color/file 대화상자, 클립보드, 다중 창, 라이트/다크 테마, DPR 스케일링을 제공함
    • 아직 초기 단계라 Qt 및 AppKit 프런트엔드와 기능 동등성에는 도달하지 못함
  • 북마크

    • 지난달 추가된 북마크에 관리 UI가 더해짐
    • about:bookmarks 페이지에서 북마크와 폴더를 관리할 수 있음(#8825)
    • 새 페이지에서 북마크 가져오기와 내보내기를 지원함(#8938)
    • 북마크와 폴더 편집용 콘텍스트 메뉴가 추가됨(#8715)
    • 모든 북마크와 폴더에 date_added 타임스탬프가 추가됨(#8867)
    • 북마크 바에서 새 탭 열기, URL 복사, 가운데 클릭 및 Ctrl/Cmd+클릭 새 탭 열기를 지원함(#8758)
    • HTML5 드래그 앤 드롭 API가 연결됐고 about:bookmarks는 이를 재정렬에 사용하며 일반 웹 페이지에서도 동작함(#8783)

HTML 파싱, 스크립트 실행, 렌더링 파이프라인

  • 추측 및 점진적 HTML 파싱

    • HTML 파서가 응답 본문을 점진적으로 소비하도록 바뀜(#9151)
    • 바이트는 스트리밍 텍스트 디코더를 지나 토크나이저에 청크 단위로 들어가며, 입력이 부족하면 토크나이저가 멈췄다가 더 도착하면 재개함
    • 전체 본문 수신을 기다린 뒤 파싱을 시작하던 기존 모델을 대체함
    • 추측 HTML 파서도 구현됨(#9114)
    • 메인 파서가 동기 외부 스크립트에서 막히면 별도 토크나이저가 아직 파싱되지 않은 입력을 앞서 스캔하고 <script src>, <link rel=stylesheet|preload>, <img src> 리소스의 추측 가져오기를 발행함
    • <base href>를 추적하고 템플릿 및 foreign content 내부를 올바르게 건너뜀
    • 추측 파서가 문서의 preload map에 연결되어 추측으로 발견된 리소스가 일반 파서의 이후 가져오기와 중복 제거됨(#9164)
  • 오프스레드 JavaScript 컴파일

    • 가져온 스크립트의 최상위 코드 바이트코드 생성이 백그라운드 스레드 풀에서 실행됨(#9118)
    • 워커 스레드는 바이트코드와 Executable 생성에 필요한 데이터를 만들고, VM 또는 GC 힙을 건드리는 작업은 메인 스레드에 남김
    • classic script, module, 최상위 IIFE를 처리하며 YouTube 로딩만으로도 약 200ms의 메인 스레드 시간이 백그라운드 스레드로 이동함
  • Navigable별 래스터화

    • 각 Navigable이 자체 스레드에서 독립적으로 래스터화됨(#8793)
    • 이전에는 iframe이 부모 display list 내부의 중첩 display list로 동기 페인트되어 최상위 traversable의 렌더링 스레드만 활성화됐음
    • 부모 display list는 이제 ExternalContentSource를 통해 각 iframe의 래스터화된 출력을 참조하므로 iframe 무효화가 부모 재기록을 요구하지 않음
    • 병렬성 외에도 iframe을 별도 샌드박스 프로세스로 옮기기 위한 준비 작업임
  • Linux dmabuf 기반 GPU 페인팅

    • Linux Vulkan 빌드에서 WebContent는 GPU-backed Skia surface에 페인트했지만 UI 프로세스와 공유하는 버퍼가 CPU 비트맵이라 매 flush마다 GPU-to-CPU readback이 발생했음
    • SharedImage가 Linux dmabuf 핸들을 담을 수 있게 되어 front/back buffer가 UI 프로세스까지 GPU에 상주함(#8917, #8920)

JavaScript 엔진 성능과 호환성

  • JS-to-JS 호출 최적화

    • Call, Return, End 명령이 일반적인 경우 AsmInt 어셈블리 인터프리터 안에 머물도록 여러 PR이 적용됨(#8891, #8909, #8912)
    • 레지스터 저장/복구에는 수작업으로 조정된 ARM64 paired load/store(ldp/stp)를 사용함
    • native function 호출도 AK::Function 대신 일반 함수 포인터를 담는 새 RawNativeFunction variant를 통해 AsmInt에서 직접 디스패치됨(#8922)
  • O(1) 바이트코드 레지스터 할당기

    • Generator::allocate_register는 사용 가능한 풀을 스캔해 가장 낮은 번호의 레지스터를 찾던 구조였고, x.com 로딩 중 이 함수만 약 800ms를 소비했음
    • C++/Rust 파이프라인 동등성 기간이 끝난 뒤 할당기는 단순 LIFO 스택으로 바뀜(#9007)
  • 캐시된 for-in 반복

    • for (key in obj) 위치가 평탄화된 enumerable key 스냅샷을 캐시하고, receiver의 shape, indexed storage, prototype chain이 유지되는 동안 재사용함(#8856)
    • Speedometer 2는 67.7 → 73.6, Speedometer 3는 4.11 → 4.22로 상승함
  • 기타 엔진 개선

    • 파서가 lexer, parser, scope collector 전반에서 식별자 이름을 zero-copy로 공유해 웹사이트 JS 코퍼스에서 파싱이 1.14배 빨라지고 RSS가 282MB 감소함(#8801)
    • 짧은 문자열 연결은 결과가 어차피 flat string으로 관찰될 때 rope 표현을 건너뛰며, 촘촘한 a + b 루프에서 2.13배 빨라짐(#9184)
    • lexical-this arrow function은 호출마다 function environment를 할당하지 않아 마이크로벤치마크에서 2.13배 개선됨(#9192)
    • sparse array는 hole에 대한 즉시 비용을 내지 않으며 Array(20_000_000)이 2천만 개의 가상 요소에 비례하는 작업 대신 대부분 메타데이터로 유지됨(#8847)
    • 새 lazy JS::Substring 타입이 regexp capture와 slice, split, indexed access 같은 string builtin을 뒷받침하며 Octane regexp 벤치마크에서 1.066배 개선됨(#8863)
    • 바이트코드 source map에서 source position이 end-to-end로 보존되어 x.com에서 약 250ms를 절약함(#9027)
    • zero-copy TransferArrayBuffer가 YouTube 로딩에서 약 130ms를 절약함(#9088)
    • cached typed-array view가 WeakHashSet에서 intrusive list로 바뀌어 pdf.js에서 Intel ISA PDF를 로딩할 때 약 250ms를 절약함(#9180)
    • 모든 Promise가 capture하지 않는 AK::Function closure를 가진 PromiseResolvingFunction 셀 2개를 할당하던 구조에서, Kind enum으로 디스패치되는 static function으로 바뀌어 resolver별 할당이 제거됨(#9188)
    • non-dictionary shape의 property-table marking을 건너뛰어 maptiler.com 로딩 중 GC 시간이 1.3초 줄어듦(#9044)
    • packed array의 Array.prototype.indexOf fast path가 추가됨(#9123)
    • Array.prototype.sort가 비교마다 재트랜스코딩하지 않고 캐시된 UTF-16을 재사용함(#9036)
    • WASM, JSON, CSS modules import가 추가됨(#6029)
    • ShadowRealm 제안이 표준화 과정에서 정체되어 지원이 제거됨(#8753)

웹 플랫폼 API와 CSS

  • Cache와 CacheStorage

    • CacheCacheStorage가 end-to-end로 구현됨(#8745)
    • open, has, delete, keys, match, matchAll, add, addAll, put 등 9개 메서드가 일시적 인메모리 저장소를 기반으로 동작함
  • CSS 기능과 렌더링 수정

    • image-set()의 표준 및 -webkit- prefix 형태에 대한 기본 지원이 추가됐고, 페인트 시점에 device pixel ratio와 가장 잘 맞는 해상도 후보를 선택하며 지원하지 않는 MIME 타입은 건너뜀(#9090)
    • image-set() 지원으로 gocomics.com의 헤더 이미지가 표시됨
    • position-anchor와 CSS anchor positioning 초기 지원이 추가되어 cssdoom.wtf의 손과 총 위치가 수정됨(#8686)
    • 색상 보간이 css-color-4에 맞춰 재작성되어 u8 대신 float에서 보간하고, missing/powerless component, out-of-gamut sRGB, alpha multiplier를 일관되게 처리함(#8934)
    • align, bgcolor 같은 legacy presentational HTML attribute가 직접 cascaded properties를 쓰지 않고 일반 author declaration처럼 cascade를 통과해 var() 치환과 invalid-at-computed-value-time fallback이 올바르게 동작함(#9176)
    • presentational hint cascade 변경으로 html.spec.whatwg.org의 crash가 수정됨
    • <thead>, <tbody>, <tfoot>, <tr>align presentational attribute를 반영해 bricklink.com의 버튼 배치가 수정됨(#9177)
    • stroke-dasharray 보간으로 SVG dash가 부드럽게 애니메이션됨(#9133)
    • autofocus attribute가 있는 요소가 페이지 로드 시 실제로 focus를 받음(#9016)
    • RTL 텍스트의 list marker가 오른쪽에 배치되어 Arabic Wikipedia의 목록 렌더링이 수정됨(#9099)
    • inline flex/grid container의 baseline이 마지막 wrapped line이 아니라 child의 first line box에서 파생되어 nos.nl의 링크 텍스트와 아이콘 정렬이 수정됨(#9183)

네트워킹과 스타일 무효화

  • 네트워킹

    • getaddrinfo가 더 이상 event loop를 막지 않음
    • LibDNS는 lookup을 thread pool에서 실행하고 AAAAA query를 병렬로 발행하며, 같은 이름에 대한 동시 lookup을 병합함(#9109)
    • RequestServer의 preconnect 경로가 resolver를 우회해 libcurl의 threaded resolver가 main thread에서 pthread_join을 유발하던 문제가 같은 DNS pool 경로로 라우팅되도록 수정됨(#9109)
    • WebContent가 네트워크보다 느릴 때 RequestServer의 queued response data drain이 O(n²)였고, YouTube 비디오를 열 때 memcpy에 약 30초, Vector::remove3초를 소비했음
    • AllocatingMemoryStream이 singly-linked chunk list로 바뀌어 소비가 O(1)이 됨(#9028)
    • 이미지 요청의 Accept header에 AVIF와 WebP를 광고해 다른 엔진과 맞췄고, 일부 CDN은 이 헤더로 최신 포맷 제공 여부나 JPEG fallback을 결정함(#9046)
  • 스타일 무효화

    • 기존 selector invalidation은 selector가 아래 방향만 본다는 전제에서 단순했지만, :host:has() 때문에 descendant 변경이 ancestor의 :has() 결과를 바꿀 수 있어 위로 올라가는 walk가 필요해짐
    • stylesheet mutation이 하나의 scope만 바꿨을 때 모든 style scope cache를 재구성하지 않도록 하여 Reddit rule cache rebuild가 13.2초 → 3.2초로 줄어듦(#9138)
    • sibling structural invalidation이 position을 관찰하지 않는 descendant로 퍼지지 않게 되어 Reddit infinite scroll에서 불필요한 recompute가 11% 감소함(#9155)
    • :has() mutation invalidation이 영향받지 않는 anchor를 건너뛰며 azure.com에서 큰 감소가 측정됨(#9168)
    • Intel ISA PDF에서 :has() child-list visit이 71k → 1.6k로 줄었고, pdf.js 로딩에서 약 650ms를 절약함(#9179)
    • 새 structural-invalidation 테스트 묶음이 여러 무효화 누락을 드러냈고 이를 수정함(#9095)
    • hover, stylesheet mutation scope, custom-property map, computed-style diffing 주변의 작은 개선도 포함됨(#9077, #9049, #9079, #9080, #9141)

메모리 할당과 빌드 체계

  • mimalloc 기본 할당기

    • C++와 Rust 코드가 각각 system allocator를 거치지 않고 mimalloc v2 단일 allocator instance를 공유함(#8752)
    • malloc()을 시스템 전체로 override하지 않으므로 third-party library는 자체 allocator contract를 유지함
    • JS benchmark가 전반적으로 개선됨
  • Rust 필수화와 빌드 시스템 정리

    • ENABLE_RUST 빌드 옵션이 제거되어 Rust가 필수가 됨(#8742)
    • GN build system이 완전히 제거되어 CMake가 단일 기준으로 남음(#8931)
  • GC와 메모리 관련 변경

    • -ftrivial-auto-var-init=zero로 컴파일해 함수 진입 시 오래된 GC pointer를 0으로 덮고, conservative stack scanner가 이를 덜 찾도록 함(#9171)
    • 드물게 쓰이는 UsedValues property가 lazy pointer 뒤로 이동해 struct가 424바이트 → 176바이트로 줄었고, sainsburys.co.uk 로딩 중 LayoutState::populate_node_from()139ms → 65ms로 줄어듦(#9104)
    • fetch body chunk가 pull-promise 경로를 거치며 chunk당 GC object 7개를 할당하던 구조에서 byte stream controller로 직접 들어가도록 바뀜(#9169)

개선된 사이트 동작

  • Reddit

    • Reddit 이미지 갤러리 캐러셀이 동작하며, ::slotted() matching과 split inline의 absolutely positioned descendant 주변의 서로 무관한 layout bug 2개가 수정됨(#9148)
    • TextDecoderStream 덕분에 SPA가 링크 클릭을 삼키지 않아 댓글을 열 수 있음
    • infinite scroll도 structural invalidation 작업의 영향을 받음
  • YouTube

    • YouTube는 off-thread top-level JS compile, off-thread WOFF2 decompression, @font-face fetch fanout 감소, RequestServer memory churn 수정, zero-copy TransferArrayBuffer의 영향을 받음
    • off-thread WOFF2 decompression은 Gmail에서도 약 170ms를 절약함(#8976)
    • 초기 로드에서 @font-face fetch fanout이 177 → 약 9개로 줄어듦(#9032)
  • 기타 사이트

    • gocomics.comimage-set() 덕분에 헤더 이미지가 표시됨
    • yandex.com/mapsWEBGL_debug_renderer_info 확장을 포함한 WebGL 수정으로 vector-tile WebGL 렌더링이 동작함(#9043)
    • strava.comNavigator.getBattery가 자체 오류가 아니라 spec-mandated error type을 던지게 되어 로그인이 동작함(#8770)
    • GitHub InsightsElement.matches().closest() selector cache 덕분에 약 100ms 빠르게 로드됨(#8987)
    • tweakers.net의 노트북 비교 페이지는 indexed HTMLFormElement property name lookup으로 약 31% 빨라짐(#9009)
    • neon.com은 더 이상 crash하지 않음(#8812)
    • channel4.com은 flex auto-margin resolution 수정으로 category text의 세로 정렬 문제가 해결됨(#9050)
    • Cloudflare Turnstile은 아직 통과하지 못하지만, auth-scheme handling, Array.prototype.shift() 최적화, <input> range 및 number element의 UA event handler hardening 덕분에 훨씬 빠르게 실패함(#9063)

WPT와 기타 플랫폼 변화

  • Web Platform Tests

    • WPT 점수가 2,003,537 → 2,067,263으로 올라 이번 달 63,726개 subtest 증가를 기록함
    • 다만 WPT가 공식 ECMAScript conformance suite인 test262를 upstream으로 가져오며 JavaScript subtest 53,207개가 추가됨
    • Ladybird는 test262를 수년간 별도로 실행해 왔고 LibJS conformance가 좋은 상태라 이 중 52,045개, 즉 97.8% 를 통과함
    • 63.7k 증가분 중 약 52k는 test262 import에서 왔고, 나머지 약 11.7k가 실제 새 브라우저 플랫폼 진전임
    • test262 import로 WPT가 JavaScript conformance를 나머지 플랫폼과 함께 측정하게 됨
  • 텍스트, 레이아웃, 프로세스, UI

    • ligature가 있는 텍스트의 selection과 hit testing이 한 glyph당 한 code unit을 가정하던 구조에서 grapheme cluster를 순회하고 glyph advance를 해당 grapheme들에 나누는 방식으로 바뀜(#8829)
    • shadow root에 innerHTML을 설정해도 전체 document layout tree를 무효화하지 않으며, pomax.github.io/bezierinfo에서 layout-and-paint 시간이 21% 줄어듦(#9191)
    • popup tab을 다른 site로 탐색해도 parent의 WebContent process가 종료되지 않음(#8730)
    • Qt UI에서 Ctrl+TabCtrl+Shift+Tab으로 열린 탭을 순환할 수 있음(#8704)
    • 가운데 마우스 버튼을 누른 채 드래그해 스크롤하거나, 제자리 클릭으로 autoscroll mode에 들어갈 수 있음(#8881, #8928)
    • 주소창 입력이 URL이나 검색 질의로 sanitize될 수 없을 때 입력을 조용히 버리는 대신 적절한 error page가 표시됨(#9072)
    • TextDecoder의 streaming counterpart인 TextDecoderStream이 구현됐고, chunk 경계에서 partial UTF-8을 hold-back해 Reddit 댓글 수정이 가능해짐(#9143)
    • cross-process BroadcastChannel 메시지가 WebContent와 WebWorker process 사이에서 IPC로 라우팅되어 listener가 어느 process에 있든 다른 브라우저와 같은 방식으로 동작함(#8865)
Hacker News 의견들
  • JavaScript 없는 브라우저를 쓰고 싶다면 Dioxus가 만드는 브라우저 프로토타입도 꽤 좋아지고 있음
    Rust GUI 프레임워크인 Dioxus가 네이티브 렌더러의 일부로 개발 중이며, Flutter처럼 Skia 대안을 직접 만들려는 방향이지만 Flutter web처럼 캔버스만 쓰는 대신 웹에서도 HTML/CSS 표준으로 동작함
    기존 브라우저 코드인 Chromium, Gecko, WebKit에는 의존하지 않고, Servo도 쓰는 stylo와 taffy 같은 Rust 크레이트를 활용한 거의 처음부터 만든 구현에 가까움: https://github.com/DioxusLabs/blitz (/apps/browser)
  • 브라우저 개발에서 가장 어려운 부분은 늘 인위적인 웹 호환성이었음
    많은 웹사이트가 특정 브라우저 로딩을 강제로 막고 Chromium만 허용하는데, 이게 Ladybird가 마주할 현실이고 새 브라우저 경쟁을 막는 큰 요인임
    DRM Widevine도 새 브라우저가 얻기 매우 어렵고, 사용자 1천만 명인 Zen Browser조차 확보에 실패함
    • 안타깝게도 새로운 세대가 IE의 교훈을 배우지 못했고, 다른 쪽이 Chrome OS Platform의 바람을 따르지 않으면 가장 먼저 불평하는 쪽이 됨
    • 그런 차단이 실제로 얼마나 흔한지 모르겠음
      지난 20년 동안 Firefox만 써 왔지만, 호환성을 위해 Chromium으로 바꾸라고 요구하는 사이트를 한 번도 본 적 없음
    • 이런 인위적 관문이 상호운용성에 크게 영향을 줄 정도라면 이미 장애물의 99%는 넘은 상태이고, 대부분은 User-Agent 문자열 위장으로 넘어갈 수 있음
      Widevine은 진짜 관문이 맞지만, 현실적으로는 Netflix, Disney 등 일부 스트리밍 사이트의 4K 재생을 막는 정도임
      Zen이 Widevine 없이도 사용자 1천만 명을 모았다는 점을 보면 아주 핵심적이라고 보기도 어려움
    • Ladybird는 바로 이 이유 때문에 최근 자신을 Chrome으로 보고하기 시작했음
    • 호환성 테스트 목적이라면 User-Agent를 흉내 낼 수 있음
      브라우저 자체를 제어한다면 DRM 관련 문제를 제외하고는 불가능한 게 거의 없음
  • 꽤 쓸 만해지고 있어 보임
    이런 글은 게임 에뮬레이터 업데이트를 읽을 때의 재미를 떠올리게 함
    “X 버그를 고쳐서 Y가 제대로 동작하게 되었고, 그 결과 Z 게임이 실행된다” 같은 식인데, 이번에 고친 것 중 하나가 CSS Doom이라 게임 쪽과의 겹침도 어느 정도는 있음
    • 맞는 비유임
      Andreas가 브라우저를 만드는 건 에뮬레이터를 만드는 것과 같다고 여러 번 말한 걸 들었음
      웹사이트마다 서로 다른 기능을 서로 다른 방식으로 쓰고, 그는 웹사이트를 ROM에 비유함
  • Ladybird가 정말 잘 진행되고 있음
    오래된 Firefox 사용자지만, Ladybird가 아주 초기 알파에 들어가고 미리 컴파일된 빌드가 나오기 시작하면 반드시 초기에 써볼 생각임
    • 지금 단계에서 한번 굴려보고 싶다면 로컬 빌드가 쉽고, 의존성 설치와 빌드 스크립트 실행 몇 명령이면 됨: https://github.com/LadybirdBrowser/ladybird/blob/master/Docu...
    • Mozilla는 적어도 강한 자극이 필요함
    • 직접 컴파일하기도 꽤 쉽고, 특히 Claude Code에게 해달라고 하면 더 쉬움
  • GTK4 / libadwaita frontend라니 좋음
    Qt보다 GTK UI/UX를 선호해서, 이쪽 개발 진행이 기대됨
  • strava.com : Login works now that Navigator.getBattery throws the spec-mandated error type instead of one of our own (#8770).
    Strava가 내 배터리 잔량을 왜 원하지?
    • 추적용 고유 지문 생성에 쓰려는 가능성이 가장 높음
    • 배터리 API를 저전력 버전 사이트를 고르는 휴리스틱으로 쓰는 걸 수도 있음
      개발도상국 대상 웹 전용 버전이 있을 수도 있고, 배터리가 낮으면 절약을 위해 위치 조회 빈도를 줄이려는 것일 수도 있음
      완전 추측이지만, Strava 같은 사이트가 배터리 정보를 요청하는 게 아주 말도 안 되는 일은 아니고, 다만 전반적으로 조금 수상하긴 함
    • Strava는 경로 추적 서비스임
      웹사이트로도 쓸 수 있다고 가정하면, 위치 조회 빈도를 조절해 정확도와 전력 소모 사이에서 절충하려는 것일 가능성이 큼
    • 계정을 무차별 대입하려는 봇은 실제 기기처럼 그 API를 구현하지 않았을 수 있음
  • 이전 글: https://news.ycombinator.com/item?id=47985497
  • SerenityOS가 지향하는 방향이 정말 좋고, 그 집중력을 Ladybird 브라우저에서도 유지했으면 함
  • 축하함
    다만 RTL 텍스트의 목록 마커 스크린샷은 같아 보임
    두 경우 모두 목록 마커가 왼쪽에 있음
  • https://ladybird.org/assets/img/newsletter-apr-2026-reddit-g...
    Ladybird Reddit 테스트에 Evangelion r/unixporn을 쓴 사람을 정말 존경함
    Evangelion을 많이 보진 않았지만, 해설 다큐멘터리는 수없이 봤고 한동안 배경화면으로도 썼을 만큼 좋아함
    핵심은 Reddit이 Ladybird에서 동작한다는 것이 엄청나다는 점임
    YouTube가 되는지는 모르겠지만, 그것도 동작했으면 좋겠고 Ladybird가 정말 실사용 가능해지는 느낌임
    Ladybird에 후원한 https://jakubsteplow.ski/에게도 고마움
    오픈소스 프로젝트에 기부하는 사람들을 Google 광고 같은 것보다 더 나은 방식으로 적극 알리고 싶고, Jakub에게 좋은 일만 있길 바라며, 다른 사람들도 Ladybird 같은 프로젝트에 독립적으로 기부했으면 함
    Human Rights Foundation의 https://hrf.org/program/ai-for-individual-rights/에도 고마움
    브라우저가 거의 단일/복수 과점 상태였는데 한 사람이 여기까지 해냈다는 게 놀랍고 정말 영감을 줌
    • EVA는 좋아하지만 조심스럽게 추천하고 싶음
      크게 두 면이 있는데, 하나는 멋진 미학을 가진 메카/외계인/괴물 SF이고, 다른 하나는 자기혐오와 외로움에 집중하는 개인 드라마임
      대부분에게는 첫 번째 면이 더 매력적이겠지만, 지금까지도 남아 있는 건 후자임
      보게 된다면 시청 순서를 주의해야 함
      오리지널 TV 시리즈와 영화 “End of Evangelion”으로 이어지는 타임라인이 있고, 완전한 리부트로 시작했다가 어떻게든 원작의 최종 리부트/리메이크/후속작이 된 “Rebuild of Eva” 영화 시리즈가 따로 있음
    • https://ladybird.org/#about
      “오늘 브라우저 작업을 하는 사람이 몇 명인가?”에 대한 답으로, 현재 Ladybird에는 유급 풀타임 엔지니어 8명이 있고 큰 자원봉사 기여자 커뮤니티도 있다고 되어 있음
    • YouTube는 Ladybird에서 동작함
      대부분도 동작하지만, 속도 외에 가장 큰 문제는 많은 ‘사람인지 확인’ 검사가 Ladybird에서 제대로 작동하지 않는다는 점임