개인적으로 Nextjs 의 복잡함을 좋아하지 않는데, Remix 가 좋은 대안을 주는 듯 하다.
대략 기억나는 것을 정리중…
Next.js 보다 빠르다.
HTTP stale-while-revalidate caching directive 를 이용한다.
Next.js 가 느린 이유중 하나는 SSG(static site generation)을 사용할 수 없는 화면인 경우 Next.js 는 브라우저에서 서버로 검색결과를 조회하고, 그 data 를 보고 이미지를 가져와야 해서이다. 더구나 서버로 검색결과를 조회하는 시점도 브라우저가 최초의 javascript 를 받은 후 처리하고 나서야 시작하게 된다. (network waterfall request chain)
Nextjs 가 data 를 가져오는데 4가지 모드를 제공하는데, Remix는 1개의 모드(loader)를 제공.
ref. 1 의 Chapter 1, Reliable, Scalable, and Maintainable Applications
확장성 Scalability
성능에 대한 표현
Scalability > Describing Performance
p.14
응답시간의 평균은 유저들이 일반적으로 어떤 평균 응답시간을 경험했는지를 말해주지 못한다.
이때는 percentiles(백분위수)를 사용하는 것이 낫다.
중앙값(median)은 50번째 백분위수라서 p50 으로 불린다.
중앙값이 1.5ms 라고 하면, 절반은 1.5ms 보다 느렸고, 절반은 1.5ms 보다 빨랐다고 알 수 있다.
p. 15
예를 들어 Amazon은 내부 서비스에 대한 응답 시간 요구 사항을 99.9% 라고 설명한다. 이말은 1,000건의 요청 중 1건에만 영향을 미친다는 뜻이다. 이는 요청이 가장 느린 고객이 종종 계정에 가장 많은 데이터를 보유하고, 구매횟수가 많은 고객이기 때문이다. 즉 가장 가치있는 고객들이다.[19].
반면에 99.99번째 백분위수(요청 10,000건 중 가장 느린 1건)를 최적화하는 것은 비용이 너무 많이 들고 아마존의 목적에 비해 충분한 이점을 얻지 못하는 것으로 간주되었다.
때때로 이러한 DDD 기술 규칙과 패턴은 DDD 접근 방식(DDD aproaches)을 구현하는 데 있어 가파른 학습 곡선을 가진 장애물로 인식되기도 합니다. 하지만 중요한 부분은 패턴 자체가 아니라 코드를 비즈니스 문제에 맞게 구성하고 동일한 비즈니스 용어(유비쿼터스 언어)를 사용하는 것입니다. 또한 DDD 접근 방식(DDD aproaches)은 중요한 비즈니스 규칙이 있는 복잡한 마이크로서비스를 구현하는 경우에만 적용해야 합니다. CRUD 서비스와 같이 더 단순한 책임은 더 간단한 접근 방식으로 관리할 수 있습니다.
Sometimes these DDD technical rules and patterns are perceived as obstacles that have a steep learning curve for implementing DDD approaches. But the important part is not the patterns themselves, but organizing the code so it is aligned to the business problems, and using the same business terms (ubiquitous language). In addition, DDD approaches should be applied only if you are implementing complex microservices with significant business rules. Simpler responsibilities, like a CRUD service, can be managed with simpler approaches.
web 에서 B site 에서 A server 로 fetch 를 보내고, B로 redirect 를 받은 경우
다음 sequence diagram 은 만약 내가 site.a.com 에 접속한 상황에서 fetch 로 api.a.com 에 request 를 했다. 그 상황에서 api.a.com 가 redirect site.a.com 를 나에게 던져준 경우이다.
이 경우 예상치 못하게 cors error 가 떴다.
site.a.com
--> fetch api.a.com
--> redirect to site.a.com
CORS error 가 뜨는 이유
CORS error 가 뜨는 이유는 Origin 이 site.a.com 이 아니라 null 로 set 돼서 site.a.com 로 request 를 보내기 때문이다. 그렇게 되면, browser 에서 orgin 과 서버가 보낸 Access-Control-Allow-Origin 값을 비교할 때 두 값이 달라서 error 를 던지게 된다.(아래 Fetch: Cross-Origin Requests 부분 참고)
여기를 보면, 처음 request 를 보낸 url에서 바뀐적이 있으면, redirect-tainted origin 으로 본다. 그렇기에 Origin 이 null 로 잡힌다.
이러면 origin 이 ‘null’ 로 바뀌었다고 봐야 하기 때문에 site.a.com 에서 CORS 를 지원하기 위한 설정을 잡아줘야 한다.
CORS error 가 없이 동작할 때
다음처럼 api.a.com 으로 보내고 api.a.com 으로 redirect 되는 경우는 다음처럼 CORS error 가 안뜨고, 잘 동작한다.
server 는 그에 따라 Access-Control-Allow-Origin 을 만들어서 response 에 보낸다.
browser 가 trusted mediator(신뢰할 수 있는 중재자) 역할을 한다. 즉, browser가 이제 client 에서 보냈던 origin 이랑 서버가 보낸 Access-Control-Allow-Origin 값을 비교해서 값이 적절하면, javascript 가 response 값을 access 할 수 있게 해준다.
javascript 가 기본적으로 접근할 수 있는 safe header 는 다음과 같다.
Cache-Control
Content-Language
Content-Length
Content-Type
Expires
Last-Modified
Pragma
js 가 다른 header 에 접근하고 싶어도 browser가 접근을 막는다. 다만 server 에서 Access-Control-Expose-Headers 에 추가된 header는 browser가 js 한테 열어준다.
이제는 browser가 안전하지 않은 요청(unsafe request)는 바로 날리지 않는다. preflight request 를 먼저 날리고 나서 날리게 된다.
Access-Control-Request-Method : 어떤 method 로 보내려는지 적는다.
Access-Control-Request-Headers : 보내려는 request 가 갖고 있는 header들을 적는다.