Google I/O 2019: Day 2 후기


The Power of Looking up

The Power of Looking up 세션 스테이지

기술관련 세션 내용이 아니라 신청할지 고민하다가 설명에 적혀져 있는 내용이 재밌어보여서 신청해봤는데 막상 가보니 사람이 엄청 줄이 길어서 놀랐다. 알고 보니, 발표자인 메이 제미슨(Mae Jemison)은 최초의 흑인 여성 우주인으로 유명한 사람이었다. 그래서인지 참가자들의 반응이 무척 좋았다. 세션은 완전히 이해를 못했지만 약간은 철학적인 이야기였는데 “올려다 보는 것”을 통해 우리는 지구의 한 존재인 것을 확인하고 서로 연결됨을 느낄 수 있다는 이야기였다.

블랙홀 사진

이 뿐만 아니라 전혀 기대하지 않았던 스피커도 등장했는데 바로 최근에 핫 이슈였던 블랙홀 사진, 그리고 그걸 찍어냈던 팀 “Event Horizon Telescope”의 프로젝트 디렉터인 셰퍼드 도엘레만(Sheperd Doeleman)이었다. 이 분이 발표하고 난 뒤에는 기립박수까지 받을 정도로 반응이 좋았고 실제로 과학사적으로 블랙홀 사진이 큰 의미를 지닌다는 것을 느낄 수 있었다.

사실 그리고 완전히 기술과 관련이 없는 세션은 아니었다. 메이 제이슨은 일련의 과정속에서 Skyfie라는, “Looking up”할 수 있게끔 하는 앱을 실제로 출시했다. 그리고 블랙홀 사진의 경우 그것을 찍는데 성공한 것은 여러 소프트웨어가 그것을 도왔기 때문이다. 가장 흥미로웠던 건, 인류는 지금까지 블랙홀 사진을 찍어본 적이 없으므로 막상 찍더라도 그것이 블랙홀 사진이라고 확신할 수 없다는 것이었고, 이를 해결하기 위해서 시뮬레이션을 통해 관측이 예상되는 블랙홀 사진을 얻어내 실제로 비교할 수 있었다는 것이었다.

세션의 전반적인 느낌은 Google I/O가 아니라 TED에 온 것 같은 느낌을 받았다. 실제로도 두 스피커 모두 TED에서 발표한 이력이 있고, 발표자료도 Google I/O에서 지원하는 템플릿이 아니라 (본인이 자주 사용하는 것 같은) 별도의 발표자료를 가지고 발표했다. 그리고 두 사람 모두 확실히 여러번 발표한 경험때문인지 말이 너무 유창했다. (덕분에 알아듣기 어려웠지만..)

What’s new in JavaScript

