December 4, 2022 • ☕️☕️ 12 min read
완벽한 힐링, 중요한 건 꺾이지 않는 마음
console.assert
를 사용하면, assertion이 false라면 에러 메시지를 반환한다. true일 경우 아무 일도 일어나지 않는다.
const errorMsg = "the # is not even";
for (let number = 2; number <= 5; number++) {
console.log(`the # is ${number}`);
console.assert(number % 2 === 0, "%o", { number, errorMsg });
}
// output:
// the # is 2
// the # is 3
// Assertion failed: {number: 3, errorMsg: "the # is not even"}
// the # is 4
// the # is 5
// Assertion failed: {number: 5, errorMsg: "the # is not even"}
assertion은 항상 코드 실행의 그 지점에서 참으로 평가되어야 한다
Ref
AWS Elastic Beanstalk은 AWS 클라우드에서 애플리케이션을 신속하게 배포하고 관리하게 해주는 서비스다. 애플리케이션을 업로드하면 elastic beanstalk이 로드 밸런싱, 조정, 모니터링 등을 관리한다.
elastic beanstalk은 사용자가 선택한 플랫폼 버전(ex Node.js 12 running on 64bit)을 빌드하고 aws 자원들을 프로비저닝한다.
웹 콘솔에서 모니터링, 로드밸런싱 등등의 작업을 진행할 수 있음며, 롤백도 쉽게 가능
‘프로비저닝’은 서버를 세팅하는 프로세스를 의미한다. (프로비저닝에도 여러 경우가 있는데 여기서는 서버 프로비저닝 - 서버 운영체제 설치, 네트워크, 미들웨어 연결 등등의 작업들 - 을 가리킨다.)
⚽️ 월드컵 모니터링도 elastic beanstalk에 있는 모니터링 섹션을 통해서 한다!
ios Live Activity는, 실시간으로 벌어지고 있는 일의 진행 상황을 잠금 화면에서 손쉽게 바로바로 확인할 수 있게 해주는 기능이다.
iPhone 14 Pro, Pro Max에서는 다이나믹 아일랜드 (Dynamic Island)를 통해서도 확인할 수 있다.
실시간 현황은 3개의 상태로 존재(Start, Update, End)하며, 배민에서는 start(주문 성공)-update(주문 상태 변경)-End(종료) 상태로 활용하고 있다.
start 지점에서 JavaScript Interface를 이용하여 실시간 현황 시작을 앱에 요청한다고 한다!
serif과 san serif은 특정 폰트를 이야기하는 것이 아니라 전체적인 스타일을 의미한다.
serif는 타이포그래피에서 위아래에 획의 일부 끝이 돌출된 것이 특징이다. 책이나 신문에서 자주쓰이며, 오래 글을 읽는 데 편하다. (보수적,전통적인 느낌을 주기 때문에 고가의 명품 브랜드가 serif를 사용한다.)
sans serif는 serif과 비교하면 획이 없다. 매거진, 웹에서 자주 쓰임 (도시적이고, 간결하며, 미니멀한 이미지를 준다,. IT 업계에서는 sans serif를 많이 사용한다.)
(사진에서 왼쪽이 serif, 오른쪽이 san-serif)
추가로 monospace는 글자 하나하나의 넓이가 모두 같은 폰트를 의미한다. (그래픽 기능이 제한되어있던 컴퓨터 터미널에서 monospace 폰트를 사용했다.)
github, naver, Wordpress, medium 등의 사이트는 시스템 폰트를 사용하는데, 그 이유는 퍼포먼스 때문이다. 폰트는 웹에서 용량이 큰 리소스다. 따라서 유저가 기본적으로 가지고있는 시스템 폰트를 사용하면 로딩시간을 줄일 수 있다.
모든 유저에 시스템 폰트를 적용하려면 다음을 추가한다.
font-family: -apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif
Segoe UI
- microsoft가 사용하는 글꼴 , 윈도우 폰 , 컴퓨터apple-system
- iOS Safari, macOS Safari, macOS Firefox 지원system-ui
- 플랫폼의 default UI fontBlinkMacSystemFont
- macOS Chrome 지원Roboto
- Android 와 Chrome OS 지원Helvetica Neue
- macOS versions < 10.11 지원arial
, sans-serif
- 모든 플랫폼 지원다음과 같이 React 코드를 작성 후,
const [number, setNumber] = useState(0);
return (
<>
<h1>{number}</h1>
<button
onClick={() => {
setNumber(number + 5);
setNumber((n) => n + 1);
setNumber(number + 42);
}}
>
Increase the number
</button>
</>
);
버튼을 클릭했을 때의 결과는?
🙋♀️ number
는 42
가 된다.
setNumber(number + 5)
는 number
가 0이니 state
를 5로 교체해달라는 명령을 큐에 넣는다.setNumber(n -> n + 1)
은 updater function을 큐에 넣는다.setNumber(number + 42)
는 number
가 0이니 state
를 42로 교체해달라는 명령을 큐에 넣는다.리액트 queue를 간단하게 구현한 코드는 다음과 같다.
export function getFinalState(baseState, queue) {
let finalState = baseState;
finalState = queue.reduce((val, update) => {
if (typeof update === "function") {
// updater 함수라면 ex) n=> n+1
return update(val);
}
// replace 작업이라면
return update;
}, baseState);
return finalState;
}
prefetchQuery
react-query 의 prefetchQuery
는 리턴데이터를 주거나 throw 하지 않는다.
function noop() {
return undefined;
}
...
_proto.fetchQuery = function fetchQuery(arg1, arg2, arg3) {
var parsedOptions = parseQueryArgs(arg1, arg2, arg3);
var defaultedOptions = this.defaultQueryOptions(parsedOptions); //https://github.com/tannerlinsley/react-query/issues/652
if (typeof defaultedOptions.retry === 'undefined') {
defaultedOptions.retry = false;
}
var query = this.queryCache.build(this, defaultedOptions);
return query.isStaleByTime(defaultedOptions.staleTime) ? query.fetch(defaultedOptions) : Promise.resolve(query.state.data);
};
_proto.prefetchQuery = function prefetchQuery(arg1, arg2, arg3) {
return this.fetchQuery(arg1, arg2, arg3).then(noop).catch(noop);
};
서버사이드에서 미리 쿼리를 적재하는데 예외발생시 redirect 시켜야한다면 prefetchQuery
대신 fetchQuery
를 사용하자.
리액트의 일은 두 단계로 나눌 수 있다.
렌더링은 느리고 커밋은 비교적 빠르다. 그래서 랜더링 단계가 너무 길어져 브라우저의 동작을 방해하는 문제를 해결하고자 랜더링 단계의 작업을 나눈 것이다. (concurrent mode)
따라서 랜더링 단계의 lifecycle 메소드들이 한번 이상 호출될 수 있다! (setState의 업데이트 함수도 2번 실행되지만 두번째 결과는 버린다) 이때, 사이드 이펙트가 있으면 문제가 생길 수 있다.
React.strict
모드가 사이드 이펙트 문제를 직접적으로 해결해주지는 않지만 어떤 문제가 생길지 보여준다.
파일에서 type definition을 타고들어가면 항상 node_modules
폴더 구조가 열리는 것에 피로감을 느꼈다. 🫠
이때 vscode에서 autoReveal
항목을 false로 설정하면 node_modules
가 열리는 것을 방지할 수 있다!
🤔 하지만 src 폴더의 파일들은 열려있게 하고 싶었다.
vscode issue에서 이에대한 논의가 있었고 최근에 vscode-insider(vscode 베타버전?)에 이 기능이 추가되었다.
(default setting으로 node_modules
는 autoReveal에서 제외되어 있다.)
"explorer.autoRevealExclude": {
"**/node_modules": true,
"**/bower_components": true
},
여러 요소에 동일하게 box-shadow
를 먹이고, 두 요소가 가까이 붙어있을 때, 한 요소의 box-shadow
가 다른 요소 위로 침범하는 문제가 발생할 수 있다.
이때는 다음과 같이 :before
pseudo element를 사용하여 box-shadow
의 레이어를 분리해주면 된다.
.withShadow {
position: relative;
}
.withShadow:before {
content: "";
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: -1;
box-shadow: -5px 5px 20px 5px #000;
}
Ref https://blog.dudak.me/2014/css-shadows-under-adjacent-elements/
let obj = await import("./say.js");
let say = obj.default;
resize
이벤트는 div
에 붙일 수 없다.
addEventlistener
(resize
, …)는 document의 리사이즈만 옵저빙할 수 있다.(모든 HTML 엘리먼트에 등록할 수 있는 것이 아니다.) 만약 div
같은 다른 리사이즈를 구독하고 싶다면 ResizeObserver
를 활용하면 된다. (Ref)getUserMedia
API는 보안이 보장된 환경에서만 사용 가능하다. localhost에서는 문제없이 사용 가능하지만, 호스팅하려면 https 프로토콜로 접속이 가능한 환경이 준비되어 있어야 한다.relative
, absolute
, fixed
, sticky
)이번에 스테이지 심사 대상인 문법들은 다음과 같다.
String.dedent()
(Stage 3)
console.log(`["I don't want extra indents"]`);
// vs.
console.log(String.dedent` [
"I don't want extra indents"
]`);
Set 메서드 추가 (Stage 3)
이터레이터 헬퍼 (Stage 3)
await 연산자 (Stage 2)
await Promise.all(ps)
// vs.
await.all ps
Ref https://github.com/tc39/agendas/blob/main/2022/11.md
결과는?!
Styled Components Performance Average performance range: 13809 ms
Modular CSS Performance Average performance range: 8995 ms
꽤나 큰 차이!
그래도 사람들은 익숙한 것에 편리하다나 뭐라나 🤷♀️
Ref https://medium.com/@pitis.radu/css-vs-css-in-js-performance-bcbdf8e1f6ff
AWS에서 Lambda의 콜드스타트 지연 시간을 줄이기 위해 SnapStart라는 기능을 공개했다.
설명은 다음과 같다.
특정 Lambda 함수에 대해 Lambda SnapStart를 활성화한 후 새 버전의 함수를 게시하면 최적화 프로세스가 트리거됩니다. 프로세스에 의해 함수가 시작되고
Init
단계 전체에 걸쳐 프로세스가 실행됩니다. 그런 다음 메모리 및 디스크 상태의 변경 불가능한 암호화된 스냅샷을 가져와서 다시 사용할 수 있도록 캐시합니다. 이후에 함수가 호출되면 필요에 따라 상태가 캐시에서 청크 단위로 검색되어 실행 환경을 채우는 데 사용됩니다. 새로운 실행 환경을 만드는 데 더 이상 전용Init
단계가 필요하지 않으므로 이 최적화를 통해 호출 시간이 단축되고 더 잘 예측할 수 있게 됩니다.
하지만 아직 서울 리전은 지원하지 않는다 🥲
Ref https://aws.amazon.com/ko/blogs/korea/new-accelerate-your-lambda-functions-with-lambda-snapstart/
ver 1.0.0 마일스톤까지 남은 이슈 단 3개!
Ref https://github.com/sveltejs/kit/issues?q=is%3Aopen+is%3Aissue+milestone%3A1.0
이런 것도 있었다니!! ㅋㅋㅋ 깐지난다.
Ref https://youtu.be/gmp0istg5xo
구성원 분의 정리요약
Ref https://www.youtube.com/watch?v=YImV7OfPqSo
닉네임부터 심상치않다… 😳
학습에서부터 실무까지 유용하게 훔쳐볼(?) 수 있어보인다.
금요일 친구들과 다같이 연차를 쓰고 호캉스… 가 아닌 한캉스 - 한옥 독채 바캉스 - 를 다녀왔다. 1박2일 동안 맛있는 거 잔뜩 먹고, 술도, 완벽한 숙소에서 10년 전 음방 유튜브만 잔뜩 보고, 서촌 골목골목 예쁜 가게들도 구경하고. 제대로 된 힐링이었다. 새벽 2시까지 축구 보다 잤는데도 하나도 안 피곤했던 다음날 ☀️ 작은 한옥 마당에 얕게 내린 첫눈까지 완전히 아름다웠다.
그리고 정말 16강에 진출하다니 ㅠㅠ 축구같은 거 관심도 없고 한 번도 제대로 본 적 없었는데, 이번 월드컵은 조별리그 3번 다 내가 사랑하는 사람들과 함께 집중해서 챙겨봤다 ㅋㅋㅋ 특히 포르투갈 전은 정말 질 것 같아서 (그리고 밤 12시라;) 그냥 잔다고 했는데, 잠을 잘 수 없는 명경기였다. 이 역사적인 순간을 친구들과 함께 가슴 졸이면서 보다니!! 최고야 짜릿해
💫 중요한 건 꺾이지 않는 맘 💫
남은 2022년, 곧 찾아올 2023년도 알빠임?의 마인드로 살아보자 👊