키보드 커버를 받고 사용한 지 한참이 됐습니다. 미뤄둔 포스팅을 이제야 적게 되네요. 4개월간 사용해 보고 느낀 점을 남기도록 하겠습니다.

 

1. 키보드 북커버

 

 

북커버를 딱 뜯으면 위와 같은 모양이 나옵니다. 좌측은 키보드, 우측은 후면 커버로 중간 포고핀으로 기준으로 분리되어 있습니다.

 

후면 커버입니다. 비닐로 덮인 검은 부분이 TabS6와 부착하는 접착테이프입니다.

 

접착테이프를 기준으로 위쪽은 펜을 수납할 수 있도록 꺾을 수 있게 되어 있으며 전 포스팅에서 리뷰한 바와 같이 펜 수납 방향이 맞아야 충전이 되므로 펜 수납 방향도 표기하고 있습니다.

 

아래쪽은 기울기를 조정할 수 있도록 경첩(?)이 있습니다. 우측 아래에 사용방법이 그림으로 나와있네요.

 

좌측 하단에 삼성 갤럭시 탭 S6용임을 표기하고 있습니다.

 

후면은 우측의 이미지와 같습니다. 접히는 부분이 약간 튀어나와 있으며 펜을 덮어 떨어지지 않도록 보관해 줍니다. 펜 보관하는 부분은 자석으로 되어 있습니다.

 

이 후면 커버에 접착 테이프 관련해서 논란이 좀 있습니다. 당장 삼성 공식 홈페이지의 후기만 봐도 알 수 있을 정도입니다.

 

 

별점이 말도 안 될 정도입니다. 대부분의 내용은 접착력과 관련된 내용입니다. 가능하면 한번 붙이고 안 떼는 것을 추천합니다.

 

 

좌측은 키보드 부분인데 특이점은 없습니다. 일반적인 66 키 미니 키보드와 비슷합니다. 

 

키가 화면과 직접적으로 닿지 않도록 살짝 아래로 들어가 있으며 고무로 화면과의 접촉을 막아줍니다.

 

탭 S4의 키보드 커버와는 달리 터치패드가 들어왔습니다. 거치해둔 상태에서 사용하기에 정말 편해졌습니다.

 

 

 

 

2. 사용 후기

 

뽑기운이 있는지는 모르겠으나 제가 받은 제품은 마감도 괜찮았으며 4개월간 사용하면서 고장은 나지 않았습니다.

 

후면 커버는 앞서 기술한 대로 논란이 좀 있습니다만 전 접착테이프라서 한번 붙이고 아예 떼질 않았습니다. 따라서 접착력 관련된 문제는 전혀 없었습니다.

 

그동안 몇 차례 세미나를 다니면서 사용한 바로는 키보드 기능으로서 별 불만은 없다입니다. 

 

사용성 자체는 괜찮습니다. 키감도 나쁘지 않습니다. 모든 게 적당한 느낌으로 사용했습니다. 키보드로서 빼어난 제품인가? 그렇다고 이런 걸 쓰라고 만든 건가?라는 느낌도 없이 그냥 키보드의 역할에 충실했습니다. 

 

덱스 모드와 터치패드의 결합은 정말 좋다고 봅니다. 키보드를 사용하며 엄지로 포인터를 이동시킬 수 있다는 점은 확실히 편했습니다.

 

그래서 결국 추천하느냐? 그건 또 별개의 문제라고 봅니다.

 

 

 

3. 문제점

 

이 키보드 커버를 마냥 추천할 수 없는 몇 가지 이유가 있습니다.

 

첫 번째로 두께입니다.

 

극히 일부의 사용자를 제외하고 일반적으로 태블릿은 휴대성에 포커스를 맞추고 구매를 하실 겁니다. 갤럭시 탭 S6의 공식 스펙은 다음과 같습니다.

 

 

두께고 5.7mm입니다. 본체만 놓고 보면 상당히 얇은 두께를 갖습니다. 그럼 키보드 커버의 공식 스펙을 알아볼까요?

 

 

저 수치가 "깊이"로 나와있어 "탭 S6를 감싸야하기 때문에 5.7mm를 받고 결국 키보드 커버의 두께가 1.1.mm다"는 누가 봐도 아닌 것 같습니다.

 

스펙만으로 보면 좀 이해가 안 가니까 직접 붙여둔 사진을 보겠습니다.

 

 

자 실제로 키보드 커버를 부착하고 난 뒤 저 스펙이 내가 이해한 스펙이 맞나 하는 생각이 듭니다. 확연히 느껴질 정도로 두꺼워집니다.

 

 

뭐 두꺼워진 정도야 두 번째 문제에 비하면 애교로 넘어갈 수 있는 문제입니다. 위 글을 읽으면서 뭔가 이상한 점을 못 찾으셨나요?

 

이 이상한 두 번째 문제점은 바로 무게입니다.

 

다시 한번 스펙을 비교해 봅시다.

 

 

네 키보드의 무게가 제품 무게의 85%에 달한다는 것입니다. 키보드 쪽 커버는 약 200g, 후면 커버는 약 160g입니다. 후면 커버와 키보드 커버를 끼면 무게가 무려 780g에 달합니다. 점점 더 휴대성과는 거리가 멀어지고 있습니다.

 

만약 키보드 커버를 모두 붙인 뒤 지하철에서 태블릿을 꺼내서 콘텐츠를 소비하려고 한다면 양손을 사용하는 모습을 발견하게 될 것입니다.

 

 

세 번째 문제는 키보드 비활성화 기능이 없다는 것입니다. 이건 키보드 구조 자체가 그렇게 되어있어서 어쩔 수 없이 발생하는 문제로 보입니다.

 

출근시간에 지하철에서 태블릿을 꺼냈습니다. 보통의 경우에는 키보드 커버를 뒤로 접고 사용할 겁니다. 자 이재 태블릿을 잡아봅시다. 엄지는 화면으로 가있을 것이며 나머지 네 손가락은 키보드 커버 위에 올라갈 것입니다.

 

무슨 상황이 생길까요? 손가락에 의해 눌린 키가 모두 동작하기 시작합니다.

 

이전 탭 S4의 키보드 커버는 터치패드가 없는 대신 포고핀이 키보드 커버 중간에 있었습니다. 따라서 뒤로 접었을 때 자연스레 포고핀이 분리되어 키보드가 동작하지 않았습니다.

 

반면 이번 키보드 커버는 포고핀이 키보드 커버 끝에 있기 때문에 뒤로 접어도 여전히 붙어있어 키보드가 동작합니다. 거치하지 않고 들고 사용할 땐 이 부분이 정말 불편해집니다.

 

 

 

4. 결론

 

키보드 커버를 구매하시기 전에 충분히 고민하고 한번 더 고민해 보시기 바랍니다.

 

사실 위의 문제를 한방에 날리는 방법이 있긴 합니다. 바로 키보드 쪽 커버를 떼고 후면 커버만 사용하는 겁니다. 그럼 무게도 약 580g, 손에 들고 키보드가 눌리는 문제도 해결, 두께도 대폭 줄어듭니다!

 

네 말도 안 되는 방법이지만 전 대부분의 경우에 키보드 커버를 떼고 사용해왔습니다.

 

키보드 커버가 주는 장점은 확실합니다. 하지만 단점 역시 그만큼 명확합니다. 만약 자신이 덱스 모드를 자주 사용하고 태블릿으로 문서작업을 하거나 타이핑을 할 목적으로 구매하셨다면 키보드 커버는 좋은 선택이 될 겁니다. 터치패드와 함께하는 작업은 분명 더 쾌적할 겁니다.

 