당연히 들어야 할 내용이라고 생각해서 참석했다. 대부분이 Chrome에서 새롭게 구현되었거나 신규 구현될 JavaScript 문법 혹은 신규 기능에 대한 짤막한 브리핑이었다. 그 목록은 아래와 같다.

  • Class private fields: 클래스에 필드를 선언할 때 앞에 #을 붙여 Private Field로 선언할 수 있다.
  • string.matchAll(): string.match()와 거의 비슷한 API이지만 Array가 아닌 Iterator를 반환하며, 각 아이템별로 매치된 값뿐만 아니라 index 값과 원래의 문자열 값이 포함되어있다.
  • Improved numeric literals: 큰 숫자 값을 선언할 때 1_000_000 (1000000값과 같음)같은 식으로 가독성을 높일 수 있다.
  • BigInts: 큰 값의 숫자 계산을 위해 뒤에 n을 붙여 BigInt 타입을 사용할 수 있다.
  • Object.fromEntries: Object.entries의 정확한 역이다. Objectfilter, map 하기에 유용하다. 또한 Map을 인수로 넘겨서 Object를 생성하기 편리하다.
  • globalThis: JavaScript는 사용되는 플랫폼이 너무 많기 때문에 글로벌 객체를 유니버셜하게 얻기 위해서 귀찮은 처리가 필요한데, 각기 다른 이름을 가진 글로벌 객체를 유니버셜하게 globalThis로 얻을 수 있게 되었다.
  • Stable Sort: 원래 array.sort 메소드가 Stable Sort가 아니었는데 Stable Sort로 바뀌게 되었다.
  • Intl.RelativeTimeFormat: date-fns의 distanceInWords 같은 API가 추가되었다. 그러니까.. “몇 분 전” 같은 것이 추가되었고 Intl아래의 객체인 만큼 모든 언어를 지원한다. 다만 라이브러리 처럼 자동으로 적절하게 해주는 건 아니라서 여전히 라이브러리는 필요할 것으로 보인다.
  • Intl.ListFormat: List를 문자열로 표현할 때 한국어로는 “A와 B” 처럼 표기할 것이고 영어로는 “A and B” 처럼 언어 별로 다른데, 이런 일을 해주는 API가 추가되었다.
  • Intl.DateTimeFormat#formatRange: 이 API를 이용하면 기간을 표현할 수 있다. 2019년 5월 6일 - 9일 처럼 표현이 가능하다.
  • Intl.Locale: 해당 지역의 정보를 담는 로케일 객체를 만들 수 있다.
  • Promise.allSettled: Promise.all과의 차이점은 모든 Promise의 상태가 “settled”로 바뀌기만 한다는 점이다. 즉 “fulfill” 되었든 “reject”되었든 상관이 없다.
  • Promise.any: Promise.racePromise중 하나만 “settled” 되면 되지만, Promise.anyPromise 중 하나가 “fulfill” 되어야 끝난다. 즉, “reject”되면 나머지 Promise들을 계속해서 실행한다.
  • WeakRef: ES2015에 추가된 WeakMap이나 WeakSet과 비슷하게 약한 참조를 하는 객체를 만들 수 있다. JavaScript에서 극히 제한적으로 메모리를 다룰 수 있게끔 하는 것으로 보인다. 사실 아직 제대로 이해하지 못했다.

이상의 기능들은 대부분 Chrome에서만 지원하거나, 그게 아니더라도 일부 브라우저에서는 지원하지 않는데, 대부분 폴리필이 가능한 성격의 기능들이고 이미 만들어져 있어서 어렵지 않게 사용이 가능할 것 같다.

JavaScript new features

세션의 전반적인 느낌은 사실 아쉬웠다. 세션 자체가 뭔가 해석이 들어가는 내용이 아니라 그냥 새로운 기능을 단순히 전달만 하는 것이기 때문에 재미있게 만들기는 어려웠겠지만, 발표가 기계적으로 느껴졌다는 점이 다소 아쉬웠다.

WebAssembly for Web Developers

원래 듣고자 했던 세션은 아니었는데, 시간이 비어서 듣게 되었다. 하지만 다 듣고나니 듣기를 잘했다는 생각이 들 정도로 알찬 발표였다. 제목 그대로, 웹 개발자의 입장에서 웹 어셈블리가 무엇인지, 어떻게 쓰면 되는 건지 왜 좋은 건지에 대해서 설명하는 세션이었다. 내 경우에는, 웹 어셈블리에 대해서 대충 어떤 건지 들어만봤고 막연하게 나랑은 거리가 먼 기술이라고만 생각해서 크게 관심이 없었다.

이 발표는 내 고정관념을 깼다. 나는 그냥 평범한 웹 개발자로서 JavaScript를 사용할 줄 알지만 C++를 잘 쓸 줄은 모른다. 그리고 내 고정관념은 WebAssembly를 사용하기 위해서 C++ 코드를 짤 줄 알아야한다는 것이었다. 이 발표에서는 JavaScript를 사용하는 웹 개발자도 WebAssembly를 유용하게 사용할 수 있다는 것을 보여줬다.

Emscripten

Emscripten

Emscripten은 최초에 asm.js를 컴파일하기 위한 도구로 활용되었지만 이제는 WebAssembly를 컴파일하는 역할을 한다. 결론적으로 Emscripten은 POSIX 시스템 위에서 돌아가도록 만들어진 C/C++ 코드를 컴파일하기 위해, POSIX 시스템 전체를 에뮬레이션한다.

웹 생태계의 확장

