📗 Angular Hybrid Rendering
Angular이전 글에서 CSR, SSR, SSG에 대해 각각의 차이점에 대해서 다뤄 보았습니다. Angular, React, Vue에서 각각의 방식으로 이러한 렌더링 방식으로 구현을 할 수가 있는데요. 대표적으로 Angular는 Universal, React는 NextJs, Vue는 Nuxt 등을 많이 사용하는 것 같네요. Angular는 국내에서 인기가 많이 없어서인지 해당 내용을 다루는 글이 없는듯하여 이번 기회에 제가 사용을 해보고 간단하게나마 정리해보겠습니다. 렌더링 종류에 대한 글은 여기를 참고 결론부터 말씀드리면 굉장히 쉽습니다! 먼저 간단하게 개념 정도만 다시 짚고 넘어가겠습니다. PreRendering 우리에게 가장 익숙한 클라이언트 렌더링(CSR) 방식은 잘 아실 테고, 서버사이드 렌더링(SSR)은 각 페이지에 대한 요청을 받으면 브라우저 엔진을 대신해서 서버에서 Node가 렌더링하고 결과물을 클라이언트에서 전달해주는 것이고, 사전 렌더링(PreRendering, SSG) 말 그대로 미리 렌더링을 해놓고 서버에서 해당 페이지에 대한 요청이 오면 미리 렌더링해두었던 페이지를 전달! 자 이제 누구도 알려주지 않았던, Angular Universal을 이용해 하이브리드 렌더링을 구현해 보겠습니다. Universal 이라는 새로운 프로젝트를 생성하고 universal package를 추가해줍니다. 을 추가 해주면 , 과 같은 뭔가 못보던 파일들이 생겨나는 것을 보실수 있습니다. 우리는 지금껏 브라우저 환경에서 클라이언트 렌더링을 사용했지만, 이제 브라우저 환경이 아닌곳에서 렌더링을 해야 하기 때문에 Node가 실행해줄 파일이 필요하기 때문입니다. 파일을 보면 처음 보는 scripts들도 확인 할 수 있습니다. 키값명칭을 보면 대충 어떤것을 하는것이겠구나.. 하는 정도의 감은 오셨을 겁니다. 먼저 을 해보기 위해 route 페이지가 필요한데, about와 contact 모듈을 추가하고 라우터에 등록 시켜보겠습니다. 각각의 컴포넌트를 생성해 router에 등록해도 되지만 아래와 같은 명령어를 통해 쉽게 추가할 수 있습니다. (Angular 프레임웍의 장점 이기도 하죠, 복잡해 보이지만 체계적이다? ^^;) Run 바로 사전 렌더링을 해보죠! !01 dist 디렉토리를 보시면 server, browser 두개의 디렉토리로 나누어져 있네요. server/main.js 이 파일이 node에서 실행해주는 파일이 되는것이고요, browser 디렉토리 내부에 있는 파일들이 렌더링된 파일들입니다. 그런데 index.html 파일만 있는게 아니고 router에 등록한 about, contact의 index.html파일도 각각의 디렉토리에 생성이 되었습니다. 각각의 페이지 요청이 오면 미리 랜더링해둔 index.html파일을 전달하기 위함이죠. Options 그리고 파일의 옵션정보를 이용해서 원하는 페이지만 사전 렌더링을 해둘수가 있습니다. 예를 들어 about 페이지만 사전 렌더링을 해두고 싶다. 그럼 , 배열에 렌더링할 페이지만 추가해줍니다. projects > hybrid-rendering-app > architect > prerender "routesFile": "./routes.txt" 파일에 경로들을 설정할수도 있습니다. 더 자세한 정보는 여기에서 확인해 주세요 이제 node로 해당 js파일을 실행해주면 됩니다. Server Start Node Express server listening on http://localhost:4000 서버를 구동해주고 브라우저에 접속해서 Network 탭을 살펴 보면 각 라우팅에 접근할 때마다 해당 문서를 다운받는 것을 확인할 수 있습니다. !main !about !contact 최초 접속시 index.html 파일을 받아 그안에서 javascript 파일에 의해 동적으로 문서를 변경하는 SPA방식과는 달리 라우터 접근시 사전에 렌더링된 문서를 서버에서 전달해주게 됩니다. 거의 변경이 없는 페이지들의 경우 이렇게 사전에 렌더링을 해두면 성능적인 부분에서 매우 효휼적일 것이지만, 페이지 내용이 자주 변경이 된다거나 게시판 같은 동적인 라우팅을 사용한다면, 에 렌더링할 페이지만 명시해주면 선택적으로 사전 렌더링을 할 수 있게 되는 것 입니다.
2022년 10월 27일7분📗 Angular Google Analytics Traking
Angular구글 분석을 사용하기 위해서는 추척아이디가 포함된 스크립트를 index.html 페이지에 삽입만 하면 되기 때문에 아주 간단하게 연동을 할 수 있습니다. 그러나 Angular와 같은 SPA방식은 단일페이지로 되어 있기 때문에 단순히 스크립트를 복사 붙여넣기 방식으로 만으로 우리가 원하는 분석데이터를 수집하기에는 아쉬움이 있습니다. 그럼 어떻게? Angular는 단일페이지 애플리케이션 프레임워크입니다. 즉, 브라우저는 기술적으로 한 페이지만 로드하고 페이지가 변경되면 DOM은 프레임워크의 JavaScript 코드에 지정된 대로 페이지의 일부만 업데이트 합니다. 컴포넌트는 시각적인 퍼즐의 일부를 구성하는 것이고 특정 보기에서 다른 곳으로 이동할 수 있고 주소 표시줄의 링크가 일치하도록 동적으로 변경되지만 여전히 동일한 루트 페이지에 있습니다. 브라우저가 페이지를 아동해도 새로고침 없이 여전히 동일한 페이지 이기 때문에 Google Analytics 태크의 기본 구현은 이를 알지 못합니다. 따라서 라우터 이벤트를 통해 변경된 페이지 정보를 추가로 전달해 주어야 합니다. gtag.js Google Analytics를 통한 추적에는 및 의 두 가지 버전이 있습니다. ga는 더 오래된 버전이며 Google에서는 대신 gtag.js 구현을 추진하고 있습니다. 시작하려면 Google Analytics 패널로 이동하여 복사하여 붙여넣기 코드를 찾아야 합니다. 트래킹ID가 포함된 코드를 복사하여 섹션에 넣어주면 됩니다. 데이터 스트림에서 스트림을 추가하면 그림과 같이 트래킹ID 및 HTML에 삽입할 script를 확인 할 수 있습니다. !01 Router Events 정보 수집 이제 페이지 이동 정보를 수집하기 위해 별도의 코드를 작성해야 합니다. Angular에는 특정 정보에 액세스하는 데 사용할 수 있는 몇 가지 이벤트 처리 방법이 있는데, 우리는 사용자가 탐색한 URL정보가 필요하기에 라우터 이벤트를 구독 할 것입니다. 이 정보를 추출하기 위해 메소드를 사용하여 라는 속성에 액세스할 수 있습니다. 이 속성에는 라우팅 URL의 부분이 포함됩니다. 코드 효율성을 위해 이 모든 것을 파일에 배치할 수 있습니다. 이 파일은 모든 것의 최상위 수준에서 로드되는 첫 번째 파일이기 때문입니다. 추적을 더욱 강화하는 데 사용할 수 있는 다른 매개변수가 있습니다. 최신 매개변수 목록은 Google Analytics 추적 페이지 보기 문서 페이지에서 확인할 수 있습니다. (https://developers.google.com/analytics/devguides/collection/gtagjs/pages) Event Tracking 이벤트 추적은 Analytics 통계에 또 다른 데이터 계층을 추가합니다. 이벤트 트래킹은 원하는 이벤트가 발생시 수집될 수 있도록 해야 하기 때문에 Angular 서비스를 만들고 구성 요소에서 사용할 것입니다. 이렇게 하려면 CLI를 사용하여 서비스를 생성한 다음 이를 공급자 중 하나로 파일에 추가할 수 있습니다. 새로 생성된 서비스 파일 내에서 호출될 때 본질적으로 실행하고 형식이 정확하고 에서 요구하는 방식인지 확인하는 함수를 생성할 것입니다. 또한 외부에서 로드된 라이브러리에 서비스를 노출하려면 를 Function으로 선언해야 합니다. 이 서비스를 사용하려면 컴포넌트로 가져와 버튼 클릭 이벤트와 같은 일이 발생할 때 트래킹 하려는 값을 에 전달하여 실행해야 합니다. 그런 다음 를 처리할 구성 요소에서 를 호출할 수 있습니다. 작동하려면 생성한 서비스를 구성 요소로 가져와야 합니다. 나만의 이벤트 및 이벤트 카테고리를 만들 수 있습니다. Google에는 사용할 수 있도록 미리 정의된 목록이 있습니다. 전체 목록은 여기에서 찾을 수 있습니다.(https://developers.google.com/analytics/devguides/collection/gtagjs/events) 마치며 단일 페이지 및 프로그레시브 웹 응용 프로그램에서 구현하는 것은 약간의 코드만 추가하면 되기 때문에 어려운 부분은 없습니다. 와 Angular 라우팅의 작동 방식을 이해하고 Analytics 추적을 구현하는 것이 중요합니다. 패키지를 설치하여 사용하는 방법도 있으니 참고 하면 좋을 것 같습니다. (https://www.npmjs.com/package/angular-google-tag-manager)
2022년 01월 02일8분🤩 1. Angular 8
AngularAngular 8버전이 출시 되었다. 이번 버젼은 최신 브라우저에서 어플리케이션의 구동 시간을 단축시키고, CLI와 함께 사용할 수 있는 새로운 API를 제공한다. 필자는 기존 Angular 6에서 8버전으로 업그레이드를 하였는데, 성능적인 면에서 많이 향상이 된 것을 체감적으로도 느낄 수 있었다. Update update.angular.io를 방문해 자세한 정보와 가이드를 참고 하자. Differential loading 차등 로딩(Differential loading)은 브라우저가 자신의 능력에 따라 최신 자바스크립트와 원시 자바스크립트를 선택하는 과정을 말한다. 기본값으로 Angular 8은 최신 빌드(es2015)와 원시 빌드(es5)를 각각 수행하고 사용자가 어플리케이션을 로드했을 때, 사용자의 브라우저는 자동으로 필요한 번들을 선택할 것이다. ng update 명령어를 쓰면 Angular는 차등 로딩을 위해 프로젝트의 tsconfig.json를 업데이트 한다. Angular CLI는 차등 로딩의 수행 여부를 결정하기 위해 tsconfig.json 파일의 target 프로퍼티에 명시된 자바스크립트의 버젼을 확인한다. target 프로퍼티가 es2015로 설정되었을 때, Angular는 두 개의 번들을 생성하고 각각 이름을 부여하고 브라우저는 런타임시에 script 태그의 속성을 통해 어떤 번들을 로드할지 결정한다. 최신 브라우저에서 초기 번들 사이즈를 40kB 이상 절감 했고, 커뮤니티에서도 얼마나 최신 자바스크립트를 많이 사용했는가에 따라 7-20% 정도의 절감 효과를 보았다는 이야기가 나왔다고 한다. !01 자세한 내용은 여기를 참고하자. Route Configurations use Dynamic Imports Angular는 어플리케이션의 일부를 라우터를 이용한 지연 로딩 기법으로 불러올 것을 권장한다. 이는 라우트 설정의 loadChildren 프로퍼티를 통해 설정할 수 있는데, 8 버전에서는 동적 임포트의 산업 표준으로 변경되었다. 이는 VSCode 같은 툴에서 해당 임포트 구문을 이해하고 교정해줄 수 있는 에디터의 지원성을 높일 것이다. ng update 명령어를 쓰면 Angular는 자동으로 해당 구문을 변경한다. Builder APIs in the CLI Angular Schematics가 ng new, ng generate, ng add, ng update와 같은 명령어에 접근하듯, 새로운 Builder API는 ng build와 ng test 그리고 ng run에 접근해 빌드나 배포 과정을 후킹할 수 있도록 한다. 공식 API 문서를 참고. CLI의 Workspace API 기존에 Schematics를 사용하려면 angular.json을 열어 수동으로 작업 저장소 설정을 수정해야 했다. Angular 8은 angular.json을 더 쉽게 관리할 수 있는 API를 제공한다. Workspace API에 대한 자세한 설명은 여기를 참고 Web Worker 지원 Web Workers는 cpu 자원을 많이 사용하는 어플리케이션에서 어플리케이션의 속도를 향상시킬 수 있는 좋은 방안이다. Web Workers는 이미지나 비디오 처리를 백그라운드 스레드로 옮길 수 있게 해준다. angular.io 공식홈도 내부의 검색과 색인을 위해 Web Workers를 사용했다고 한다. 이제 CLI로 Web Workers를 생성할 수 있고, worker를 생성하려면 다음 명령어를 사용하면 된다. web worker를 생성했다면, 원래 사용하던 대로 사용하면 된다. CLI가 web worker를 알아서 번들화 하고 정리해준다. 더 자세한 Angular CLI의 Web Workers에 대해서 알려면 여기를 참고. Deprecation Angular는 공개 API가 n + 2 버젼을 지원하도록 한다. 즉 8.1 버젼에서 폐기 처분될 기능은 9 버젼과 10 버젼까지는 작동할 것이라는 이야기이다. 예를 들어, 버젼 8에서 platform-webworker를 폐기 하게 된다. Angular에서 폐기, 제거된 기능 관련하여 정리된 리스트를 보려면 Deprecation Guide를 참고하자. Ivy & Bazel Ivy를 8.0 버전에서 프리뷰 옵션 형태로 사용이 가능하다. Angular Ivy는 가상 DOM의 한계를 지닌 이전 렌더러의 문제를 해결하기 위해 만들어 졌다. Ivy는 원본보기 엔진의 크기가 작고, 빠르고 간단하며, Tree Shaking의 장점과 Incremental DOM의 메모리 사용 공간을 줄인다. Ivy를 통해 렌더링하는 동안 메모리 할당을 최소화하고 증분 빌드를 허용하는 한 번에 하나의 파일을 컴파일하여 메모리가 제한된 장치에서 앱 성능을 향상 시키도록 설계되었다. 즉, Ivy는 컴파일 프로세스를 단순화하여 압축한다. 그리고 더 작고 더 많은 원자 함수로 나누기 때문에 Ivy는 이전 렌더러에 비해 Tree Shaking에 더 최적화되어 있다. Ivy enable 을 편집하여 Ivy를 선택하고 angularComplierOption 섹션을 추가하고 enableIvy를 true로 설정한다. 새로운 Angular CLI 프로젝트의 경우, newscript를 실행할 때 --enableIvy 플래그를 사용할 수 있다. 그 결과, 번들 크기의 15%로 줄어들었다면 이는 웹 사이트 로딩 시간이 15% 더 빨라짐을 의미한다. 참고 (blog.angularindepth.com - Angular Ivy)
2019년 07월 22일8분Angular Observable
Angular옵저버블은 ES7 릴리스에 포함될 비동기 데이터를 관리하기위한 새로운 표준이다. Angular는 이벤트 시스템과 HTTP 서비스에서 옵저버블을 광범위하게 사용한다. Observables 옵저버블은 시간이 지남에 따라 여러값을 가질 수 있는 지연 콜렉션이다. 1. Observables는 lazy하다. 지연 옵저버블을 뉴스 레터로 생각할 수 있다. 각 구독자(subscriber)마다 새로운 뉴스 레터가 만들어진다. 그 뉴스레터들은 구독자들에게만 보내고 다른 사람에게는 보내지 않는다. 2. Observables는 시간이 지남에 따라 여러 값을 가질 수 있다. 뉴스 레터 구독을 계속 열어두면, 매번 새로운 뉴스 레터를 받게된다. 발신자(sender)는 받은 시간을 결정하지만 받은 편지함에 곧바로 올 때까지 기다려야한다. 옵저버블과 프로미스간의 다른 중요한 차이점이 있는데, promise은 항상 오직 하나의 값만을 반환한다는 점이다. 또 하나는 옵저버블의 구독을 취소 할 수 있다는 점이다. 뉴스 레터를 더 이상 원하지 않으면 구독을 취소하면된다. 반면 프로미스는 취소 할 수 없다. 프라미스가 당신에게 건네지면, 그 프라미스의 resolve가 이미 진행되고 있으며, 일반적으로 프라미스의 resolve가 실행되는 것을 막을 수 있는 권한이 없다. Push vs pull observables를 사용할 때 이해해야 할 핵심 사항은 observables가 push한다는 것이다. (옵저버블은 push 시나리오를 따른다는 말) push와 pull은 데이터 생성자가 데이터 소비자와 커뮤니케이션하는 방법을 설명하는 두 가지 방식이다. Pull Pulling일 때 데이터 소비자는 데이터 생성자로부터 데이터를 가져 오는 시점을 결정한다. 생산자는 언제 데이터가 소비자에게 전달되는지를 알지 못한다. 모든 자바 스크립트 함수는 pull 시나리오를 사용한다. 함수는 데이터의 프로듀서이며 함수를 호출하는 코드는, 호출에서 하나의 반환 값을 “꺼내”(pull) 가져와 이를 소비한다. Push Pushing일 때, 다른 방향으로 동작한다. 데이터 생성자 (뉴스 레터 생성자)는 소비자 (뉴스 레터 구독자)가 데이터를 가져 오는 시점을 결정합니다. 프로미스는 오늘날 자바 스크립트에서 사용하는 가장 일반적인 push 방법입니다. 프로미스(생산자) 전달자는 등록된 콜백(소비자)에게 resolve된 값을 전달하고, 프로미스는 함수와는 달리 콜백에 그 값이 “푸시 (push)”되는 시기를 정확하게 결정한다. Observables는 JavaScript로 데이터를 푸시하는 새로운 방법이다. 옵저버블은 여러 값의 생산자로서 구독자에게 “푸시 (pushing)”한다. Angular에서 Observables Angular에서 HTTP 요청을 하면 옵저버블 형태로 반환을 한다. observable을 반환하는 fetchUsers 메서드를 사용하여 간단한 HttpClient를 만들었다. 어떤 종류의 리스트에 사용자를 표시하고 싶으므로 fetchUsers 메서드를 사용해서 해보자. 이 메소드는 옵저버블을 반환하기 때문에 우리는 그것을 구독해야 한다. Angular에서 우리는 두 가지 방식으로 Observable을 구독 할 수 있다. 방식 1 비동기 파이프를 사용하여 템플릿의 옵저버블을 구독하는 방법이 있다. 이로 인해 Angular는 컴포넌트의 생명주기 동안 구독을 처리한다. Angular는 자동으로 구독하고 구독취소한다. 비동기 파이프가 노출되야하므로 모듈에 “CommonModule”을 import하자. > 일반적으로 달러($)기호는 Stream의 약어로 쓰이기 때문에 변수이름 앞에 $를 사용하면 변수의 관찰 가능 여부를 쉽게 식별 할 수 있다. 방식 2 메소드를 사용하여 옵저버블을 구독한다. 데이터를 표시하기 전에 먼저 데이터에 뭔가 작업하기를 원한다면 편리할 수 있다. 단점은 구독을 직접 관리해야한다는 것다.(구독취소를 해주어야 함) 템플릿 로직이 꽤 비슷하다는 것을 알 수 있듯이, 2번 방식으로 간다면 구성 요소 논리는 훨씬 더 복잡해 질 수 있다. 일반적으로 방식1을 선택하는 것이 좋다. 가장 쉽고 구독을 수동으로 관리할 필요가 없다. Creating an observable yourself Angular가 제공한 일반적인 옵저버블을 다루는 방법을 알았으므로 옵저버블을 어떻게 생성하는지 보자. observables는 새로운 Observable() 호출을 사용하여 만든 다음 observer에 가입하고 next()를 호출하여 실행하고 unsubscribe()를 호출하여 삭제한다. observable 만들기 observables를 만드는 것은 쉽다. 새로운 Observable()을 호출하고 옵저버를 나타내는 하나의 인수를 전달하면됩니다. 그러므로 저는 보통 그것을 “observer”라고 부른다. 옵저버블 구독하기 옵저버블은 구독하지 않으면 아무 일도 일어나지 않을 것이다. 옵저버를 구독 할 때 subscribe()를 호출 할 때마다 옵저버블에 독립 설정이 실행된다. 구독 요청은 동일한 옵저버블에 대한 여러 구독자간에 공유되지 않는다. 옵저버블 실행하기 observables 안의 코드는 observables의 실행을 나타낸다. 옵저버블을 만들 때 주어진 매개 변수(observer)에는 옵저버블의 구독자에게 데이터를 보낼 수있는 세 가지 함수가 있다. next: Number나 Array나 객체같은 여러 값을 subscribers에게 보낸다. error: 자바스크립트 에러나 예외값을 보낸다. complete : 어떤 값도 보내지 않는다. 콜은 구독자에게 실제로 데이터를 전달할 때 가장 일반적이다. 옵저버블의 실행 중에는 의 무한 호출이있을 수 있지만 또는 가 호출되면 실행이 중지되고 더 이상 데이터가 subscribers에게 전달되지 않는다. 옵저버블 처분 옵저버블의실행은 무한한 시간 동안 실행될 수 있기 때문에, 실행을 막을 수있는 방법이 필요하다. 각 구독자마다 각 실행이 실행되기 때문에, 메모리와 컴퓨팅 성능이 낭비, 즉 더 이상 데이터가 필요없는 구독자는 구독을 멈추는 것이 중요하다. 옵저버블을 구독할 때, 진행중인 실행을 취소하면 구독이 반환된다. 실행을 취소하려면 를 호출하면 된다.
2019년 02월 17일12분