하지만 콘텐츠 소비용으로 태블릿을 구매하셨다면 키보드 커버는 과한 선택이 아닌가 싶습니다. 더 저렴하고 더 얇고 더 가벼운 북커버를 고려해 보시는 것을 추천드립니다.

 

 

 

5. 참고

 

전 북커버는 사용해 보지 않았으며 키보드 커버만 사용했습니다. 티스토리 포스팅도 대부분 PC로 작업하며 태블릿은 컨텐츠 소비, 사내 문서 확인, 필기용으로만 사용했습니다. 이런 사용자 환경의 관점에서 작성한 글임을 다시 알려드립니다.

 

북커버와 키보드 커버의 비교는 "바다 야크"님의 비교글에 잘 나와있으므로 관심 있으신 분들은 확인해 보시기 바랍니다.

 

 

반응형

 

우분투 서버에 FTP를 활성화하고 Filezilla를 사용하기 위한 서버를 설치해 봅니다.

 

 

 

1. vsftpd 설치

 

vsftpd는 Very Secure FTP로 보안을 강화한 FTP입니다. 보안뿐 아니라 성능과 안정성도 뛰어나며 FTP를 쉽게 관리할 수 있습니다.

 

다음 명령어를 통해 vsftpd를 설치합니다.

 

$sudo apt-get install vsftpd

 

 

 

 

2. 설정 변경

 

vsftpd.conf파일의 설정을 변경해 줍니다.

 

$sudo vi /etc/vsftpd.conf

 

여러 설정중 다음 설정을 변경합니다.

 

write_enable=YES

 

 

xferlog_file=/ver/log/vsftpd.log

 

 

설정 저장 후 다음 명령으로 vsftpd를 재시작합니다.

 

$sudo service vsftpd restart

 

 

 

 

3. Filezilla 서버 설치.

 

이제 FTP 구성을 마쳤으니 Filezilla를 설치해 줍니다.

 

다음 명령어를 실행해 설치작업을 진행합니다.

 

$sudo apt-get install filezilla

 

 

 

 

4. Filezilla 클라이언트 접속

 

이제 윈도우에서 클라이언트를 통해 접속하면 정상적으로 접속 처리됩니다.

 

 

 

 

 

반응형

윈격 접속을 위해 Putty를 쓰는데 vi 에디터에서 주석 처리된 글이 진짜 하나도 안 보인다.

 

 

좀 읽을 수 있도록 폰트의 컬러를 변경해 봅니다.

 

폰트 컬러 설정은 다음과 같이 설정 > Wondow > Colours에서 변경할 수 있습니다.

 

 

가장 안보였던 ANSI Blue를 찾아 RGB를 (100, 100, 255)로 변경해줬습니다.

 

 

그리고 Apply를 눌러 적용해주면 

 

 

이제 글이 제대로 보입니다.

 

 

 

반응형

 

우분투 서버 18-04.3 버전에 docker-compose를 설치해 봅니다.

 

 

 

1. docker-compose 설치하기

 

GitHub의 Compose 저장소 릴리스 페이지에서 Docker Compose 바이너리를 다운로드할 수 있습니다.

터미널에서 curl 다음 명령을 실행하여 바이너리를 다운로드해봅시다.

 

$sudo curl -L "https://github.com/docker/compose/releases/download/1.26.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

 

 

** 만약 다른 버전을 사용하고 싶으시다면 "1.26.0"을 원하는 버전으로 변경해서 다운 받으시면 됩니다.

** 만약 알파인(alpine) 버전을 다운 받았다면 py-pip, python-dev, libffi-dev, openssl-dev, gcc, libc-dev, make의 추가 패키지가 필요할 수 있습니다.

 

 

20.02.14 추가 내용

 

정확한 원인은 알 수 없으나 1.25.0 버전을 위와같이 설치하면 계속 CURL 에러가 발생합니다. 만약 반드시 1.25.0 버전이 필요한 경우가 아니라면 다음 명령어를 통해 설치하는것을 추천드립니다.

 

$sudo curl -L https://github.com/docker/compose/releases/download/1.25.4/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose 

 

 

 

2. 권한 부여

 

정상적으로 다운받았다면 다음 명령을 실행 해 바이너리에 권한을 부여합니다.

 

$sudo chmod +x /usr/local/bin/docker-compose

 

 

** 만약 명령이 실패한다면 docker-compose의 경로를 확인해 주세요.

 

 

 

3. 설치 확인

 

정상적으로 설치되었는지 다음 명령어로 확인해 봅니다.

 

$docker-compose --version

 

 

 

 

** 수정. 

2020.06.28 docker compose 버전을 1.2.5에서 1.2.6으로 변경.

 

 

반응형

 

Putty를 사용해 리눅스에 원격 접속을 할 때 Connection refused 에러가 발생해 이에 대한 해결책을 포스팅합니다.

 

 

 

1. 원인

 

제가 겪은, 가장 대표적인 원인은 openssh가 리눅스에 설치되어 있지 않아서입니다.

 

최소설치를 하거나 우분투 서버판을 설치할 때 openssh를 설치하는 옵션을 건너뛰면 발생합니다.

 

 

 

2. openssh 설치

 

무언가를 설치하기 전에 업데이트를 먼저 해줍시다.

 

$sudo apt-get update

 

 

업데이트가 완료되었으면 openssh를 설치합니다.

 

$sudo apt-get install openssh-server

 

 

 

 

3. 접속 확인

 

설치가 완료되었으면 윈도우에서 putty로 접속을 해봅시다.

 

 

별문제 없이 잘 동작하는 것을 확인할 수 있습니다.

반응형

이 글은 Velopert의 "리액트를 다루는 기술"을 참고하였습니다.

 

 

1. 불변성 관리

 

리액트를 다루면서 불변성을 유지하면서 상태를 업데이트하는 것이 중요하단 걸 모든 개발자는 알 것입니다.

이를 위해 전개 연산자 및 배열의 내장 함수를 사용하면 배열이나 객체를 복사하고 새로운 값을 덮어쓸 수 있습니다.

그러나 객체의 구조가 커지고 깊이가 깊어지면 불변성을 유지하면서 업데이트하기가 매우 힘들어집니다. 값 하나를 업데이트하기 위해 수많은 코드를 작성해야 할 수도 있습니다.

 

이러한 상황에서 immer 라이브러리를 이용하면 구조가 복잡한 객체도 짧은 코드를 사용해 불변성을 유지하면서 업데이트를 할 수 있습니다.

 

 

 

2. immer

 

Immer은 보다 편리한 방식으로 불변의 상태로 작업을 가능하게 해주는 패키지입니다. copy-on-write 메커니즘을 기반으로 합니다.

기본 아이디어는 모든 변경사항을 currentState의 프록시인 임시 draftState에 반영하는 것입니다. 

이후 모든 변경이 끝이 나면 Immer는 draftState에 대한 변경내용을 기반으로 nextState를 생성합니다.

 

 

즉, Immer는 현재 상태를 가져와서 변경 사항을 기록하기 위해 draft를 만들고 작업이 끝나면 draft를 토대로 nextState를 만듭니다.

 

기본적으로 Immer는 다음과 같이 사용합니다.

import produce from 'immer';
const nextState = produce(orgState, draft => {
  //값 바꾸기
  draft.somewhere.deep.inside = changedValue;
});

procude 함수는 두 파라미터를 받습니다. 첫 번째 파라미터는 수정하고 싶은 상태이며 두 번째 파라미터는 상태를 어떻게 업데이트할지 정의하는 함수 합니다.