웹 생태계는 이미 거대하다. npm만 보더라도 엄청나게 많은 모듈들이 등록되어있다. 하지만 어떤 경우에는 맞닥뜨린 문제가 npm 모듈로는 해결할 수 없는 반면, C / C++로 해결할 수 있는 경우가 있다. 이 경우에 WebAssembly가 도움이 될 수 있다.

대표적인 사례가 squoosh.app이다. squoosh는 이미지를 압축하는 웹 앱인데, 서버 없이도 잘 동작한다. 이미 많은 이미지 인코더가 C 혹은 C++로 쓰여져 있기 때문에 이런 인코딩 코드 베이스 자체를 가져다 써서 만들어진 것이 Squoosh다. Squoosh는 기존에 만들어져있는 C / C++ 인코딩 알고리즘, 예를 들어, mozjpeg 등을 Emscripten을 통해 WebAssembly로 만들어서 사용했다. 실제로 오픈되어있는 squoosh의 코드를 까보면 해당 부분이 어떻게 구현되어있는지 볼 수 있다.

다만 조금 의문이 드는 건 분명 C++을 배울 필요가 없다고 했지만 squoosh에서는 약간의 C++ 코드를 직접 작성해야한다는 것이다.

WebAssembly의 성능

WebAssembly는 빠르다. 하지만 요즘에 JIT 컴파일러의 성능향상을 얻은 JavaScript도 그에 못지않을 만큼 빠르다. 하지만 JavaScript의 경우 때때로 특정 코드가 특정 브라우저에서 실행될 때 예상되지 않은 실행속도를 보여주는 경우가 생긴다. 이는 각 브라우저별로 JavaScript의 성능을 최적화하는 방법이 다른 것에서 기인한 것이다. 하지만 WebAssembly의 경우 정적 타입 시스템을 사용하기 때문에 성능을 최적화하는 것이 JavaScript에 비해 훨씬 쉽고, 일관적이다(참고).

Squoosh에서는 이미지를 회전하는(Rotating) 작업을 할 때의 성능 측정을 해봤는데 브라우저 별로 실행속도가 무척 큰 차이가 나는 것을 발견했다. 빠른 경우 400ms 정도였지만, 최악의 경우 특정 브라우저에서 8초에 육박하는 시간이 걸렸다. 이를 WebAssembly로 다시 했더니 일관적으로 500ms 미만의 시간이 걸렸다. 따라서 squoosh는 Rust로 이미지를 회전시키는 로직을 작성하게 되었다.

AssemblyScript

AssemblyScript는 TypeScirpt를 WebAssembly로 컴파일하는 컴파일러다. 즉, AssemblyScript 덕분에 이미 TypeScript를 알고있는 개발자라면 WebAssembly를 쓰기 위해서 배워야할 게 별로 없다. AssemblyScript를 쓰기 위해서 추가적으로 배워야 할 것은 JavaScript에는 없지만 WebAssembly에는 있는 타입들과 메모리를 다룰 수 있는 몇가지 함수들 뿐이다. (아직 WebAssembly에는 Garbage Collector가 없다.)

WebAssembly가 빠르고 실행속도가 일관적이긴하지만 모든 코드를 WebAssembly로 짜는 것은 별로 좋지 않은 생각이다. WebAssembly는 디버깅하기 힘들고 코드 스플리팅은 더 어렵다. 그렇기 때문에 적절한 곳에만 WebAssembly를 사용하는 것이 좋다. 병목인 부분이나 JavaScript 플랫폼이 메워주지 못하는 부분을 WebAssembly로 채울 수 있다.

추가될 기능들

마지막으로 WebAssembly에 나올 새로운 기능들이 소개되었다. 이전까지 WebAssembly를 사용한 적이 없어서 모두 이해하지는 못했다. 간단한 것만 말하자면, 멀티스레드 지원이 추가될 예정이고 앞으로 더 많은 언어를 추가하기 위해 고수준 언어를 지원하기 위한 가비지 컬렉션, 함수형 프로그래밍 언어를 지원하기 위해 Tail Call Optimization 지원이 추가된다는 등의 소개가 있었다.


Google I/O 후기 포스팅

  1. Google I/O 2019: Day 1
  2. Google I/O 2019: Day 2 👈
  3. Google I/O 2019: Day 3