ziglog

    Search by

    2025년 7월

    August 2, 2025 • ☕️☕️☕️☕️ 19 min read

    💡 Newly Learend


    Date.prototype.getTimezoneOffset()

    자바스크립트에서 **로컬 시간(Local time)**과 UTC(GMT) 간의 시간차를 분(minute) 단위로 반환하는 메서드 이 메서드는 특히 시간대(time zone)를 고려한 날짜·시간 계산이나 표준화된 타임스탬프를 만들 때 유용하다.

    • 서버-클라이언트 간 시간 동기화

      • 클라이언트는 브라우저의 로컬 시간을 사용하고, 서버는 일반적으로 UTC를 기준으로 함.
      • 로컬 시간과 UTC 간 시간차를 계산해서 서버에 전달하거나 서버에서 받은 UTC 값을 로컬 시간으로 변환할 수 있음.
    • 표준화된 시간 처리

      • 여러 지역의 사용자에게 동일한 시간 정보를 제공해야 할 때.
      • 예: new Date()로 생성한 값에 getTimezoneOffset()을 반영하여 UTC로 변환.
    • 타임존 보정

      • 예를 들어 사용자의 지역이 서머타임을 적용하는 경우, getTimezoneOffset()은 이를 자동 반영하여 오차값을 반환함.

    git diff [-options]

    옵션 설명
    git diff <commit1> <commit2> 두 커밋 사이의 변경 사항 비교
    git diff <branch1>..<branch2> 브랜치 간 차이 비교 (.....는 의미가 다름)
    git diff HEAD 현재 작업 디렉토리와 최신 커밋(HEAD) 비교
    git diff --cached 또는 --staged staging area(인덱스)와 최신 커밋(HEAD) 비교
    git diff <파일명> 특정 파일만 비교

    short-circuting

    boolean 연산을 수행할 때 필요 이상의 계산을 하지 않고 결과를 바로 결정하는 최적화 기법을 말한다.

    주로 AND (&&)나 OR (||) 연산에서 사용되며, 조건문에서 자주 등장한다.

    AND (&&) 연산자

    • 왼쪽 조건이 false이면, 전체 결과는 무조건 false이다.
    • 그래서 오른쪽 조건을 평가하지 않고 바로 false를 반환한다.
    Copy
    if (isLoggedIn && user.hasPermission()) {
    	// isLoggedIn이 false이면, user.hasPermission()은 실행되지 않음
    }

    OR (||) 연산자

    • 왼쪽 조건이 true이면, 전체 결과는 무조건 true이다.
    • 그래서 오른쪽 조건을 평가하지 않고 바로 true 반환한다.
    Copy
    if (isAdmin || user.hasAccess()) {
    	// isAdmin이 true이면, user.hasAccess()는 실행되지 않음
    }

    ⚠️ 왜 중요한가요?

    • 불필요한 연산을 줄여 성능을 향상시킬 수 있다.
    • 오류를 방지할 수 있다. 예를 들어 null 객체 접근을 막는 데 유용하다.
    Copy
    if (obj != null && obj.property == 'value') {
    	// obj가 null이면, property 접근 시 에러 발생하는 것을 방지
    }

    HTTP 409 에러

    409 에러는 HTTP 상태 코드 중 하나로, 요청이 서버의 현재 상태와 충돌하여 처리될 수 없을 때 발생한다. 주로 PUT 요청이나 데이터베이스 업데이트 시 중복된 값을 저장하려고 할 때 나타난다.

    useAsyncEffect

    useEffect 내 비동기 함수를 안전하게 처리하기 위한 함수 (커스텀)

    Copy
    export function useAsyncEffect(
    	effect: () => Promise<void | (() => void)>,
    	deps?: DependencyList
    ) {
    	useEffect(() => {
    	let cleanup: (() => void) | void;
    
    	effect().then(result => {
    		cleanup = result;
    	});
    
    	return () => {
    		cleanup?.();
    	};
    
    	// eslint-disable-next-line react-hooks/exhaustive-deps
    	}, deps);
    }

    Geolocation API

    사용자의 동의를 받아 위치정보를 표시한다.

    navigator.geolocation 을 통해 접근한다.

    Ref https://developer.mozilla.org/en-US/docs/Web/API/Geolocation_API

    캡티브 마켓

    캡티브 마켓이 존재한다는 건 특정 시장에서 독점이나 과점이 형성되어 있다는 의미로 받아들여진다. 우리나라에서는 주로 계열사 간 내부시장을 뜻하는 말로 사용된다.

    Ref https://www.moef.go.kr/sisa/dictionary/detail?idx=2543

    ky

    • fetch API에 기반한 작고 우아한 HTTP 클라이언트
    • 지원 항목
      • Simpler API
      • Method shortcuts (ky.post())
      • Treats non-200 status codes as errors
      • Retries failed requests
      • JSON option
      • Timeout support
      • URL prefix option
      • Instances with custom defaults
      • Hooks

    Ref https://www.npmjs.com/package/ky/v/0.9.0

    react-query의 mutate vs mutateAsync

    mutate

    • 콜백 기반 처리: 성공/실패 핸들링을 위해 onSuccess, onError, onSettled 등의 옵션이나 인라인 콜백을 사용.
    • Promise를 반환하지 않음: await를 사용할 수 없음.
    • 주로 이벤트 핸들러에서 사용**: 예: 버튼 클릭 시 네트워크 요청을 트리거할 때.
    Copy
    const mutation = useMutation({
    	mutationFn: (data) => postUser(data),
    	onSuccess: () => {
    		console.log('성공!');
    	}
    });
    
    mutation.mutate({ name: '지은' });

    또는 콜백을 인라인으로 제공한다:

    Copy
    mutation.mutate({ name: '지은' }, {
    	onSuccess: () => console.log('요청 성공'),
    });

    mutateAsync

    • Promise를 반환: await 또는 .then().catch()로 처리 가능.
    • try-catch 문으로 오류 제어 가능: 동기적인 코드 흐름으로 작성 가능.
    • 조건부 로직 처리에 유리: 요청 결과에 따라 로직 분기 처리해야 할 경우에 좋음.
    Copy
    const mutation = useMutation((data) => postUser(data));
    
    const handleSubmit = async () => {
    	try {
    		const response = await mutation.mutateAsync({ name: '지은' });
    		console.log('성공:', response);
    	} catch (error) {
    		console.error('에러:', error);
    	}
    };

    typescript asserts

    일반적으로 단언(또는 불변)이라고 불리며, 변수가 예상한 것과 일치하지 않을 때 초기에 에러를 발생시키는 기능이다.

    Copy
    assert(someValue === 42);

    위 예제에서 someValue42가 아니라면 AssertionError가 발생한다.

    적절하지 않은 타입을 넘기는 것을 방지한다.

    Copy
    function multiply(x, y) {
    	assert(typeof x === "number");
    	assert(typeof y === "number");
    
    	return x * y;
    }

    Ref https://devblogs.microsoft.com/typescript/announcing-typescript-3-7/#assertion-functions

    사용자의 브라우저가 동작하는 환경을 명시한다.

    예) "MacIntel""Win32""Linux x86_64""Linux armv81".

    Ref https://developer.mozilla.org/en-US/docs/Web/API/Navigator/platform

    vercel satori

    HTML과 CSS를 SVG로 변환하는 라이브러리

    다음 JSX 코드를

    Copy
    import satori from 'satori'
    
    const svg = await satori(
      <div style={{ color: 'black' }}>hello, world</div>,
      {
        width: 600,
        height: 400,
        fonts: [
          {
            name: 'Roboto',
            // Use `fs` (Node.js only) or `fetch` to read the font as Buffer/ArrayBuffer and provide `data` here.
            data: robotoArrayBuffer,
            weight: 400,
            style: 'normal',
          },
        ],
      },
    )

    다음과 같은 svg로 바꿔준다.

    Copy
    '<svg ...><path d="..." fill="black"></path></svg>'

    Ref https://github.com/vercel/satori

    Timeout의 종류

    Connection Timeout

    • 클라이언트가 서버측으로 connection을 맺길 원하지만 서버의 장애 상황으로 connection조차 맺어지지 못할 때 발생하는 timeout이다.
    • 우리가 흔히 알고있는 TCP 3 way handshake를 통해 TCP 연결이 생성되지 못한것을 의미한다.

    Read Timeout

    • 클라이언트와 서버가 connection을 맺으면 하나의 데이터 덩어리가 아닌 여러개의 패킷으로 나눠서 전송하게 되는데, I/O작업이 길어지거나 락이 걸려 요청이 처리되지 못하고 있을 때 클라이언트는 더 이상 기다리지 못하고 커넥션을 끊는다. 즉, 응답을 기다리지 못하는 것이다. 이런 상황을 Read Timeout 이라고 하는데 java에서는 SocketTimeout Exception이 떨어진다.

    import map

    JSON object 형태로 모듈 정의자를 지정할 수 있다.

    Copy
    <script type="importmap">
    	{
    		"imports": {
    			"shapes": "./shapes/square.js",
    			"shapes/square": "./modules/shapes/square.js",
    			"https://example.com/shapes/square.js": "./shapes/square.js",
    			"https://example.com/shapes/": "/shapes/square/",
    			"../shapes/square": "./shapes/square.js"
    		}
    	}
    </script>

    절대 또는 상대 경로에 매핑하여, 빌드 과정을 거치지 않고도 모듈 해석을 제어할 수 있다.

    Ref https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules#importing_modules_using_import_maps

    Aggregation api

    여러 개의 데이터를 그룹화하고 통계를 낸 결과를 반환해주는 API이다.

    예를 들어, 2024년에 팔린 상품 중 카테고리별 총 매출이 얼마인지 보고 싶을 때, 여러 데이터를 집계(Aggregation) 할 수 있다.

    💡 실제 예시 (마케팅 플랫폼 API 예시)

    • 데이터:

      Copy
      [
      	{ "campaign": "A", "clicks": 10 },
      	{ "campaign": "A", "clicks": 20 },
      	{ "campaign": "B", "clicks": 5 }
      ]
    • Aggregation API 호출 결과 (캠페인별 클릭 수 합계):

      Copy
      [
      	{ "campaign": "A", "clicks_sum": 30 },
      	{ "campaign": "B", "clicks_sum": 5 }
      ]

    이벤트 핸들러에서 Promise 호출하기

    🤔 이벤트 핸들러에서 Promise 함수를 호출할 때, async~await을 붙여야 할까?

    Copy
    const myPromiseFunction = async () => {
      await axios.get(...)
    }
    
    return (
    	<>
    		<button onClick={myPromiseFunction}>클릭!</button> // 1️⃣
    		<button onClick={async () => await myPromiseFunction()}>클릭!</button> // 2️⃣
    	</>
    )

    두 방법은 대부분의 경우 동일하게 작동한다.

    첫 번째 방식은 myPromiseFunction이 반환하는 Promise를 await로 기다리며, Promise가 완전히 완료된 후 함수가 끝난다.

    두 번째 방식은 myPromiseFunction이 반환하는 Promise를 기다리지 않으며, 함수는 즉시 종료되고 Promise는 백그라운드에서 실행된다.

    일반적인 경우 async~await으로 감싸는 것은 불필요하지만, 다음처럼 이벤트 핸들러에서 에러 처리 등 여러 작업을 할 때는 필요할 수 있다.

    Copy
    <button
      onClick={async () => {
        try {
          await myPromiseFunction();
          alert('완료!');
        } catch (e) {
          alert('실패');
        }
      }}
    >
      클릭!
    </button>

    📍 Monthly Pinned


    ‘네이비즘 서버시간’은 누가 만들었을까?

    개인이 만든 별 거 아닌 것 같은 프로그램이 이렇게 전국민이 다방면으로 활용하는 서비스가 되다니 흥미롭다.

    티켓팅 연습게임, 포도알 만들기, 어워즈 등의 기능까지 있었다니 체험해봐야겠다. 😆

    Ref https://yozm.wishket.com/magazine/detail/3214/

    AI의 새로운 핵심 역량은 프롬프트가 아닌 “컨텍스트 엔지니어링”

    • “프롬프트 엔지니어링”에서 한 단계 발전한 “컨텍스트 엔지니어링”으로 논의가 전환되고 있음
    • 컨텍스트란 단순한 프롬프트 문장이 아니라, LLM이 답변을 생성하기 전 볼 수 있는 모든 정보(지침, 대화이력, 장기 메모리, 외부 정보, 가용 도구 등) 를 의미함
    • 에이전트의 성공과 실패는 이제 모델의 성능보다 컨텍스트의 질에 달려 있음
    • 고도화된 에이전트는 사용자의 캘린더, 과거 이메일, 연락처 등 다양한 맥락을 통합해 더 실제 문제 해결에 가까운 응답을 생성함
    • 컨텍스트 엔지니어링은 상황 맞춤형 동적인 시스템 설계로, 올바른 정보와 도구를 정확한 시점에 LLM에 제공하는 과정임

    Ref https://www.philschmid.de/context-engineering

    낙관주의가 현실을 만든다

    ‘현실적인’ 기대치는 사실 ‘현실적’이지 않을 수도 있다!

    “속도를 높여라(Up the tempo)”, 그리고 “야망이 현실을 만든다(Ambition shapes reality)”

    Ref https://blogbyash.com/translation/optimism-shapes-reality/

    접근성, 현실적으로 어디까지 가능할까?

    단순히 Voice Over용 label을 잘 붙이거나 텍스트 크기를 키우는 것이 아닌,

    유저의 디지털 숙련도에 따라 UI를 커스텀하고 있던 여러 서비스의 노력들.

    Ref https://slashpage.com/grit-han-94/grit-han-article?post=943zqpmqr4n3q2wnvy87

    대부분의 RESTful API는 실제로 RESTful하지 않음

    • Fielding의 규칙에 따르면 진정한 RESTful API는 하이퍼미디어(HATEOAS) 기반 동적 탐색이 필수임
    • REST는 단순히 HTTP 위에서 CRUD를 구현하는 것이 아니며, 웹의 원리와 같이 느슨한 결합·진화 가능성·동적 상태 전이에 초점을 둔 아키텍처임
    • 현실에서는 실용성과 팀의 상황에 맞는 설계가 더 중요할 수 있음
    • 외부 개발자를 위한 퍼블릭 API라면 HATEOAS 채택이 권장되지만, 내부 전용 API라면 단순한 RPC 스타일도 실용적임
    • API는 배우기 쉽고 오용하기 어렵게 설계하는 것이 핵심이며, 반드시 RESTful일 필요는 없음

    Ref https://florian-kraemer.net//software-architecture/2025/07/07/Most-RESTful-APIs-are-not-really-RESTful.html

    과도한 JavaScript 중심 개발, 웹을 망가뜨리다

    • JS 프레임워크 남용으로 웹사이트 복잡성 심화
    • 개발자 경험(DX)이 사용자 경험(UX)을 압도
    • 단순한 작업에도 과도한 구조 요구
    • 성능·접근성·유지보수성 모두 저하
    • 웹 본연의 기능 회복이 해법

    글만 읽으면 완전히 디스토피아 같다…⚔️

    Ref

    ‘소셜’ 지워지는 소셜미디어, 이대로 끝나는 걸까?

    소셜 미디어 생태계의 근본적 변화 - 소셜미디어는 더 이상 ‘소셜하지 않다’

    전통적인 소셜 네트워크 서비스들은 이제 점차 디지털 콘텐츠 소비 플랫폼으로 전환되고 있다.

    Ref https://yozm.wishket.com/magazine/detail/3243/

    프론트엔드에서 갑자기 물리학이 왜 나와?

    시간(duration) 기반의 CSS를 대체할, 물리학을 적용한 “Spring” 모델!

    뉴턴 법칙, 운동방정식, 오일러 방법… 🤯

    최근 본 변태 중에 가장 호기심 가는 변태

    Ref https://yozm.wishket.com/magazine/detail/3245/

    웹 애니메이션 최적화 requestAnimationFrame 가이드

    웹 프레임에 따라 실제 화면이 갱신되어 표시되는 주기에 따라 함수를 호출하는 requestAnimateFrame에 대한 구체적인 가이드

    반드시 1초에 60번 호출하는 것은 아니며, 디스플레이의 주사율을 따른다! (ex. 60hz)

    Ref https://inpa.tistory.com/entry/🌐-requestAnimationFrame-가이드

    Mise: 통합 런타임 버전 관리

    Node.js, Python, Java 상관없이 사용할 수 있는, 표준화된 방식의 런타임 매니저!

    mise.toml 설정 파일을 통해 같은 프로젝트의 팀원들과 패키지 버전을 통일할 수 있다.

    Ref https://www.daleseo.com/mise/

    애플, Figma/Sketch용 iOS/iPadOS 26 Design Kit 공개

    Apple 공식 Figma/Sketch용 UI 키트로, iPhone 및 iPad 인터페이스를 매우 정밀하게 재현했다.

    Ref https://developer.apple.com/design/resources/#ios-apps

    이제 모던 CSS가 SPA를 대체할 때

    • View Transitions API 같은 모던 CSS 기능의 등장으로, 이제 매끄러운 페이지 전환을 위해 SPA 구조가 필요 없는 상황임
    • 대부분의 SPA 사이트는 실제로 기대한 만큼의 성능이나 부드러운 경험을 제공하지 못하며, 오히려 무거운 JavaScript 코드가 사용자 경험을 저하시키는 경향임
    • Chromium 기반 브라우저에서 네이티브 페이지 전환과 Speculation Rules를 활용하면, 자바스크립트 없이도 빠르고 자연스러운 내비게이션 구현이 가능함
    • SPA의 복잡한 구조는 브라우저 최적화를 방해하므로, 실제 웹사이트는 HTML과 CSS 중심의 MPA 구조가 더 빠르고 관리가 쉬움
    • 앞으로는 불필요한 SPA 도입을 지양하고, 모던 CSS와 네이티브 기능을 활용해 효율적이고 유지 관리가 쉬운 웹사이트 개발이 필요함

    Ref https://www.jonoalderson.com/conjecture/its-time-for-modern-css-to-kill-the-spa/

    그록(Grok)은 정말 챗GPT만큼 쓸만한가요?

    ‘말귀 점수’와 ‘다재다능 점수’ 등의 현실적인 지표로 분석한 재밌는 글

    Ref https://yozm.wishket.com/magazine/detail/3266/

    이벤트와 함수는 다르다

    항상 주장하고 싶었던, handleClickonClick를 구별해서 사용하는 것

    하지만 느낌으로만 설명 가능할 뿐, 논리적으로 근거를 붙이기가 어려웠는데

    답답했던 내 맘을 속 시원히 설명해준, 영어박사의 글

    핵심 HTML의 기본 이벤트를 생각해보자

    Copy
    <button onClick={handleClick}>클릭</button>

    여기서 onClick은 “클릭이 발생했음” 을 브라우저가 알려주는 이벤트

    handleClick은 그 이벤트를 받아서 실행되는 함수

    즉, 브라우저는 “클릭이 일어났어!”라고 알려주고, 개발자는 “그럼 이 함수를 실행할게”라고 응답하는 구조다.

    이벤트는 “알림” - on + 실제 발생한 일 함수는 “실행” - 동사 원형 + 실제 수행할 작업 HTML처럼 생각 - 기본 태그의 이벤트 패턴 참고 재사용 고려 - 특정 컨텍스트에 종속되지 않는 이름 의미의 일치 - 이름과 실제 동작이 일치해야 함

    Ref https://junilhwang.github.io/TIL/clean-code/조각모음/이벤트와_함수는_다르다/#_3-headless-ui의-장점들

    Zero - Gmail을 대체 가능한 오픈소스 AI-기반 이메일 클라이언트

    이메일 서비스를 만들어 볼까… 🙄

    Ref https://github.com/Mail-0/Zero

    ForesightJS - 마우스·키보드 예측 기반 퍼포먼스 최적화 프리패칭 JS 라이브러리

    • 사용자 인텐트(의도)를 실시간으로 예측하는 초경량 자바스크립트 라이브러리
    • 마우스 궤적, 스크롤 방향, 탭/키보드 이동 등 사용자 행동을 실시간 분석해, hover 발생 전 예상 타겟에 미리 액션 실행
    • 프리패칭 시점 최적화 : 무엇(what) 을 언제(how) 불러올지는 개발자가, 언제(when) 프리패칭할지는 ForesightJS가 담당

    사용자 의도를 예측한다니! 진짜 별 게 다 나온다. 요즘 관심 있는 뇌과학과 연결됐을지도?

    상당히 직관적으로 체험 가능한 홈페이지 구경 추천 👇👇

    Ref https://foresightjs.com/

    Fast - 빠른 소프트웨어의 힘

    • 소프트웨어 개발에서 빠름(fast)을 요구하는 일은 드물지만, 빠른 소프트웨어는 사용자 행동에 변화를 만들어냄
    • 빠른 배포와 실시간 스트리밍 같은 기술은 업무 효율과 원격 근무를 혁신적으로 향상시킴
    • 느린 소프트웨어는 인지적 마찰을 유발하고, 실제로 사용자의 생산성을 크게 저하시키는 요인임
    • 빠른 소프트웨어는 복잡성을 감추지 않으며, 단순성과 집중력을 보여줌
    • 앞으로 개발 산업에서는 성능과 경험 최적화를 중시하는 흐름이 강해질 전망임

    좋았어 빠르게 달려보는 거야 🏃‍♀️

    빠름, 그리고 단순함

    Ref https://www.catherinejue.com/fast

    🧺 Wrap up


    와! 진짜 너무 덥다. 말이 안 되는 폭염과 열대야의 연속 🥵

    팀이 건물을 옮긴 후 더 쩌는 디모. 거리가 멀어진 만큼 끝없이 올라가는 한낮 최고기온과 스트레스

    하지만 이 속에서도 내 길을 찾아야지.


    Relative Posts:

    2025년 6월

    June 29, 2025

    zigsong

    지그의 개발 블로그

    RotateLinkImg-iconRotateLinkImg-iconRotateLinkImg-icon