draft내부에서 값을 변경하면 produce 함수가 불변성을 유지하면서 상태를 업데이트해 줍니다.

 

 

 

3. 불변성 유지를 위해 Immer를 사용하지 않을 때

 

다음 예시 코드는 Immer를 사용하지 않고 불변성을 유지할 때의 예시 코드입니다.

 

import React, {useRef, useCallback, useState} from 'react';

const App = () =>{
  const nextId = useRef(1);
  const [form, setForm] = useState({name: '', userName: ''});
  const [data, setData] = useState({
    array: [],
    uselessValue: null
  });

  const onChange = useCallback(e=>{
    const {name, value} = e.target;
    setForm({...form, [name]: [value]});
  }, [form]);

  const onSubmit = useCallback(e=>{
    e.preventDefault();
    const info = {
      id: nextId.current,
      name: form.name,
      userName: form.userName
    };
    setData({...data, array: data.array.concat(info)});
    setForm({name: '', userName: ''});
    nextId.current += 1;
  }, [data, form.name, form.userName]);

  const onRemove = useCallback(id=>{
    setData({...data, array: data.array.filter(info=>info.id !== id)});
  }, [data]);

  return(
    <div>
      <form onSubmit={onSubmit}>
        <input name="userName" placeholder="ID" value={form.userName} onChange={onChange}/>
        <input name="name" placeholder="Name" value={form.name} onChange={onChange}/>
        <button type="submit">Register</button>
      </form>
      <div>
        <ul>
          {data.array.map(info=>(
            <li key={info.id} onClick={()=>onRemove(info.id)}>
              {info.userName} ({info.name})
            </li>
          ))}
        </ul>
      </div>
    </div>
  );
}

export default App;

위와 같이 전개 연산자와 배열의 내장 함수를 사용하면 어렵진 않지만 상태가 복잡해지면 귀찮은 작업이 필요하게 될 수 있습니다. 

 

 

 

4. 불변성 유지를 위해 Immer를 사용할 때

 

다음 예시 코드는 Immer를 적용한 코드입니다.

 

import React, {useRef, useCallback, useState} from 'react';
import produce from 'immer';

const App = () => {
    const nextId = useRef(1);
    const [form, setForm] = useState({ name: '', userName: '' });
    const [data, setData] = useState({
      array: [],
      uselessValue: null
    });

  const onChange = useCallback(e=>{
    const {name, value} = e.target;
    setForm(
      produce(form, draft=>{
        draft[name] = value;
      })
    );
  }, [form]);

  const onSubmit = useCallback(e=>{
    e.preventDefault();
    const info = {
      id: nextId.current,
      name: form.name,
      userName: form.userName
    };
    setData(
      produce(data, draft=>{
        draft.array.push(info);
      })
    );
    setForm({name: '', userName: ''});
    nextId.current += 1;
  }, [data, form.name, form.userName]);

  const onRemove = useCallback(id=>{
    setData(
      produce(data, draft => {
        draft.array.splice(draft.array.findIndex(info=>info.id === id), 1);
      })
    );
  }, [data]);

  return(
    <div>
      <form onSubmit={onSubmit}>
        <input name="userName" placeholder="ID" value={form.userName} onChange={onChange}/>
        <input name="name" placeholder="Name" value={form.name} onChange={onChange}/>
        <button type="submit">Register</button>
      </form>
      <div>
        <ul>
          {data.array.map(info=>(
            <li key={info.id} onClick={()=>onRemove(info.id)}>
              {info.userName} ({info.name})
            </li>
          ))}
        </ul>
      </div>
    </div>
  );    
};

 

Immer는 필수적으로 사용해야 하는 라이브러리는 아닙니다. 사용하는 게 더 불편하다면 사용할 이유가 없습니다. 단지 복잡한 객체의 상태를 업데이트해야 할 때 많은 도움이 되며 생산성을 높여줍니다.

 

 

 

 

반응형

 

 

이 글은 Janelle WongAtomic Design Pattern: How to structure your React application를 번역한 글입니다.

 

 

 

리액트에서 애플리케이션을 확장해 나감에 따라 종종 컴포넌트 구조의 복잡도가 올라가는 것을 관리하는 것에 대한 어려움에 직면합니다. 필자가 이 포스트에서 빼버리고 싶은 것은 왜 전형적인 디자인 패턴(아토믹 디자인)을 구현하는 것이 애플리케이션 코드의 가독성, 확장성, 유연성에 중요한지 이해하는 것입니다. 아토믹 디자인 패턴은 리액트 컴포넌트 특징에 있어서 대단히 적합하다고 증명되었습니다.

 

 

 

Atomic Design

Brad Frost 와 Dave Olsen에 의해 개발된 아토믹 디자인은 다섯 가지 기초 블록으로 시스템 설계를 만들기 위한 방법론이며 이 블록을 합치면 일관성, 모듈성, 확장성을 촉진시킵니다. 이글에서는 이러한 원리들이 어떻게 React에서 인터페이스를 만들 때 자연스럽게 적합한지, 그리고 추상적 생태계 안에서 동적 수명주기의 컴포넌트를 매핑할 수 있는 것과 같이 어떻게 아토믹 은유(Atomic metaphor)를 유용한 방법으로 확장하는지에 대해 알아보겠습니다.

 

 

 

Atomic Development

아토믹 디자인은 다섯개의 레벨로 구분되어 있으며 React의 컴포넌트 기반 구조에 놀라울 정도로 잘 매핑됩니다. - 원자(Atoms) > 분자(Molcules) > 유기체(Organisms) > 탬플릿(Templates) > 페이지(Pages)

 

 

  • 원자: 버튼, 인풋, 폼라벨 등과 같은 기본적인 블록입니다. 그 자체로는 유용하지 않습니다.
  • 분자: 버튼, 인풋, 폼라벨을 묶어 기능을 만드는 것과 같이 원자 아이템을 그룹화합니다.
  • 유기체: 분자를 묶어 네비게이션 바와 같은 인터페이스에서 구분되는 부분인 유기체를 만듭니다. 
  • 탬플릿: 페이지는 주로 유기체의 그룹으로 구성되며 클라이언트가 볼 수 있는 최종 디자인입니다.
  • 페이지: 다른 템플릿의 렌더를 보는 생태계 입니다. 단일 환경(애플리케이션)에 여러 생태계 생성할 수 있습니다.

 

 

 

File Structure

리액트가 컴포넌트 기반의 구조기 때문에 컴포넌트를 기능보다 유형에 따라 구성하는 것은 꽤 일반적입니다. 만약 각각의 컴포넌트 기능에 대해 하위 생태계를 만들고 싶다면 어떻게 해야 할까요?

 

 

각각의 컴포넌트나 서비스는 자신의 인스턴스가 동작하는데 필요한 모든 것이 포함된 독립된 환경을 갖습니다. 각각의 컴포넌트, 버튼, 폼은 앱에서 독립된 요소들과 같이 동작하는 자신들의 스타일, 액션, 단위 또는 통합 테스트를 갖고 있으며 이미지나 다른 로컬 변수를 추가할 수도 있습니다. 이것은 효율적이고 일관적이며 코드 테스트를 더 쉽게 만들고 노력을 줄여줍니다.


이런 유형의 조직은 한 컴포넌트 안에 다른 컴포넌트를 중첩시킬 수 있습니다. 만약 /Delete, /Submit, /Login 또는 /Register 내부에 새 컴포넌트를 정의한다면 내부의 컴포넌트는 사촌 컴포넌트는 사용이 불가하며 바로 위의 부모 컴포넌트만 사용할 수 있습니다. 

 

 

 

