본문 바로가기
Community/밋업

[밋업 #2] 시니어코딩 - 두 번째 Meet up

by Aaron-Kim 2022. 12. 29.

22.12.28.Wed

 

시니어코딩 두 번째 밋업에 참석하였습니다.

 

오늘 밋업 세션은 2가지가 있었습니다.

 

1. React Infinity Scroll 기법

2. TDD with Cypress E2E (Live Coding)

 

우선 React Infinity Scroll 입니다.

tanstack/react-query/useInfiniteQuery

  • 보이지 않는 데이터들에 대한 dom을 제거해야 하는데 제거하지 않음
  • 데이터는 많아도 되는데 dom을 반드시 제거해야 렉이 안걸림
  • 위 아래 보이는 위치 잘 정해주는 것은 좋지만 dom을 제거 안해줘서 별로 좋지 않음
  • react-query를 사용하면서 dom을 제거해주기 위해 adapter 용도로 별도 모듈 제작해보는 것은 어떨까?

intersection observer

  • 맨아래 div ref 걸고 스크롤 감지하면 뒤 array에 push 해서 작동

react-window

  • 데이터 신경 안쓰고 dom을 알아서 제거해줌
  • height가 고정형이면 쉬운데 가변형을 써야함 (ValuableSizeList)
    • 매번 height 다시 계산 필요 (개별 item height 다 가지고 계산)
  • 맨 상위로 올라가면 (스크롤 top 0) 다시 데이터를 react-query 이용해서 원하는 개수만큼 가져옴
    • react-query는 스크롤 탑 감지하고 이전 데이터 가져오는 용도로만 활용
    • 화면에 대한 것은 react-window 이용
  • 정방향이면 괜찮은데 역방향이면 height를 처음부터 계산해야 해서 깜빡꺼림 -> 보완 방법은?

 

=> 현재 회사의 한 프로젝트에서 react-query를 이용하여 infinite scroll을 구현하였습니다.

그래서 다시 확인해보니 스크롤이 내려갈 때 마다
dom이 새로 생성되면서 제거되지 않고 계속 쌓이는 모습을 볼 수 있었습니다.

인피니티 스크롤에 있어서 데이터가 많은 것은 크게 문제가 되지 않지만,
dom이 점점 쌓이는 것은 성능에 부담을 줄 수 있다고 생각됩니다.

 

intersection observer는 회사의 다른 프로젝트에서 FadeInUp 인터렉티브 효과를 주기 위해 활용한 적이 있습니다.

아래로 스크롤을 내리면서 해당 요소가 보이면 css 효과를 통해 아래에서 위로 올라오는 듯한 느낌을 제공합니다.

인피니티 스크롤로는 방법적인 부분으로만 인지하고 있었는데,
마찬가지로 intersection observer를 이용해도 dom은 계속 생성되어 남게 됩니다.

 

마지막 react-window도 사용해 본 적은 없지만 예전에 react를 학습할 때
virtualized 기법으로 오프 더 스크린 느낌으로

현재 화면에 보이는 요소가 20개라고 하면 위에 20개 아래 20개 정도 씩 해서 캐치하고 있다가

아래로 가면 방금 하단의 20개가 해당 화면에 보이는 원리 정도로만 이해했습니다.

이에 대해 react-window는 virtualized 보다 조금 더 가볍게 발전된 라이브러리로 보이고,

가변형일 때 각 height를 계산해야 하는 등 신경 쓸 것이 조금 있지만 dom을 제거해주는 좋은 기능이 있습니다.

 

다음 프로젝트를 할 때에는 intersection observer나 react-window 기법을 이용하여
다양하게 인피니티 스크롤을 구현해보면 좋을 것 같습니다.

추가적으로 JS에서 기본적인 것들 외에 Intersection 같은 내장 객체나
JS에서의 AOP 라고 불리는 Proxy 객체 등 여러 가지 것들이 많은데
시간이 되면 추후에 학습하면서 적용해보고 싶습니다.

 

 

두 번째는 TDD with Cypress입니다.

Todo App을 예제로 라이브 코딩을 해주셨는데 정말 멋지시고 좋았습니다.

저도 다음 밋업 발표 때는 라이브 코딩을 한번 해볼까 생각도 듭니다.

 

간단하게 정리하면 다음과 같습니다.

 

Test Driven Development

  • 제품 구현 전 테스트 코드 먼저 작성하고 테스트 코드 통과하면 이후 리팩토링
  • write a failing test → make the test pass → refactoring
  • test code를 요구사항 명세서처럼 작성함으로써 context가 switching 될 때 좀 더 빠르고 편하게 볼 수 있음
  • test code가 있음으로써 새로운 feature가 추가 되어도 기존 feature가 제대로 작동함을 보장 가능
  • unit test - integration test - UI test (E2E test)

E2E test with Cypress (종단간 테스트)

  • 실제 사용자의 행동 분석 및 테스트
  • component 테스트, unit test 등 가능
  • time travel; 상황마다 테스트를 통해 체크 가능 (마치 redux store 상태 보는 느낌)
  • real time reload
  • debuggability
  • automatic waiting

TO DO APP 실습

  • testing tool이므로 cypress는 devDep로 설치
  • package.json; test:e2e: cypress open
  • component test, e2e test 2가지 기능
  • e2e test
    • configuration
  • cypress.config.js
    • e2e: { baseUrl setting }
  • cypress/e2e 폴더에 작성
  • index.html
    • title
  • command.js
  • Cypress.Commands.add(’getByDataset’, (dataset) => cy.get(`data-cy=${dataset}`));
  • todo.cy.js
    • describe 함수
describe("todo app test", () => {
	beforeEach(() => {
	  // 각 함수 호출될 때 마다 반복되는 함수 지정
	  cy.visit("index.html");
	});
	context("todo app first screen", () => {
	  it("browser's title => Todo App", () => {
	    cy.title().should('eq', 'Todo App');
	  });

	  it("Heading exists", () => {
	    /* cy.get() - querySelector 같은 것, 
           data attribute 사용 권장 */
	    // cy.contains() - text 가져오기
            cy.getByDataset('todo-title').should('exist');
            cy.contains('My Todo App').should('exist');
	  });

	  it("Form exists", () => {
	      cy.getByDataset('todo-form').should('exist');
	  });
	});
	context("todo add", () => {
          it('input text', () => {
            cy.getByDataset('todo-form-input').type('Typescript Study');
            cy.getByDataset('todo-form-input').should('have.value', 'Typescript Study');
          });
      
          it('input text validation for empty', () => {
            const stub = cy.stub();
            cy.on('window:alert', stub);
            cy.getByDataset('todo-form').submit().then(() => {
              expect(stub.getCall(0)).to.be.calledWith("빈 문자열 입력 불가");
            });
          });
      
          it('input text and add -> todo list added', () => {
            cy.getByDataset('todo-form-input').type('Typescript Study');
            cy.getByDataset('todo-form').submit();
            cy.getByDataset('todo-list-container').children().each($el => {
              expect($el[0].textContent).to.equal('Typescript Study');	
            });
          });
        });
      });

 

 => TDD를 학습해야지 학습해야지 생각만 하다가 올해가 끝나갑니다.

물론 여러 가지 것들을 하려고 시도를 많이 했지만 아쉽습니다.

내년에는 TDD 학습을 해서 실제로 프로젝트에 적용까지 해보고 싶습니다.

 

오늘은 지난번에 제가 첫 발표를 한 이후에 두 분이 새롭게 좋은 주제를 가지고 세션 발표를 해주셨는데,

저도 기억 속에 잊혀져 있던 것들이 다시 새로 나오면서 인지하게 되었습니다.

다들 정말 고생 많으셨고 저도 많이 배워서 감사합니다.

 

앞으로 더더욱 열심히 해야겠다는 생각이 듭니다,

 

다들 화이팅입니다!

반응형

'Community > 밋업' 카테고리의 다른 글

[밋업 #1] 시니어코딩 - 첫 번째 Meet up  (2) 2022.12.18

댓글