리액트에서 애플리케이션을 확장해 나감에 따라 종종 컴포넌트 구조의 복잡도가 올라가는 것을 관리하는 것에 대한 어려움에 직면합니다. 필자가 이 포스트에서 빼버리고 싶은 것은 왜 전형적인 디자인 패턴(아토믹 디자인)을 구현하는 것이 애플리케이션 코드의 가독성, 확장성, 유연성에 중요한지 이해하는 것입니다. 아토믹 디자인 패턴은 리액트 컴포넌트 특징에 있어서 대단히 적합하다고 증명되었습니다.
Atomic Design
Brad Frost 와 Dave Olsen에 의해 개발된 아토믹 디자인은 다섯 가지 기초 블록으로 시스템 설계를 만들기 위한 방법론이며 이 블록을 합치면 일관성, 모듈성, 확장성을 촉진시킵니다. 이글에서는 이러한 원리들이 어떻게 React에서 인터페이스를 만들 때 자연스럽게 적합한지, 그리고 추상적 생태계 안에서 동적 수명주기의 컴포넌트를 매핑할 수 있는 것과 같이 어떻게 아토믹 은유(Atomic metaphor)를 유용한 방법으로 확장하는지에 대해 알아보겠습니다.
Atomic Development
아토믹 디자인은 다섯개의 레벨로 구분되어 있으며 React의 컴포넌트 기반 구조에 놀라울 정도로 잘 매핑됩니다. - 원자(Atoms) > 분자(Molcules) > 유기체(Organisms) > 탬플릿(Templates) > 페이지(Pages)
원자: 버튼, 인풋, 폼라벨 등과 같은 기본적인 블록입니다. 그 자체로는 유용하지 않습니다.
분자: 버튼, 인풋, 폼라벨을 묶어 기능을 만드는 것과 같이 원자 아이템을 그룹화합니다.
유기체: 분자를 묶어 네비게이션 바와 같은 인터페이스에서 구분되는 부분인 유기체를 만듭니다.
탬플릿: 페이지는 주로 유기체의 그룹으로 구성되며 클라이언트가 볼 수 있는 최종 디자인입니다.
페이지: 다른 템플릿의 렌더를 보는 생태계 입니다. 단일 환경(애플리케이션)에 여러 생태계 생성할 수 있습니다.
File Structure
리액트가 컴포넌트 기반의 구조기 때문에 컴포넌트를 기능보다 유형에 따라 구성하는 것은 꽤 일반적입니다. 만약 각각의 컴포넌트 기능에 대해 하위 생태계를 만들고 싶다면 어떻게 해야 할까요?
각각의 컴포넌트나 서비스는 자신의 인스턴스가 동작하는데 필요한 모든 것이 포함된 독립된 환경을 갖습니다. 각각의 컴포넌트, 버튼, 폼은 앱에서 독립된 요소들과 같이 동작하는 자신들의 스타일, 액션, 단위 또는 통합 테스트를 갖고 있으며 이미지나 다른 로컬 변수를 추가할 수도 있습니다. 이것은 효율적이고 일관적이며 코드 테스트를 더 쉽게 만들고 노력을 줄여줍니다.
이런 유형의 조직은 한 컴포넌트 안에 다른 컴포넌트를 중첩시킬 수 있습니다. 만약 /Delete, /Submit, /Login 또는 /Register 내부에 새 컴포넌트를 정의한다면 내부의 컴포넌트는 사촌 컴포넌트는 사용이 불가하며 바로 위의 부모 컴포넌트만 사용할 수 있습니다.
왜 이런 걸 하나요?
React 파일 구조를 조직할 때 아토믹 디자인 패턴을 따르는 주요한 목적은 각각의 컴포넌트를 독립된 환경에 두는 것입니다. 부작용이 독립되어 있을 때 코드는 더 읽기 쉬워지고 모듈화 됩니다. 기능의 단일 인스턴스 테스트는 좀 더 직관적이 될 것이고 그러면 애플리케이션의 전체 품질 보증이 향상됩니다. 애플리케이션의 상태 관리의 복잡도가 증가함에 따라 이런 패턴의 파일 구조는 상태를 확인하고 다루는 데 있어서 도움이 될 것입니다.
프론트 엔드 개발이 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는 유효한 옵션입니다.
만약 당신이 이러한 프레임워크에 대해서 좀 더 배우길 원한다면 이 훌륭한 리소스를 확인하시기 합니다:
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에 대해 더 알고 싶다면 여기 좋은 자료가 있습니다.
요즘 가장 인기 있는 토픽 중 하나이며 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)을 사용하는 스키마를 통해 정의됩니다. 한번 스키마가 만들어지면 프론트엔드 개발자와 백엔드 개발자 모두 정의된 데이터 구조를 인지하고 있기 때문에 서로 독립적으로 작업을 할 수 있습니다.
AMP는 구글이 2015년 10월 초에 발표한 프로젝트로 Accelerated Mobile Pages(APM)를 의미합니다. AMP(Accelerated Mobile Pages)는 지연 없이 페이지에 바로 액세스 가능하게 하는 프레임워크로 다양한 웹 기반의 기술을 사용해 모바일 웹의 성능을 높이기 위한 목적을 가지고 있습니다. AMP는 모든 형태의 웹페이지를 대상으로 하기보다는 읽기에 적합한(reading content) 콘텐츠를 대상으로 하고 있습니다.
AMP의 구성요소
AMP 형태로 페이지를 구성하려면 AMP 프레임워크 가이드라인에 맞추어 페이지를 개발해야 합니다. AMP는 다음과 같이 크게 3개의 영역으로 구성되어 있습니다.
바벨은 무료 오픈 소스 자바 스크립트 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)와 밀접하게 연결되어 있습니다.
데코레이터를 직접 컴파일합니다.
바벨은 데코레이터를 직접 컴파일하지 않습니다. 데코레이터를 이전 버전으로 컴파일하는 레거시 모드가 있습니다.
프로그레시브 웹앱(Progressive Web Apps)은 Google I/O 2016에서 소개된 미래의 웹 기술이며, PWA라고 줄여서 부르기도 합니다. PWA는 최고의 웹과 최고의 앱을 결합한 경험을 일컫습니다. 쉽게 말하자면, PWA는 모바일 앱과 웹 기술의 장점을 결합한 것입니다.
왜 PWA를 도입해야 하는가? - Native 앱의 낮은 접근성
위 통계치에서 보듯이 모바일 사용자는 웹 보다 네이티브 앱을 더 많이 이용합니다. 문제는 대부분의 사용자는 새로운 앱을 거의 설치하지 않으며 자신이 사용하던 앱만 사용한다는 것입니다. 그에 반해 사용자들은 월평균 100개 이상의 새로운 사이트를 방문한다고 합니다.
결론은 바로 이것입니다. 네이티브 앱의 장점인 수용력과 웹의 장점인 접근성을 동시에 추구하는 것이 바로 PWA입니다.
PWA: 웹 앱을 구축하는 새로운 철학.
PWA는 브라우저를 통해 처음 방문한 사용자에게 유용하며, 설치가 필요하지 않습니다. PWA는 사용자가 관계를 점진적으로 형성할수록 성능이 더욱 강력해질 것입니다. 느린 네트워크에서도 빠르게 로드되고, 관련된 푸시 알림을 전송할 수 있습니다. 모바일 앱처럼 전체 화면으로 로드되고, 홈 화면에 아이콘이 표시됩니다.
( HTTPS, WebApp Manifest, Service Worker ) -> PWA
PWA를 위해선 다음과 같은 요소가 반드시 필요합니다.
HTTPS를 운영해야 합니다.
웹 앱 매니페스트(Web App Manifest)가 있어야 합니다.
서비스 워커를 사용해야 압니다.
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 역시 모바일 환경에서의 웹의 사용성을 향상하는 일환으로 대두되고 있습니다. PWA가 SPA를 직접적으로 포함하는 개념은 아니지만 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을 미리 예측할 수 없거나 고유 한 페이지가 많은 사이트의 경우 예측하기 어려울 수 있습니다.
ASP.NET Core를 사용하는 솔루션에서 TypeScript를 사용하는 방법에 대해 알아봅니다.
0. 솔루션 및 프로젝트 생성.
TypeScript를 사용할 솔루션 및 프로젝트를 생성합니다.
예시에 사용된 솔루션은 ASP.Net Core 3.0을 사용하였으며 ASP.Net Core 웹 응용 프로그램 프로젝트중 웹 응용프로그램(Razor)을 사용하였습니다.
1. NuGet 패키지 설치
"프로젝트 -> NuGet 패키지 관리자"를 클릭해 NuGet 패키지 관리자를 엽니다.
"StaticFiles"와 "TypeScript.MsBuild"를 검색해 설치합니다.
2. Node.js 설치
TypeScript를 빌드하기 위해 gulp를 사용합니다. 여기에서 Nodejs를 설치하세요.
3. 외부 웹 도구 설정 변경.
PATH 환경 변수에서 npm을 찾도록 Visual Studio를 구성합니다. 기본적으로 Visual Studio는 설치 디렉터리에 있는 npm의 버전을 사용합니다.
도구 > 옵션 > 프로젝트 및 솔루션 > 웹 패키지 관리 > 외부 웹 도구로 이동한 후 목록에서 $(PATH) 항목을 선택합니다. 위쪽 화살표를 클릭하여 이 항목을 목록의 두 번째 위치로 이동합니다.
4. ts 파일 생성.
다음과 같이 프로젝트에 "scripts" 폴더를 추가한 후 "app.ts" 파일을 생성합니다.
그리고 다음과 같이 코딩합니다.
function sayHello() {
const compiler = (document.getElementById("compiler") as HTMLInputElement).value;
const framework = (document.getElementById("framework") as HTMLInputElement).value;
return `Hello from ${compiler} and ${framework}!`;
}
5. TypeScript 구성 파일 생성.
이제 TypeScript 컴파일러 구성 파일을 생성합니다. "script" 폴더 내에 "tsconfig.json" 파일을 생성합니다.
새 항목 추가를 이용해 "TypeScript JSON 구성 파일"을 선택해서 생성하면 기본 설정을 자동으로 입력해 줍니다.