왜 이런 걸 하나요?

React 파일 구조를 조직할 때 아토믹 디자인 패턴을 따르는 주요한 목적은 각각의 컴포넌트를 독립된 환경에 두는 것입니다. 부작용이 독립되어 있을 때 코드는 더 읽기 쉬워지고 모듈화 됩니다. 기능의 단일 인스턴스 테스트는 좀 더 직관적이 될 것이고 그러면 애플리케이션의 전체 품질 보증이 향상됩니다. 애플리케이션의 상태 관리의 복잡도가 증가함에 따라 이런 패턴의 파일 구조는 상태를 확인하고 다루는 데 있어서 도움이 될 것입니다.

 

 

 

아래에 정보를 얻기에 좋은 자료가 있습니다.

 

 

 

반응형

 

 

다음 글은 Simon Holdorf10 Things Front-End Developers Should Learn in 2020를 번역한 글입니다.

 

 

 

Intorduction

 

Photo by Isaac Smith on Unsplash

 

프론트 엔드 개발이 2020 년에 가장 인기 있는 기술 중 하나가 될 것이라는 데는 의심의 여지가 없습니다.


이전에는 프론트 엔드 공간의 개발자가 HTML, CSS 및 jQuery를 통해 대화형 웹 사이트를 만드는 것으로 충분했지만 오늘날에는 광범위하고 끊임없이 변화하는 기술(툴, 라이브러리 그리고 마스터해야 할 프레임워크) 생태계와 자기 계발에 끊임없이 투자해야 할 필요성에 직면 해 있습니다.


지난 몇 년 동안 ReactJS, VueJS 및 Svelte와 같은 멋진 새 라이브러리와 프레임 워크가 Javascript를 사용하여 주요 웹 애플리케이션을 구동했습니다.


이 글은 2020 년에 프론트 엔드 개발자로서 당신이 프로그래밍을 시작하거나 이미 경험을 쌓았든 상관없이 레벨 업하기 위해 집중해야 할 것에 대한 지침을 제공하는 것을 목표로 합니다.

 


 

1. Framework

 

2020년에는 아마 Facebook의 ReactJS와 커뮤니티 중심의 VueJS사이의 결투가 있을 것입니다. React는 현재 Github에서 14만 개 이상의 스타를 받았으며 Vue는 더 많은 15만 3천 개의 스타를 받았습니다. Angular로 예를 들자면 5만 3천 개 밖에 받지 못했습니다.


2019년의 Raact(파란선), Vue(빨간 선), Angular(노란 선), Svelte(초록선)에 대한 검색량에 의하면 Vue는 React보다 약간 우위에 있습니다. Angular는 자리를 지키지 못하고 있으며 Svelete는 이 비교에서 아무런 역할을 하지 못하고 있습니다.
그래서 2020년에 Javascript 프레임워크와 함께 작업하거나 작업하려는 프론트엔드 개발자는 React나 Vue를 주요한 선택으로 집중해야 합니다.  만약 거대한 엔터프라이즈 프로젝트에서 일해야 한다면 Angular는 유효한 옵션입니다.

 


따라서 2020 년 동안 JavaScript 프레임 워크와 함께 작업하거나 작업하려는 프론트 엔드 개발자는 React 및 Vue를 기본 선택에 집중해야 합니다. 대규모 엔터프라이즈 프로젝트에서 작업하는 경우 Angular는 유효한 옵션입니다.


만약 당신이 이러한 프레임워크에 대해서 좀 더 배우길 원한다면 이 훌륭한 리소스를 확인하시기 합니다: 

 

 

 

2. Static Site Generators

 

 

정적 사이트 생성기는 Server Side Rendering의 강력한 기능(SEO에 매우 중요하지만 초기 로드 시간이 있음)과 Single Page Application을 결합합니다.

 

요즘은 Next나 Nust 같은 솔루션이 마크다운 지원, 모듈 번들러, 통합 테스트 러너 등과 같은 편리한 기능을 제공하기 때문에 SSR이 필요하지 않더라도 많은 프로젝트에서 SSG를 선택합니다.

 

만약 당신이 프론트엔드 개발에 관심이 있다면 당신은 다음 프로젝트를 관심 있게 보고 실습 경험을 쌓아야 합니다.

  • Next(리액트 기반)
  • Nuxt(뷰 기반)
  • Gatsby(리액트 기반)
  • Gridsom(뷰 기반)

 

이것들은 아마 2020년에 가장 인기 있는 것들 일 것입니다. 자세한 내용을 보려면 다음 자료를 확인하세요:

 

 

 

3. JAM Stack

 

Photo by www.cygnismedia.com

 

JAM스택은 Javascript(클라이언트에서 동작하는, 예를 들면 Reacy, Nue 혹은 VanillaJS), API(서버 측 프로세스는 추상화되어있고 Javascript를 통해 HTTPS 위에서 접근됨) 그리고 Markup(배포 시 미리 빌드된 탬플릿 마크업)을 의미합니다.
이것은 웹사이트와 앱을 더 나은 성능을 위해 빌드하는 방법으로 낮은 확장 비용, 보안 강화, 더 나은 개발 경험을 제공합니다.

 

이러한 용어는 새로운 것은 아니지만 모두 웹서버에 의존하지 않는다는 공통점을 갖습니다. 따라서 Ruby나 Node.js 백엔드 또는 Drupal이나 WordPress 같은 서버 측 CMS에 의존하는 모놀리틱 앱(단일 앱)은 JAMStack으로 구축되지 않습니다.

 

만약 JAM스택으로 작업하길 원한다면 여기 모범사례들이 있습니다:

  • 모든 프로젝트가 CDN에서 제공됨: 서버가 필요 없기 때문에 모든 프로젝트는 CDM으로부터 제공받을 수 있습니다. 탁월한 속도와 성능을 제공합니다.
  • 모든 것이 Git에 있음: 누구나 DB나 복잡한 설치작업 없이 Git 저장소로부터 전체 프로젝트를 클론 할 수 있어야 합니다.
  • 자동화된 빌드: 웹 훅이나 클라우드 서비스 같은 모든 마크업은 미리 빌드되어 있기 때문에 빌드를  완벽하게 자동화할 수 있습니다.
  • 아토믹한 배포: 큰 규모의 프로젝트에서 수백, 수천 개의 파일 재배포로 인한 일관성이 없는 상태를 피하기 위해 아토믹한 배포는 변경내용이 실제 반영되기 전 모든 파일이 업로드될 때 까지 기다립니다. 
  • 인스턴트 캐시 무효화: 사이트가 운영 중일 때 CDN이 변경 사항을 확인할 수 있도록 인스턴트 캐시 제거를 처리할 수 있는지 확인해야 합니다.

 

Netfix나 Neit처럼 잘 알려진 호스트들은 JAMStack 애플리케이션을 지원하며 큰 규모의 회사는 이를 이용하여 고객에게 좋은 경험을 전달합니다.

 

이것은 분명히 2020년에 프론트엔드 개발자로서 알고 싶어 하는 것 일 겁니다. 만약 JAMStack에 대해 더 알고 싶다면 여기 좋은 자료가 있습니다.

 

 

 

4. PWA

 

 

Progressive Web App(PWA)는 2020년에 확실히 인기 있는 트렌드가 될 것입니다. 더 많은 회사들이 네이티브 앱 보다 PWA를 통해 풍부한 모바일 경험을 고객에게 제공하고 있습니다.

 

PWA는 신뢰할 수 있고(빠른 로딩, 인터넷 연결 없이 작업이 가능) 빠르며(부드러운 애니메이션, 유저 작업에 대한 빠른 응답) 매력적(네이티브 앱을 사용하는 기분, 훌륭한 UX)입니다.

 

