# 자바스크립트 최적화

최적화하는 방법은 너무나 많고, 당연한 것들은 쉽게 지나칠수있으니 조금씩 추가하도록 하겠습니다.

  1. 쓸데없는 변수의 사용을 줄여서 메모리관리

  2. 동기와 비동기함수를 고를수있는 상황이라면 대부분의 경우 비동기 함수를 고르는게 좋다.

  3. 객체의 프로퍼티를 읽을때 소소한 최적화.

아래의 코드를 보자.

이런식으로 미세하지만 조금 더 효율적인 코드로 변경할 수 있다.

function someFunc() {
  const { scrollX, scrollY } = window;
  // ...some code
}

위의 코드 또한 아주 무거운 window객체에서 프로퍼티를 여기저기서 매번 읽을거라면

변수에 담아두고 활용하면 효율적이고, 코드도 깔끔하다. 프로퍼티 참조하는것도 비용이다.

# memory leak (메모리릭)

메모리릭은 더 이상 '닿을 수 없는' 참조가 해제되지 않을 때(gc가 일어나지 않아서) 발생한다.

쉽게 말해서 쓸데없이 자원을 낭비하고 있는거다.

어떤 변수를 썼을때 자동으로 해제되지않는 경우들이다. (그래서 원시타입 변수는 무시하면 된다.)

  • 전역변수는 당연히 쓰지마라.

  • 타이머는 사용하고나면 clear해야한다.

  • 클로져는 해제하지않는 참조변수가 있으므로 필요한곳에만 적당히 쓰자.

  • 이벤트리스너를 add하고 remove하지 않은 경우

  • dom tree에서 삭제했지만 dom node에는 남아있는 경우

# hotspot - 자주 반복돼서 수행되는 구간

jit 컴파일 오버헤드. hotspot이 많을때 유리하다. 컴포넌트 기반 개발 방식은 코드를 재활용하기 좋다. jit컴파일이 코드를 최적화하는 오버헤드가 있더라도, 기존 코드를 재활용하여 개발하면, 성능상 이점을 가져올수있다.

jit컴파일이 코드를 최적화할때 오버헤드가 발생한다. (보다 효율적인 로직으로 코드를 실행하기위해서) 그런데 js는 페이지 레이아웃을 건드리거나, 사용자 입력에 반응하는 방식의 프로그램이 많은데, 한두번만 수행되는 코드가 많으면, 비효율적이다. 왜냐면 위에서 언급했듯이, 코드를 실행하기전에 컴파일러가 코드를 최적화하는데 드는 오버헤드가 있으므로. 그런데 컴포넌트 기반 개발을 하면서 코드가 재활용되는 경우가 많으므로. 한번이상 활용되는 함수같은것은 따로 빼서 관리하는것이, 최적화과정을 한번만 거치기때문에 유리하다. 깨끗한코드와 협업을 위해서도 좋다.

adaptive jitc 는 타입프로파일링을 수행하므로, 변수의 타입이 변하지않는다면 높은 성능을 얻을수있다.

js는 타입이 없다. 하지만 엔진 내부적으로는 타입이 존재한다. profiler는 사용되는 변수들의 타입이나 값을 profile해 두었다가 optimizing jit를 적용할때 이들 정보를 이용하여 예전 jitc에서 생성했던 예외처리 루틴들을 대폭 생략한 효율적인 코드를 생성한다. 이런 코드를 생성할때, 예외적으로 loop를 n번 수행하는동안 x라는 변수가 계속 int였다가, 그다음 iteration에서 갑자기 string으로 바뀌어버리는 경우, optimizing jitc로 생성된 그 효율적이었던 코드는 유효하지않게된다. 그래서 다시 예전 baseline-jitc로 생성한 코드로 수행하게된다. 예외상황이 발생하면 overhead가 커진다. Typescript와 함께 형변환을 최대한 줄이면 실제로 성능이 좋아진다.

profiling을 수행하는동안 특정변수의 타입이 변하지않으면, 그 이후에도 그 변수는 타입이 변하지않을 가능성이 높다 라는 가정하에 최적화를 하기때문에, js에서 변수의 타입을 바꾸는것은 성능상 매우매우 좋지않다. 따라서 변수의 타입을 바꾸지말아야한다. 변수의 타입이야기가 나왔는데, ==는 변수의 타입이 다르면 변환후 비교하기때문에 명시적으로 변환하여 ===로 비교하는게 낫다.