ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Yarn berry] Yarn Berry의 문제점
    개발 블로깅/Improving Performance 2022. 10. 19. 20:14

     

    모노레포로 사용 중인 Yarn berry 환경에서의 성능 개선을 위해 정말 이것저것 많은 노가다와 테스트를 삽질했다. 특히 pnp를 통한 zero install에 굉장히 많은 기대를 하며 기적 같은 속도 개선이 이루어지기를 바랬었다.

    그러나 결론은 아래와 같다.

     

    Yarn Berry 환경 자체가 매우 느려서 성능을 개선할 수가 없다.

     

    이전 블로그 포스팅에서도 작성했듯이, Yarn Berry 환경 자체는 단순히 자바스크립트 파일로만 동작하는 환경이다 보니, Yanr Classic 환경 위에서 또 하나의 작은 환경으로 Javascript 코드로 동작하게 된다.
    실제 shell과 다이렉트로 동작하는 게 아니다 보니 우선 느린 요소가 생길 수밖에 없을 것 같긴 하다.

     

    Yarn install

    yarn Classic과 yarn Berry의 단순히 install 속도만 비교해봐도 바로 차이를 느낄 수 있다.

    # Yarn Classic

     

    # Yarn Berry (pnp install)

     

    동일한 프로젝트로 비교해 봤을 때, Yarn Classic 환경에서 node_modules로 약 40초 정도 걸리던 것이, Yarn Berry 환경에서 pnp로 Install하면 약 80초 정도가 걸린다... (Berry 환경에서 pnp 대신 node_modules로 설치하면 200초가 걸린다..ㅎ)

     

    그러나 pnp로 zero install을 하면 어떨까?

     

    install 자체는 느리지만, pnp를 통한 zero install로 관리함으로써 install 과정 자체를 없앨 수 있다면 괜찮아질까 했다.

    그러나 이 또한 두 가지 문제를 가지고 있다.

     

    pnp zero install의 문제점

    많은 트러블 슈팅 이후 pnp 적용까지 성공시킨 뒤, 이제는 모든 dependency를 오로지 zip으로만 관리해서 완전히 install 명령어 자체를 사용하지 않는 것을 기대했다. 그러나 막상 보니 굉장히 큰 문제가 하나 있었다.

     

    pnp를 사용한다고 해서 완전히 install 과정을 없앨 수 있는 것이 아니다.

     

    안타깝게도 모든 Dependency들이 zip으로만 관리될 수 있는 것이 아니기 때문이다.

    현재 환경에 대한 바이너리 정보를 가지고 동작해야 하는 디펜던시들은, install시에 현재 환경에 대한 바이너리 정보를 수집하여 모듈이 설치가 되기 때문에, 이들은 zip 파일로 관리되지 않고 unplugged라는 디렉토리 내 별도의 바이너리 파일로 관리된다.

     

    훑어보면 nextswc, esbuild, sentry-cli와 같이 로컬에서 shell과 맞물려 사용되는 모듈들이다. 이들은 install 과정 중에 해당 환경을 읽고 바이너리 정보들을 생성한다.

    만약 install 없이 zip으로만 저장했다가 다른 ubuntu 환경 등에서 build를 수행하는 순간, build 과정 실패 혹은 run Time이 깨질 수도 있다.

    따라서 이처럼 현재 로컬 환경의 의존성을 가지는 모듈들이 있기 때문에, 완전히 install 과정 자체를 없앨 수는 없다.

     

    그래도 이미 zip 파일을 가지고 있는 상태에서 install을 하기 때문에 빠르게 설치할 수 있지 않을까 라는 희망을 가질 수도 있겠다.
    그러나 안타깝게도 이 또한 무시할 수 없을 만큼의 시간이 들게 된다.

    실제로 테스트해보니, zip 파일로 저장한 상태에서 install을 실행시켰을 때 진짜 극히 일부의 Dependency만 설치한다 하더라도 28초라는 상당한 시간이 발생했다..

    install 명령어를 수행하는 것 자체가, 그 무거운 디펜던시 모듈을 네트워크를 통해 다운로드하고, 그 많은 디펜던시 트리 정보들을 전체적으로 읽은 뒤 적절한 위치를 찾아 설치를 하는 작업을 하는 것이다 보니, 한 두 개의 install을 수행하는 것이라 하더라도 install 사이클 자체가 꽤나 무거운 작업이어서 적지 않게 시간이 걸린다.

     

    뿐만 아니라, 혹시나 install 과정을 없앨 수 있다고 하더라도 별도의 문제점이 발생한다.

     

    pnp로 설치된 zip 파일들을 커밋해서 들고 다니기엔, 사실상 매우 무겁다.

     

    pnp를 하려는 궁극적인 목적이, 많은 무거운 디펜던시들을 압축된 파일로 가볍게 만들어서 아예 커밋 자체에 저장을 해버린 뒤 install 과정 자체가 없이 들고 다니도록 하는 게 것이다.

    그러나 아무리 zip 파일로 관리한다고 해도 커밋 자체에 저장하기에는 굉장히 사이즈가 크다...

    zip 파일 양 자체도 많고, 압축파일이라 해도, 애초에 dependency 사이즈가 크다 보니 아무리 압축 파일 이어도 무시하지는 못할 정도이다.

    위에서 사용한 동일한 프로젝트에서 zip 파일의 디펜던시 전체 사이즈를 확인해 봤을 시, 간단한 디펜던시만 있음에도 불구하고 약 800MB 정도 나왔던 것 같다. 

     

    800MB라는 파일들을 커밋으로 들고 다니게 된다면 어떤 일이 발생할까?

    우선 pnp에서 Dependency 버전 업데이트 등으로 인한 Dependency Tree 변경사항이 생길 때마다 change Files 개수가 급격히 많아진다.

    아래는 단지 next 버전을 11에서 12로 변경했을 뿐인데, 158개라는 file changed가 일어났다..

    이러한 파일 변경사항이 많아지면 commit 속도와 Remote Push 속도가 꽤나 느리다.

    무엇보다 이러한 많은 file 개수들을 들고 다니는 게 옳은 건지도 모르겠다...ㅜ

     

    우선 여기까지는 pnp install 과정에 대한 문제점들을 설명해 보았는데,
    pnp 사용에 있어 install 과정뿐 아니라 다른 한 가지 문제점을 더 가지고 있다.

     

    Yarn pnp 임시 바이너리 환경


    우리 팀 내에서는 Cypress를 이용하여 intergration Test를 수행하고 있다.

    pnp를 통해 Cypress를 돌리려고 하다 보니 제대로 동작하지 않는 이슈가 있었는데, 알고 보니 cypress-io 내에서 node script로 Cypress action을 하기 위해 실행되는 index.js 파일이 npm을 통해서 수행되도록 되어 있다.

    이 말은 즉슨, yarn berry 환경인 pnp.cjs에서 동작하는 것이 아니란 것이다.

     

    GitHub - cypress-io/github-action: GitHub Action for running Cypress end-to-end tests

    GitHub Action for running Cypress end-to-end tests - GitHub - cypress-io/github-action: GitHub Action for running Cypress end-to-end tests

    github.com

     

     

     

    그래서 pnp에서 cypress run을 해주려면 yarn berry의 임시 바이너리 스크립트 환경 위에서 실행하도록 해야 한다.

    다행히 yarn berry 자체에서 이러한 기능은 쉽게 할 수 있도록 `yarn dlx`라는 명령어로 지원해주는데, 안타까운 것은 해당 환경 위해서 cypress를 띄우고 테스트 코드를 돌릴 때 굉장히 많은 시간이 소요된다.

    기존에 Yarn Classic에서 40초 정도 걸리던 테스트 코드가, yarn berry에서 돌리니 1분 50초 정도 걸린다.

     

    # Yarn Classic에서 돌린 테스트 실행 속도

     

    # Yarn Berry에서 돌린 테스트 실행 속도

     

    이 역시 환경 위에 yarn berry 환경을 하나 더 띄워서 돌리다 보니 발생할 수밖에 없는 현상인 것 같다.

     

    마치며

    Yarn Berry의 궁극적인 기대 요소였던 pnp도 결국 큰 효과를 얻을 수 없는 것을 알게 되었고, 느린 Run time 환경까지 감당해야 하는 부가적 요소까지 발생하면서, 정말 Yarn berry 환경이 우리가 가지고 가야 할 환경이 맞는지 의심이 들기 시작했다.

    혹시나 우리가 Yarn Berry라는 환경을 잘못 사용하고 있는 건가 싶어 정말 많은 리서치를 시도해 보았다.

    다른 기업의 Frontend Team에서는 Yarn Berry 환경을 꽤나 잘 이용하고 있는 것 같고, 딱히 Yarn Berry performance Issue에 대해 다룬 내용은 몇몇 개 Stack Overflow 외에는 찾을 수가 없다.

     

    다른 팀에서는 어떤식으로 Yarn Berry 사용하고 있는지 정말 궁금하다..

    반응형

    댓글

Designed by Tistory.