PWA는 오프라인 기능을 위해 서비스 워커를 사용하고 전체 화면을 위해 web-app manifest 파일을 사용합니다.

 

PWA 애플리케이션을 만들어야 하는 이유는 다음과 같습니다:

  • 브라우저에서 유저의 홈 화면을 추가할 수 있음.
  • 인터넷이 연결되어 있지 않더라도 동작함.
  • 웹 푸시 알림을 지원함.
  • 구글의 Lighthouse 기능을 사용할 수 있게 함.

 

만약 PWA에 대해 더 알고 싶다면 다음 추가 자료를 확인하세요:

 

 

 

5. GraphQL

 

 

요즘 가장 인기 있는 토픽 중 하나이며 2020년에 배우거나 항상 시켜야 할 확실한 트렌드는 GraphQl입니다.

 

REST는 Stateless 서버와 같은 훌륭한 콘셉트를 제공함으로써 오랜 기간 웹 API를 설계하기 위한 사실상의 표준으로 여겨졌으나 점점 많은 이들에게 RESTful API는 급격히 변화하는 클라이언트를 따라잡기에 유연하지 않다고 여겨지고 있습니다.


GraphQL은 개발자가 RESTful API를 다룰 때 마주치는 그 이슈를 해결하기 위해서 Facebook에 의해 개발되었습니다.

REST API를 사용하면 개발자는 /users/ 엔드포인트 또는 /tours//location 엔드포인트 처럼 특정한 목적으로 생성된 여러 엔드 포인트로부터 데이터를 가져옴으로써 데이터를 수집합니다.

 

GraphQL을 이용하면 다르게 동작합니다. 개발자는 데이터 요구사항과 함께 GraphQL 서버에 쿼리를 보냅니다. 서버는 요구사항에 해당하는 모든 데이터를 JSON 객체로 반환합니다.

 

GraphQL을 사용해서 얻는 또 다른 이점은 강력한 타입 시스템을 사용한다는 것입니다. GraphQL서버의 모든 것은 GraphQL Schema Definition Language(SDL)을 사용하는 스키마를 통해 정의됩니다. 한번 스키마가 만들어지면 프론트엔드 개발자와 백엔드 개발자 모두 정의된 데이터 구조를 인지하고 있기 때문에 서로 독립적으로 작업을 할 수 있습니다.

 

GraphQL에 대해 더 자세히 알아보려면 다음과 같은 훌륭한 자료를 확인해 보세요:

 

 

 

6. Code Editors/IDEs

 

 

2019년과 마찬가지로 Microsoft의 VS Code는 2020년에도 대부분의 프론트엔드 엔지니어들에게 최고의 에디터가 될 것입니다.

 

VS Code는 코드 자동완성 및 강조 기능과 같은 IDE와 유사한 기능을 제공하며 Extension Marketpalce기능을 통해 서의 무한으로 확장할 수 있습니다.

 

특히 Marketplace는 VS Code를 매우 뛰어나게 만들어줍니다. 프론트엔드 개발자를 위한 몇 가지 훌륭한 확장 기능은 다음과 같습니다:

  • JavaScript (ES6) code snippets
  • npm
  • Prettier
  • CSS Peek
  • Vetur
  • ESLint
  • Live Sass Compiler
  • Debugger for Chrome
  • Live Server
  • Beautify

 

이것들은 꽤나 멋진 예시입니다. VS Code에는 더 많은 것들이 있으므로 아직 사용해보지 않은 경우 직접 사용해 보길 바랍니다.

 

 

 

7. Testing

 

테스트되지 않은 코드는 제품으로 도달해서는 안됩니다.


개인적인 프로젝트에서는 어떤 테스트도 없는 것이 편리해 보일지도 모르지만 상업적이고 엔터프라이즈 환경에서는 테스트가 필수적입니다. 그러므로 가능하다면 어떤 개발자든 개발 과정에서 통합 테스트를 하는 것이 낫습니다.

 

테스트 케이스들의 차이를 다음과 같이 비교할 수 있습니다: 

  • 유닛 테스트: 단일 컴포넌트나 함수를 독립적으로 테스트.
  • 통합 테스트: 컴포넌트 간의 상호작용을 테스트.
  • End-to-end 테스트: 브라우저 상에서 모든 기능을 갖춘 채 사용자의 흐름을 테스트.


수동 테스트, 스냅숏 테스트 등 더 많은 테스트 방법이 있습니다.  만약 시니어 개발자의 위치로 이동하고 싶거나 개발 표준이 존재하는 몇몇의 큰 기업에 일자리를 갖고 싶다면 테스팅 스킬을 개선하기 위해 노력해야 합니다.

 

 

 

8. Clean Code

 

클린 한 코드를 작성할 수 있는 것은 훌륭한 기술이며 많은 기관에서 높게 요구됩니다. 만약 당신이 개발자에서 선임 개발자의 위치로 오르고 싶다면 당신은 정말로 클린 코드에 대한 개념을 배워야 합니다.

 

클린 코드는 우아하고 읽기에 즐거워야 합니다. 그건 집중되어야 하고 잘 돌봐야 합니다. 모든 테스트는 클린 코드로 실행합니다. 클린 코드는 중복을 포함하지 않으며 클래스, 메서드, 함수와 같은 엔티티의 사용이 최소화되어야 합니다.

 

클린 코드를 위해서 개발자가 해야 할 몇 가지가 있습니다:

  • 변수, 클래스, 메서드, 함수에 의미 있는 이름을 지어야 합니다.
  • 함수는 작아야 하며 가능한 한 적은 매개변수를 가져야 합니다.
  • 주석은 필요하지 않습니다 - 코드 스스로가 말해주어야 합니다.

 

만약 클린 코딩에 대해 더 알고 싶다면 Robert C. Martin의 서적과 게시물을 참조하십시오.

 

 

 

9. Git

 

 

요즘의 웹 개발에 있어  Git은 의심할 여지없이 버전 관리의 표준입니다.  모든 프런트 엔드 엔지니어에게 모든 규모의 팀에서 효과적으로 잘 작동하게 하기 위해 기본 Git 개념과 워크 플로를 알고 있어야 한다는 건 정말 중요합니다.

다음은 몇 가지 잘 알려진 Git 커맨드입니다:

  • git config
  • git init
  • git clone
  • git status
  • git add
  • git commit
  • git push
  • git pull
  • git branch

 

생산성을 향상하기 위해 이러한 커맨드를 알아두는 것은 언제나 좋습니다만 프론트엔드 엔지니어들은 Git 뒤에 있는 기초 개념 또한 알아두어야 합니다. 여기 당신을 위한 몇 개의 자료가 있습니다:

 

 

 

10. Soft Skills

 

Photo by "Top 8 soft skills in UI/UX design"

 

종종 간과하곤 하지만 소프트 스킬을 배우는 것은 개발자들에게 정말 정말 중요합니다.

 

기술적 측면을 이해하는 데에 있어서 도움이 됩니다만 팀과 어떻게 의사소통하는지 아는 것도 똑같이 중요합니다. 만약 당신이 기술경력에 진지하거나 선임직 위치로 옮길 계획이 있다면 이러한 소프트 스킬을 배워야 합니다.

  • 감정 이입(Empathy)
  • 의사소통(Communication)
  • 팀워크(Teamwork)
  • 다가감과 돕는 것(Approachability and helpfulness)
  • 인내(Patience)
  • 열린 생각(Open-mindedness)
  • 문제 해결(Problem-solving)
  • 책임(Accountability)
  • 창의력(Creativity)
  • 시간 관리(Time management)

 

항상 염두에 두세요: 선임 개발자를 위한 가장 중요한 결과물은 선임 개발자입니다.

p.s) 이문장의 뜻을 잘 모르겠습니다. 원문은 "The most important deliverable for a senior developer is more senior developers." 입니다.

 

 


 

Conclusion

 

이 글에서 2020년에 프론트엔드 개발자가 배우거나, 향상하거나, 마스터해야 할 열 가지 중요한 것들에 대해 보여주었습니다.


이 리스트는 완전하지는 않지만 내년에 대한 영감을 주길 바랍니다. 선택은 당신의 것입니다.

 

 

 

반응형

PWA, SPA, SEO 관련 내용은 다음 글을 확인해 주세요.

 

 

1. 목차

 

  • PWA
  • SPA
  • SEO
  • AMP
  • Babel
  • TypeScript
  • JavaScript Framework
    • Angular
    • React
    • Vue

 

4. AMP

 

AMP란?

 

AMP는 구글이 2015년 10월 초에 발표한 프로젝트로 Accelerated Mobile Pages(APM)를 의미합니다. AMP(Accelerated Mobile Pages)는 지연 없이 페이지에 바로 액세스 가능하게 하는 프레임워크로 다양한 웹 기반의 기술을 사용해 모바일 웹의 성능을 높이기 위한 목적을 가지고 있습니다. AMP는 모든 형태의 웹페이지를 대상으로 하기보다는 읽기에 적합한(reading content) 콘텐츠를 대상으로 하고 있습니다.

 

 

AMP의 구성요소

 

AMP 형태로 페이지를 구성하려면 AMP 프레임워크 가이드라인에 맞추어 페이지를 개발해야 합니다. AMP는 다음과 같이 크게 3개의 영역으로 구성되어 있습니다.

 

 

A. AMP HTML

 

일반적인 AMP HTML의 구조는 다음과 같습니다.

 

<!doctype html>  
<html amp lang="en">  
  <head>
    <meta charset="utf-8">
    <title>Hello, AMPs</title>
    <link rel="canonical" href="http://example.ampproject.org/article-metadata.html" />
    <meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
    <style>body {opacity: 0}</style><noscript><style>body {opacity: 1}</style></noscript>
    <script async src="https://cdn.ampproject.org/v0.js"></script>
  </head>
  <body>
    <h1>Welcome to the mobile web</h1>
  </body>
</html>  

 

일반적인 HTML 구조와 비슷하지만, 몇가지 제약 사항들이 있습니다.

  • 문서의 FOUC를 방지하기 위해 opacity:0을 지정
  • 일반적인 태그들의 사용이 제한되며, 제공되는 custom tag(웹 컴포넌트의 custom element)를 사용 
  • 사용자 작성 및 써드파티 스크립트가 허용되지 않음

 

B. AMP JS

 

위의 AMP HTML 구조에서 보듯이 https://cdn.ampproject.org/v0.js는 기본적으로 포함되어야 합니다. 이 JS의 역할은 다음과 같습니다.  

 

  • Async to the max:  모든 외부 JS 파일들은 비동기로 처리
  • DNS prefetching/preconnect 힌트를 통해 DNS lookup 시간을 줄이도록 처리
  • Download-independent sizing : 이미지등에 대해 정해진 크기의 값으로 설정해, 리플로가 발생하지 않도록 처리
  • Smart content prioritization : 필요한 콘텐츠만 로드 되록 함.
  • Limited by design : 디자인 항목 제한.
    • 사용자 JS 로딩을 제한해 병목 현상 발생 요인을 차단
    • 일부 태그를 제한하며, 기본적인 CSS 선택자만 사용
    • 스크롤 요소를 배제하며, stylesheets는 50k 미만만 허용

C. AMP CDN

 


CDN을 통해 쉽게 캐싱될 수 있도록 디자인되었으며, 구글에서 제공하는 CDN 서비스를 통해 제공하도록 하거나 직접 구축하거나 또는 일반적인 웹 서버를 통해 서비스할 수도 있습니다.

 

AMP에 대한 자세한 내용은 AMP공식 홈페이지에서 확인하시기 바랍니다.

 

 

 

5. Babel

 

바벨은 무료 오픈 소스 자바 스크립트 transpiler입니다.  트랜스파일러란 한 프로그래밍 언어로 작성된 소스 코드를 읽고 다른 프로그래밍 언어로 동등한 코드를 생성하는 도구입니다. 바벨에선 ES2015 이후의 문법으로 적힌 JavaScript를 지금 구형 브라우저에서도 사용할 수 있게 변환해주는 역할을 합니다.

Babel은 Pollyfill을 사용 하여 JavaScript 환경에서 누락된 기능을 지원합니다. 폴리필이란 웹 개발에서 기능을 지원하지 않는 웹 브라우저 상의 기능을 구현하는 코드를 뜻합니다. 즉 바벨은 ES2015에서 지원하지 않는 ES6의 기능을 추가 코드를 삽입하여 가능하게 해 줍니다. 

예를 들어 Array.from및 Promise기능은 ES6이상의 버전에서만 사용할 수 있습니다. 하지만 바벨의 폴리필 기능을 이용해 ES6을 지원하지 않는 브라우저에서도 해당 기능을 사용할 수 있습니다.

 

바벨은 그 자체로는 아무것도 수행하지 않습니다 ".babelrc"라는 설정 파일에 바벨이 수행할 모든 동작을 정의해 주어야 합니다. 

{
  "presets": ["es2015", "react"],
  "plugins": []
}

npm 등으로 바벨 및 필요한 프리셋을 설치 후 ".babelrc"에 설정한 후 실행시키면 적합한 버전에 알맞은 js파일이 트랜 스파 일링 됩니다.

 

 

 

6. TypeScript

 

TypeScript는 오픈 소스 순수 객체 지향 프로그래밍 언어입니다.  TypeScript는 Apache2 라이선스에 따라 Microsoft 에서 개발 및 유지 보수됩니다.

 

TypeScript의 위치는 위 그림과 같습니다. Javascript로 컴파일 되는 Javascript의 수퍼셋이라고 합니다. 컴파일이 필요하므로 타입 스크립트를 브라우저에서 바로 사용할 순 없습니다. 

 

위 통계자료에서 보듯이 타입스크립트에 대한 관심은 점차 확대되어가고 있습니다.

 

타입 스크립트는 컴파일이 필요한 새로운 언어입니다. 대부분의 사람들이 JS를 사용할 수 있는데 굳이 새로운 언어를 다시 배워야 하는 것에 대한 거부감이 타입 스크립트 도입에 가장 큰 결점일 것입니다.

그러나 타입 스크립트를 도입하게 되면 그동안 js에서 느꼈던 결점을 대부분 보완해 줍니다. 인텔리센스를 통해 자동완성 기능을 제공해주며 명시적 형식의 선언으로 인해 컴파일 단계에서 오류를 줄일 수 있습니다. 또한 C# 및 Jave와 유사한 문법 스타일을 갖고 있으며 큰 규모의 js 프로젝트의 경우 복잡도를 많이 낮출 수 있습니다.

 

 

바벨과 타입스크립트

 

그러면 바벨과 타입스크립트 중에서 어떤 걸 사용해야 할까요? 사실 정답은 없습니다. 이에 대한 내용은 이 글을 참조해 주시기 바랍니다. 심지어 이 글에서는 둘 다 사용하는 것을 추천하기도 합니다.

 

아래의 표를 통해 서로의 특징을 비교해보고 사용하는것을 추천드립니다.

 

타입스크립트 바벨
TypeScript는 오픈 소스 순수 객체 지향 프로그래밍 언어입니다. 일반 JavaScript로 컴파일되는 강력한 형식의 JavaScript 수퍼셋 입니다. Babel은 무료 오픈 소스 JavaScript 트랜스파일러입니다. 주로 ES6 이상 버전 코드를 모든 브라우저에서 실행할 수있는 이전 버전과 호환되는 JavaScript의 ES5로 변환하는 데 사용됩니다.
프로그래밍 언어 입니다. 트랜스파일러이며 툴 입니다.
데이터 형식 확인 기능이 있습니다. 테이터 형식을 신경쓰지 않습니다.
모든 프로젝트의 파일을 한번에 컴파일합니다. 한번에 한 파일씩 트랜스파일링 합니다.
뛰어난 형식(type) 기능을 사용할 수 있으며 큰 어플리케이션을 개발하는데에 좋습니다. 최신 언어 기능을 사용하여 일반 JavaScript 코드를 작성하려는 개발자에게 적합합니다.
강력한 타이핑(type)이 가능한 JS의 추가 애드온입니다. 새로운 JS 구문 기능을 입력으로 사용하고 이전보다 안정적인 구문을 출력으로 리턴하는 변환기입니다.
Microsoft에서 개발하고 유지 관리합니다. ECMA 기술위원회 39 (TC39)와 밀접하게 연결되어 있습니다.
데코레이터를 직접 컴파일합니다. 바벨은 데코레이터를 직접 컴파일하지 않습니다. 데코레이터를 이전 버전으로 컴파일하는 레거시 모드가 있습니다.

 

 

 

 

References

반응형

 

1. 목차

 

  • PWA
  • SPA
  • SEO
  • AMP
  • Babel
  • TypeScript
  • JavaScript Framework
    • Angular
    • React
    • Vue

 

 

2. PWA

 

PWA란?

 

프로그레시브 웹앱(Progressive Web Apps)은 Google I/O 2016에서 소개된 미래의 웹 기술이며, PWA라고 줄여서 부르기도 합니다. PWA는 최고의 웹과 최고의 앱을 결합한 경험을 일컫습니다. 쉽게 말하자면, PWA는 모바일 앱과 웹 기술의 장점을 결합한 것입니다. 

 

 

왜 PWA를 도입해야 하는가? - Native 앱의 낮은 접근성

 

위 통계치에서 보듯이 모바일 사용자는 웹 보다 네이티브 앱을 더 많이 이용합니다. 문제는 대부분의 사용자는 새로운 앱을 거의 설치하지 않으며 자신이 사용하던 앱만 사용한다는 것입니다. 그에 반해 사용자들은 월평균 100개 이상의 새로운 사이트를 방문한다고 합니다.

 

결론은 바로 이것입니다. 네이티브 앱의 장점인 수용력과 웹의 장점인 접근성을 동시에 추구하는 것이 바로 PWA입니다.

 

 

PWA: 웹 앱을 구축하는 새로운 철학.

 

 

PWA는 브라우저를 통해 처음 방문한 사용자에게 유용하며, 설치가 필요하지 않습니다. PWA는 사용자가 관계를 점진적으로 형성할수록 성능이 더욱 강력해질 것입니다. 느린 네트워크에서도 빠르게 로드되고, 관련된 푸시 알림을 전송할 수 있습니다. 모바일 앱처럼 전체 화면으로 로드되고, 홈 화면에 아이콘이 표시됩니다. 

 

 

( HTTPS, WebApp Manifest, Service Worker ) -> PWA

PWA를 위해선 다음과 같은 요소가 반드시 필요합니다.

  1. HTTPS를 운영해야 합니다. 
  2. 웹 앱 매니페스트(Web App Manifest)가 있어야 합니다.
  3. 서비스 워커를 사용해야 압니다.

PWA는 운영체제의 여러 특별한 권한을 부여받기 때문에, 웹 서버와의 보안 연결(HTTPS)은 필수입니다. 웹 앱 매니페스트라는 이름만 보고 겁낼 필요는 없습니다. 단지 사이트와 관련된 정보를 담는 JSON 파일일 뿐입니다.

 

 

서비스 워커

 

서비스 워커는 브라우저가 백그라운드에서 실행하는 스크립트로, 웹페이지와는 별개로 작동하고 클라이언트에 설치되는 프록시입니다. 브라우저 백그라운드에서 네트워크를 가로채는 Thread Thread라고 이해하시면 됩니다.

서비스 워커는 오프라인 환경을 완벽히 통제할 수 있는 권한을 개발자에게 부여하여 오프라인 환경을 지원할 수 있도록 해주기 때문에 PWA에서 반드시 필요합니다.

, 서비스 워커가 동작하는 브라우저를 미리 확인해야 하며 레거시 브라우저 (예를 들면 IE)에서는 동작하지 않을 수 있습니다.

 

 

 

2. SPA

 

SPA란?

 

단일 페이지 애플리케이션(Single Page Application, SPA)은 모던 웹의 패러다임입니다. SPA는 기본적으로 웹 애플리케이션에 필요한 모든 정적 리소스를 최초에 한번 다운로드합니다. 이후 새로운 페이지 요청 시, 페이지 갱신에 필요한 데이터만을 전달받아 페이지를 갱신하므로 전체적인 트래픽을 감소시킬 수 있습니다. 또한 전체 페이지를 다시 렌더링 하지 않고 변경되는 부분만을 갱신하므로 새로고침이 발생하지 않아 네이티브 앱과 유사한 사용자 경험을 제공할 수 있습니다.

 

실제로 전통적인 MPA방식에서는 서버에서 렌더링 작업을 수행한 후 HTML을 클라이언트에 리턴하며 이 HTML의 내용대로 페이지를 새로고침 하게 됩니다. 

그러나 SPA 방식에서는 서버에서 렌더링 작업을 수행하지 않으며 요청한 데이터 파일만 클라이언트로 리턴합니다. 이후 클라이언트에서는 이 데이터 파일을 토대로 다시 렌더링이 필요한 부분만 변경하여 새로고침 과정을 생략합니다.

 

 

Progressive Single Page Application

 

 

결국 SPA가 추구하는 핵심적인 가치는 웹의 UX 및 속도를 향상함으로써 사용성을 극대화하는 것이라 할 수 있습니다특히 모바일 환경에서는 트래픽 최소화와 속도 및 반응성, 사용성 등이 보다 중요한 이슈이므로 SPA 구조는 모바일 퍼스트(Mobile First) 전략에서는 거의 모범사례에 가까운 모델이라 할 수 있습니다.

 

앞서 설명한 PWA 역시 모바일 환경에서의 웹의 사용성을 향상하는 일환으로 대두되고 있습니다. PWASPA를 직접적으로 포함하는 개념은 아니지만 SPA 구조는 PWA와 궁합이 잘 맞는 선택이며 PWA 방식으로 만들어진 웹은 대부분 SPA입니다.

 

 

모든 게 완벽한 실버 불릿일까?

 

SPA를 도입하면 다음과 같은 장점이 있습니다.

  • 자연스러운 UX
  • 필요한 리소스만 부분적으로 로딩하여 성능 향상.
  • 서버의 탬플릿 연산을 클라이언트로 분산 가능.
  • 컴포넌트 기반 개발에 용이함.
  • 모바일에서 동일한 API를 사용하도록 설계 가능.

빠른 반응성과 화면 전환 애니메이션, 그리고 새로고침이 없는 자연스러운 UX, 모든 페이지를 로딩하지 않고 필요한 부분만 업데이트를 수행해 성능이 개선되며 모듈화 및 컴포넌트화를 통해 유지보수가 쉽고 개발이 편합니다.

 

그러나 실버 불릿은 없다 라는 말 대로 SPA는 장점만 존재하는 기술은 아닙니다. SPA를 도입하면 다음과 같은 문제점을 맞닥뜨리게 될 수 있습니다.

  • 상대적으로 느린 초기 구동 속도.
  • 어려운 검색엔진 최적화
  • 보안 이슈
  • 구형 브라우저 미지원

이러한 문제를 해결하기 위해선 추가적인 노력이 필요합니다.

 

상대적으로 느린 초기 구동 속도는 Lazy Loading을 사용해 필요한 데이터를 필요할 때 청크 단위로 받도록 함으로써 로딩 속도를 많이 개선할 수 있습니다.

대부분의 크롤러는 브라우저가 아니므로 렌더링 한 결과 페이지를 획득할 수 없습니다. 따라서 빈 페이지를 받게 되어 SPA는 검색 결과에 노출되지 않을 수 있습니다. 검색엔진 최적화는 별도로 설명하겠습니다. 

SPA에서 보안 이슈의 핵심은 비즈니스 로직이 JS로 구현되어 있다는 점입니다. 이로 인해 클라이언트단에서 로직이 노출될 수 있으며 압축 및 난독화로 해결될 문제가 아니므로 설계상에서부터 고민해야 할 문제가 됩니다. 이 경우 핵심 로직은 서버에서 수행하도록 구현해야 합니다. 또한 당연한 말이지만 중요한 데이터의 경우 유효성 검사를 양측 모두에서 수행해야 합니다.

구형 브라우저 미지원 문제는 마땅한 방법이 없습니다. 초기 SPA 도입 시 꼭 IE를 사용해야 하는지 고민후 작업에 착수해야 합니다.

 

 

 

3. SEO

 

SEO란?

 

SEO란 Search Engine Optimization, 검색 엔진 최적화의 약자입니다. 대부분의 사이트는 검색엔진에 잘 노출될수록 좋습니다. 이는 당연히 마케팅에도 긍정적인 효과를 발휘합니다. 아무리 PWA와 SPA를 이용해 UX를 극대화시킨 사이트를 만들어 놓았더라도 실제 사용자가 검색할 수 없다면 무슨 소용일까요?

 

SPA... Empty page?

 

위에서 잠깐 설명했지만 크롤러는 브라우저가 아닙니다. 크롤러가 SPA로 만들어진 사이트를 방문하면 다음과 같은 페이지를 획득할 것입니다.

 

크롤러는 내용이 전혀 없는 빈 페이지로 인식할 것입니다. 이렇게 되면 검색되어도 내용이 없는 페이지로 보이거나 심지어 검색이 되지 않을 수도 있습니다.

SEO에는 여러 다양한 기법이 있습니다만 이번에는 SPA로 인해 발생한 문제를 해결하기 위한 SEO방법에 대해서만 알아보도록 합니다.

 

메타 태그만 넣어주기.

 

클라이언트 측에 렌더링 하지는 않고, 서버 쪽에서 라우트에 따라 필요한 메타태그만 넣어주는 방법입니다. SNS 공유를 할 때 내용이 잘 전달되게 할 때 매우 적합한 방식입니다. 이러면 크롤러에선 해당 페이지에 대한 기본 정보는 얻어 갈 수 있게 됩니다.

실제로 facebook을 비롯한 SNS에서 신경 써줘야 할 부분은 내가 서비스하고 있는 URL의 링크와 미리 보기 같은 기능이 정상적으로 작동하는가입니다.

 

Prerender 사용하기.

Prerender는 아예 자바스크립트 렌더링 엔진을 갖고 있습니다. 따라서 코드를 문자열 형태로 변환을 하는 게 아니라 자바스크립트 코드를 실행시켜 뷰를 렌더링 한 결괏값을 반환합니다. 렌더링 속도는 그렇게 빠르지 않기 때문에 이 서비스는 오직 검색엔진 최적화를 위해서만 사용됩니다. 크롤러 봇이 해당 페이지에 들어온 경우에만 대신 렌더링을 해줘서 반환을 해주는 것이죠.

 

Prerender는 상용 서비스입니다. 미리 렌더링 해야 할 페이지의 수와 캐싱 주기에 따라 가격이 달라집니다.

자세한 내용은 공식 홈페이지를 참조해 주시기 바랍니다.

 

SSR

 

전통적인 MPA에서는 SEO 관련 이슈가 적었습니다. 전통적인 MPA의 경우 브라우저에서 JavaScript 코드가 동작하기 전에도 완성된 형태의 탬플릿(HTML에 데이터가 삽입된 상태)을 서버로부터 전달받습니다. 이 때문에 JavaScript 를 구동하지 않는 모르는 검색 로봇이 페이지를 크롤링하기에 매우 매우 적합합니다.

 

문제는 이런 방식으로 렌더링을 하다 보면 SPA를 도입한 장점을 포기해야 한다는 점입니다. 이러한 문제를 해결하기 위해서 구글에서는 "Dynamic Rendering"이라는 개념을 발표했습니다.

 

Dynamic Rendering

 

"현재는 자바 스크립트를 처리하기가 어렵고 모든 검색 엔진 크롤러가 자바 스크립트를 성공적으로 또는 즉시 처리할 수 있는 것은 아닙니다. 앞으로는 이 문제를 해결할 수 있기를 희망하지만 그동안 이 문제에 대한 해결 방법으로 동적 렌더링을 권장합니다. 동적 렌더링은 특정 사용자 에이전트에 대해 클라이언트 측 렌더링 콘텐츠와 사전 렌더링 된 콘텐츠 간 전환을 의미합니다."

 

동적 렌더링을 위해서는 웹 서버가 사용자 에이전트 확인 등의 방법으로 크롤러를 감지해야 합니다. 크롤러의 요청은 렌더러로 라우팅 되고 사용자의 요청은 정상적으로 제공됩니다. 필요한 경우 동적 렌더러는 크롤러에 적합한 콘텐츠 버전을 제공합니다. 예를 들어 정적 HTML 버전을 제공할 수 있습니다. 모든 페이지 또는 페이지마다 동적 렌더러를 사용하도록 선택할 수 있습니다.

 

동적 렌더링을 사용하면 사이트의 구조를 변경할 필요가 없습니다. 크고 빠르게 변하는 사이트에 적합할 수 있습니다만 별도의 렌더링 서버를 운영해야 할 수도 있습니다.

 

Hybrid Rendering

 

하이브리드 렌더링은 사실 새로운 개념이 아닙니다. 이것은 크롤러와 사용자 모두에게 정적 HTML을 제공하는 것을 의미합니다. 그런 후 나머지 항목을 표시하기 위해 JS를 실행하는 개념입니다. 

 

* FCP: First Contentful Paint. 요청된 콘텐츠가 표시되는 시간.
* TTI: Time To Interactive. 요청된 페이지를 사용할 수 있을 때까지 걸리는 시간.

 

크롤러와 사용자 모두 정적 HTML을 전달받으므로 SEO를 해결할 수 있으며 빠른 페이지 로딩이 가능합니다. 문제는 가능한 모든 URL에 대해 개별 HTML 파일을 생성해야 한다는 것입니다. URL을 미리 예측할 수 없거나 고유 한 페이지가 많은 사이트의 경우 예측하기 어려울 수 있습니다.

 

 

 

 

 

References.

 

반응형

+ Recent posts