※ 본 포스팅은 개인 기록용으로 반응형 웹에서 이미지나 요소의 비율을 유지하는 방법에 대해 고민하다가 알게된 내용을 정리한 것입니다. 혹시나 저와 비슷한 고민을 하시는 분이 계실까봐 기록으로 남깁니다.

 aspect-ratio로 반응형 웹에서 요소의 비율 유지하기

 

 들어가며

최근 캐러셀(슬라이더) 컴포넌트를 만들면서 이미지의 비율을 어떻게 유지할지 고민이 많았습니다. 처음에는 단순히 width와 height를 픽셀로 고정하거나 퍼센트(%)로 지정했는데, 이게 생각보다 쉽지 않더라구요. 고정 픽셀을 사용하면 모바일에서 깨지고, 퍼센트만 사용하면 부모 요소의 크기에 따라 이미지가 찌그러지는 문제가 있었습니다. div를 여러 개 중첩해서 해결할 수도 있겠지만, 성능 이슈가 걱정되었죠. 그러다 발견한 게 바로 `aspect-ratio` CSS 속성입니다. 

 

 aspect-ratio란?

`aspect-ratio`는 요소의 가로세로 비율을 설정하는 CSS 속성입니다. 예를 들어 16:9 비율을 유지하고 싶다면 다음과 같이 작성할 수 있습니다: 

element { aspect-ratio: 16/9; }

 

실제 사용 예시 - 기존 제가 했던 캐러셀 구현 방식의 문제점

처음에는 이런 식으로 구현했습니다

.carousel-wrapper {
  width: 100%;
  position: relative;
}

.carousel-container {
  width: 100%;
  height: 0;
  padding-bottom: 56.25%; /* 16:9 비율을 위한 padding hack */
  position: relative;
}

.carousel-item {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

.carousel-image-wrapper {
  width: 100%;
  height: 100%;
  position: relative;
}

.carousel-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
...

<div class="carousel-wrapper">
  <div class="carousel-container">
    <div class="carousel-item">
      <div class="carousel-image-wrapper">
        <img src="image1.jpg" class="carousel-image" alt="" />
      </div>
    </div>
    <!-- 추가 슬라이드 아이템들... -->
  </div>
</div>

...

여기에서 저는 처음에는 구현이 일단 됐기 때문에 다른 작업을 하다가

실제로 api 연결을 하고 사진이 많아졌을 때 컴포넌트가 버벅거리는 경험을 하게 되었습니다.

그래서 코드를 점검해보고 고민해보는 시간을 갖게 되었고 제가 내렸던 이 방식의 문제점은

  1. div가 너무 많이 중첩됩니다 (wrapper -> container -> item -> image-wrapper -> image)
  2. position: absolute를 사용해야 하는 등 복잡한 position 설정이 필요합니다
  3. padding hack(padding-bottom: 56.25%)을 사용해야 해서 코드가 직관적이지 않습니다
  4. DOM 요소가 많아져서 성능에 영향을 줄 수 있습니다

였고 어떤 식으로 최적화 및 html 요소를 줄일 수 있을지 찾아보았습니다.

 

 aspect-ratio를 활용한 개선된 구현

이걸 aspect-ratio를 사용하면 훨씬 단순화할 수 있었습니다:

.carousel {
  width: 100%;
  overflow: hidden;
}

.carousel-item {
  width: 100%;
  aspect-ratio: 16/9;
}

.carousel-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
<div class="carousel">
  <div class="carousel-item">
    <img src="image1.jpg" class="carousel-image" alt="" />
  </div>
  <!-- 추가 슬라이드 아이템들... -->
</div>

 

단순히 계산해도 원래는
캐러셀 랩퍼 > 컨테이너 > 아이템 > 아이템 랩퍼 순으로 4뎁스나 필요했었는데

개선된 코드에서는 랩퍼 없이 캐러셀, 캐러셀 아이템 만으로 엄청 간소화되었습니다.

더 좋은 방법이 있지 않을까 고민하지 않고 아는 지식만으로 구현하려 했었기 때문에

무지에서 발생한 성능저하였고, 지금 구현은 된다고 하더라도 내가 하는게 최선인지 의심해보던 초심을 몇개월동안 잃어버렸던 것 같은데 포스팅할 좋은 경험이 되었습니다.

본 포스팅은 제가 참여한 세션에 대한 정리 및 생성형 ai 테스팅을 위한 포스팅입니다.

생성형 ai로는 클로드 3.5 를 사용했고 원본 필기 내용은 포스팅하지 않았습니다.

 

# 2024 IF 카카오 컨퍼런스 리뷰: AI 혁신과 안전성의 균형

카카오가 2024년 IF 카카오 컨퍼런스를 통해 자사의 AI 전략과 새로운 서비스들을 공개했습니다. 이번 컨퍼런스의 핵심은 AI 기술 혁신과 안전성 확보의 균형이었습니다. 주요 발표 내용을 세션별로 정리해보았습니다.

## 1. 오프닝 키노트: 카카오의 AI 생태계 전략

### 관계 기반의 서비스 확장
- 카카오는 '나 > 친구 > 지인 > 비지인 > 비즈니스'로 이어지는 관계 생태계를 구축
- 카카오로그인, 카카오싱크 API를 통한 연결성 강화
- 대체 불가능한 사용자 경험 제공에 중점

### 새로운 AI 어시스턴트, Kanana(카나나)
- 모델 오케스트레이션 방식 채택: 내부 모델, 오픈소스 모델, 비공개 모델 통합 운영
- 질문 분석을 통한 최적 AI 모델 선택으로 비용 효율성 확보
- 개인화된 AI 메이트 기능 제공
  - 개인 메이트 '나나'와 그룹 메이트 '카나' 구분
  - 그룹 대화방에서 문맥을 파악하고 자연스러운 대화 참여
  - 음성 기반 대화 및 핸즈프리 모드 지원
  - PDF 등 각종 문서 분석 기능
  - 음악 플레이리스트 추천 기능
- 연말 사내 테스트 버전 출시 예정

### 주요 기술 혁신
- "페이크 시그널" 탑재로 안티어뷰징 시스템 고도화
- IP 기반 음성 생성 AI 도입
- 감정 기반 목소리 생성 기능 구현
- AI 커머스 MD 기능으로 관계 기반 커머스 강화

### 카나나 앱의 특별한 기능
- 핸즈프리 모드: 음성으로 모든 메시지 확인 및 응답 가능
- 디바이스 간 완벽한 동기화로 대화 백업 제공
- 초대 링크 기반의 그룹 커뮤니케이션 시스템
- 메시지별 의미있는 기억 보존 기능

## 2. AI Safety: 안전한 AI를 향한 노력

### AI Safety Initiative
- 3대 핵심 가치: 안전, 혁신, 포용
- AI 윤리원칙 및 리스크 관리 사이클 운영
- AI Action Summit 및 국가 인공지능위원회 출범과 연계
- AI Seoul Summit 참여를 통한 국제 협력 강화

### 책임있는 AI를 위한 8대 가이드라인
1. 사회윤리
2. 비차별과 비편향
3. 포용성
4. 투명성
   - AI 기술 활용 목적 명시
   - AI 사용 영역 명확한 알림
   - 위험 요소 사전 고지
5. 보안과 안전
6. 인권
7. 프라이버시
8. 이용자보호

### AI 리스크 유형 분류
- AI 주체 리스크
  - 기술적 리스크: 모델 불완전성
  - 장기적 리스크: 통제 불가능성, 자가발전 위험
- 인간 주체 리스크
  - 윤리적 리스크
  - 적극적 악용 및 수동적 부주의 사례 관리

## 3. Personalized 모델: KOLLAGE

### 이미지 생성 기술 혁신
- 텍스트-이미지 변환(Text to Image) 기술 적용
- 디퓨저 모델 기반의 점진적 이미지 생성
- FLUX.1.PRO 모델 도입으로 고품질 이미지 생성
- ControlNet과 LoRA 활용한 다양한 스타일 구현

### 기술적 특징
- 인스턴트부스 기반 아이덴티티 정보 학습
- 글로벌 임베딩과 패치 임베딩 결합
- SISI 데이터셋과 SIMI 데이터셋 활용
  - SISI: 단일 인물 이미지 데이터셋
  - SIMI: 다양한 각도/표정의 동일인물 데이터셋
- 영상 기반 데이터셋 구축으로 학습 데이터 확보

### 안전성 확보 방안
- 비가시성 워터마크 적용
- 얼굴 위변조 탐지 기술 도입
- 부적절 콘텐츠 필터링 시스템 구축
- 불법촬영물 신고 및 모니터링 시스템 구축

## 4. 사내 AI 봇 개발 사례

### RAG 아키텍처 활용
- 위키 기반 정보 관리 시스템
- 정보 처리 프로세스
  1. 정보수집
  2. 정보가공
  3. 정보생성
  4. 정보검토
- 하이브리드 검색 방식 도입
  - 렉시컬 서치: 키워드 기반 검색
  - 시멘틱 서치: NLP 기반 문맥 고려 검색
  - 상위 3개 응답 제공 시스템

### LLM 개발 전략
- Task별 전문 모델 구축
  - 테이블 위치/설명
  - SQL 생성
  - 일상 질문 응답
- LoRA Adaptor 활용으로 메모리 효율화
- 대화 히스토리 최적화 관리
  - 맥락 기반 히스토리 관리
  - 새로운 맥락 시 과거 히스토리 삭제
  - 연속된 맥락 시 히스토리 참조

### 실제 활용 사례
- 개발자, 기획자, 디자이너 간 업무 시간대 차이 극복
- 부재중에도 데이터 기반 응답 제공
- 과거 작업물에 대한 즉각적인 질의응답 지원

## 마치며

2024 IF 카카오 컨퍼런스는 AI 기술의 혁신과 안전성 확보라는 두 가지 목표를 동시에 추구하는 카카오의 방향성을 잘 보여주었습니다. 특히 개인화된 AI 서비스인 Kanana의 출시 준비와 함께, AI Safety Initiative를 통한 책임있는 AI 개발 노력이 돋보였습니다. 

"미래를 예측하는 가장 좋은 방법은 미래를 창조하는 것"이라는 컨퍼런스의 메시지처럼, 카카오는 안전하고 혁신적인 AI 서비스로 새로운 미래를 만들어가고 있습니다. 앞으로 카카오가 이러한 비전을 어떻게 실현해 나갈지 주목됩니다.

 

생각보다 두서 없이 내용들을 적은 것들도 최근 모델들은 맥락을 파악해서 재배치하는 능력이 우수한 것으로 보이네요

정리할 때 많이 유용할 것 같다는 생각이 듭니다.

다만, 내용을 숙지하지 못한 상태에서 너무 의존하게 되면 글은 생성을 했지만 내가 이해하지 못할 수도 있겠다는 경각심도 드는 하루였습니다.

 

body 안에

<script src="https://unpkg.com/@lottiefiles/lottie-player@latest/dist/lottie-player.js"></script>

을 삽입하고

경로를 맞춰준 뒤에

<template>
  <main>
    <h1>메인 페이지</h1>

    <div class="controller">
      <lottie-player
        src="/Red_Blue.json"
        background="transparent"
        speed="1"
        loop
        autoplay
      ></lottie-player>
    </div>
  </main>
</template>

<style>
.controller {
  width: 200px;
}
</style>


이런 식으로 삽입하면 lottie animation의 구현이 된다.

참조 : 

https://github.com/airbnb/lottie-web

 

GitHub - airbnb/lottie-web: Render After Effects animations natively on Web, Android and iOS, and React Native. http://airbnb.io

Render After Effects animations natively on Web, Android and iOS, and React Native. http://airbnb.io/lottie/ - airbnb/lottie-web

github.com

https://help.lottiefiles.com/hc/en-us/articles/4439877810841-Getting-Started

안녕하세요! 오늘은 JavaScript를 사용하여 달력을 구현하는 방법을 알아보겠습니다. 달력은 웹 개발에서 흔히 사용되는 UI 요소이며, 다양한 기능을 구현하는 데 활용될 수 있습니다.

1. 요일 계산

달력을 만들기 위해서는 먼저 각 달의 1일이 어느 요일인지 알아야 합니다. 이를 위해 getFirstDayIndex 함수를 정의합니다.

const getFirstDayIndex = (year, month) => {
  return (new Date(year, month, 1).getDay() + 6) % 7;
};

이 함수는 다음과 같이 작동합니다.

  1. new Date(year, month, 1): 해당 년, 월의 1일을 나타내는 Date 객체를 생성합니다.
  2. .getDay(): Date 객체의 요일을 가져옵니다. (0: 일요일, 1: 월요일, ..., 6: 토요일)
  3. + 6: 요일 값을 0부터 시작하도록 변환합니다.
  4. % 7: 7로 나눈 나머지를 계산하여 0부터 6 사이의 값을 얻습니다.

예를 들어, 2024년 3월 1일은 수요일입니다. 따라서 getFirstDayIndex(2024, 2) 함수는 3을 반환합니다.

 

2. 날짜 수 계산

다음으로 각 달의 날짜 수를 계산해야 합니다. 이를 위해 getDaysInMonth 함수를 정의합니다.

export const getDaysInMonth = (year, month) => {
  return new Date(year, month + 1, 0).getDate();
};

이 함수는 다음과 같이 작동합니다.

  1. new Date(year, month + 1, 0): 해당 년, 월의 다음 달의 0일을 나타내는 Date 객체를 생성합니다.
  2. .getDate(): Date 객체의 날짜를 가져옵니다.

예를 들어, 2024년 3월은 31일입니다. 따라서 getDaysInMonth(2024, 2) 함수는 31을 반환합니다.


달력도 고도화할 수 있는 여지가 많으며 구현 방법도 가지각색입니다. 다음 포스팅에서는 완성된 달력의 예시를 가져오면서 어떤 코드가 추가로 들어가는지 서술하겠습니다.

1. CDN이란 무엇인지

CDN은 Content Delivery Network의 약자로, 콘텐츠 전송 네트워크를 의미합니다. 이는 전 세계 여러 지역에 위치한 서버들을 통해 웹 콘텐츠를 효율적으로 전달하는 시스템입니다. 기본적으로 사용자가 웹 페이지에 접속할 때, 해당 페이지에 있는 이미지, CSS 파일, JavaScript 파일 등의 리소스는 웹 서버로부터 다운로드됩니다. 하지만 이 서버가 물리적으로 사용자와 먼 곳에 위치해 있다면, 데이터의 전송 속도가 느려지고 웹 페이지의 로딩 속도가 느려질 수 있습니다. 이때 CDN은 이러한 문제를 해결하기 위해 사용됩니다.



2. CDN을 웹 개발자가 왜 알아야하는지

프론트엔드 개발자에게 CDN은 매우 중요한 요소입니다. 첫째로, 웹 페이지의 성능을 향상시키는 데 도움이 됩니다. CDN은 전 세계 여러 지역에 위치한 서버를 통해 콘텐츠를 제공하기 때문에, 사용자가 가까운 서버에서 콘텐츠를 다운로드할 수 있습니다. 이로써 웹 페이지의 로딩 속도가 향상되고, 사용자 경험이 개선됩니다. 둘째로, 트래픽 부하를 줄여줍니다. CDN은 웹 서버의 부하를 분산시켜주기 때문에, 더 많은 사용자가 동시에 웹 사이트를 이용해도 서버가 안정적으로 작동할 수 있습니다.

 

3. 프론트엔드 개발자에게 CDN의 중요성

프론트엔드 개발자에게 CDN은 필수적인 도구입니다. CDN을 통해 웹 페이지의 로딩 속도를 향상시킬 수 있어 사용자의 만족도를 높일 뿐만 아니라, 웹 서버의 부하를 줄여 서버의 안정성을 높여줍니다. 이는 구글에 따르면 웹 페이지 로딩 속도가 3초에서 5초로 증가할 때, 이탈률이 32%에서 90%로 급증한다는 것을 감안할 때 매우 중요합니다.

 

4. CDN의 활용 방안

다양한 CDN 서비스가 존재하는데, 그중에서도 대표적인 서비스로는 다음과 같은 것들이 있습니다:

1) Cloudflare: 웹 성능 최적화, 보안 및 DDoS 방어, 그리고 애널리틱스 기능을 제공합니다.
2) Akamai: 글로벌 컨텐츠 전송 서비스로서, 다양한 콘텐츠 유형을 효율적으로 제공합니다.
3) Amazon CloudFront: 아마존의 CDN 서비스로, AWS와의 통합을 통해 유연한 스케일링 및 안정적인 성능을 제공합니다.
4) Fastly: 빠른 속도와 실시간 콘텐츠 전송을 지원하여 사용자 경험을 향상시킵니다.

이러한 CDN 서비스들을 활용하여 웹 페이지의 성능을 최적화할 수 있습니다. CDN을 통해 웹 페이지에 사용되는 이미지, CSS 파일, JavaScript 파일 등을 캐싱하여 전 세계 사용자에게 빠르게 전송하고, 더 나은 사용자 경험을 제공할 수 있습니다.

 

5. CDN의 활용 사례

대형 기업들은 CDN을 통해 웹 성능을 향상시키고 있습니다. Netflix는 수백만 명의 사용자에게 고화질의 영상을 빠르게 스트리밍하기 위해 CDN을 활용하고 있습니다. 또한, Amazon과 eBay는 CDN을 사용하여 상품 이미지와 정보를 빠르게 제공함으로써 사용자 경험을 향상시키고 있습니다.

CDN은 현대 웹 개발에서 필수적인 요소로 자리잡았으며, 프론트엔드 개발자에게는 이를 이해하고 활용하는 것이 중요합니다. CDN을 통해 웹 페이지의 성능을 최적화하고 사용자 경험을 향상시키는 것은 프로페셔널한 웹 개발자로 성장하는 데 있어 필수적인 요소입니다.

 

참고자료:
https://aws.amazon.com/ko/what-is/cdn/

https://www.akamai.com/ko/glossary/what-is-a-cdn

https://www.alibabacloud.com/ko/knowledge/what-is-cdn

https://library.gabia.com/contents/infrahosting/8985/

 

CDN이란 무엇인가요 - Alibaba Cloud 기술 자료

CDN은 Content Delivery Network를 의미합니다. CDN은 사용자의 위치에 따라 최종 사용자에게 콘텐츠 (웹 페이지, 동영상, 이미지 등)를 전달합니다.

www.alibabacloud.com

 

CDN(콘텐츠 전송 네트워크)이란 무엇일까요? CDN은 어떻게 작동하나요? | Akamai

콘텐츠 전송 네트워크(CDN)는 사용자와 가까운 곳에서 콘텐츠를 전송함으로써 더 빠르고 안정적인 온라인 경험을 제공합니다. 자세히 알아보세요.

www.akamai.com

 

CDN이란 무엇인가요? - 콘텐츠 전송 네트워크 설명 - AWS

콘텐츠 전송 네트워크(CDN)의 주 목적은 대기 시간을 줄이거나 네트워크 설계로 인해 발생하는 통신 지연을 줄이는 것입니다. 인터넷의 글로벌하고 복잡한 특성으로 인해 웹 사이트(서버)와 사용

aws.amazon.com

 

※ 본 포스팅은 개인 기록용으로 두서가 없을수도 있고 잘못된 정보를 제공할 수도 있습니다. 혹여나 저와 비슷한 이슈가 있는 분이 있을까봐 결론만 먼저 위에 서술하겠습니다.

 nodemon과 pm2는 같이 사용하면 안된다.

이것이 이번에 했던 뻘짓의 결론입니다.

사용하고 싶어서 같이 사용한 것은 아니지만, 회사의 레거시라 이미 작성이 되어 있는 상태였고, 요구사항은 원본과 루트폴더에 있는 파일을 수정 혹은 추가 없이 이번 이슈를 해결하는 것이었습니다.

제가 했던 프로젝트였다면 ecosystem.config.js 를 만들어서 development, production 환경을 나눠서 돌아가게 할 수 있었을텐데, 하필 회사에서 db에 로직이 추가되면서 백엔드가 주기적으로 뻗는데 pm2가 그것을 감지하지 못하는 이슈가 있었습니다. pm2에서 script를 인자로 받아서 "npm run dev"를 실행하고 있었는데 npm run dev의 script에 nodemon app.js (실제론 app.js는 아니지만 제가 pm2와 nodejs에 대해서 학습한 내용만 기록에 남기는 것이 목표이므로 프로젝트나 회사가 특정될 수 있는 정보는 전부 배제합니다) 구문이 있었기 때문입니다.

pm2로 npm run dev를 실행하는 구문은 다음과 같습니다.

pm2 start npm --name 'test_backend' -- run dev

 

 pm2가 nodemon으로 시작한 앱의 종료를 감지하지 못하는 이유

pm2가 무엇인지, pm2는 nodejs 환경에서 동작하는 내장 로드 밸런서를 포함하고 있는 프로세스 관리자(매니저)라던지와 같은 정보들은 다른 블로그와 선배들의 정리된 글이 많으므로 이번 포스팅에서는 생략하겠습니다. pm2 자체에 대한 학습이 필요하신 분들은 밑의 참고자료들의 링크를 참조해주세요.

결과는 알겠는데, 이것이 어떠한 원리로 인해서 서로 충돌이 있었는지 공부해보게 되었습니다.

이는 pm2가 무엇인지, pm2는 어떻게 동작하는지, nodemon의 목적은 무엇인지를 제대로 파악하고 있었다면 명확하게 알 수 있는 문제입니다.

프로세스 관리자는 프로세스 생성, 종료 및 모니터링과 관련된 다양한 활동을 합니다. pm2는 애플리케이션이 시작된 후 항상 status가 online이 되도록 하는 것을 목표로 합니다. (이는 중단되지 않는 서비스를 목표로 한다는 뜻 입니다.)

nodemon은 node app.js와 ctrl + c 를 계속 해야하는 번거로움을 줄여줄 수 있는 솔루션입니다. 파일 시스템의 변경을 감지하여 서버를 재시작하고 개발자들에게 더 좋은 개발 경험을 주는 것이 목표입니다.

pm2는 각 프로세스끼리 통신하면서 이벤트 혹은 시그널 등을 주고 받으며 기능을 구현하고 있습니다.

프로세스가 준비 되었다면 ready 이벤트를 보내어 이 프로세스가 online이라는 것을 알려주거나,

죽은 프로세스는 SIGOUT 시그널을 보내서 pm2가 프로세스가 종료되었음을 인지하고 다시 시작하게 합니다.

 

여기에서 nodemon과 pm2가 상호 보완적이 아닌, 독립적으로 실행되기 때문에 이슈가 발생했었습니다.

pm2는 어플리케이션이 죽어야 그것을 감지하고 재시작하는 로직인데,

nodemon은 파일의 변경을 바로바로 감지해서 서버를 재시작하기 때문에 백엔드, 프론트, db와의 연결은 상관 없이 nodemon에 의해 서버만 재시작된 상황으로 백엔드는 뻗어있고, 어플리케이션은 확실하게 종료된 적이 없기 때문에 pm2는 어플리케이션을 재시작하지 못했던 것 입니다.

 

좀 더 큰 관점으로 이야기하자면, pm2는 어플리케이션 내부의 로그를 직접 확인하지는 못하고,

내부에서는 이미 nodemon이 다 처리하고 pm2와는 아무런 관계가 없기 때문에 pm2는 몰랐던 것입니다.

 

pm2를 이용한 서버의 재기동 및 해결은 nodejs의 script와 명령어는 어떻게 어디에서 실행되는지와

linux의 cli에 대해서 좀 더 공부한 후에 해결이 가능했으나 본 포스팅에서는 내용이 중구난방이 될 수 있어서 다음에 기회가 된다면 또 정리해보려고 합니다.

(막상 한정된 주제로 이슈를 정리하고 요약하니 얼마 되지 않네요)

 

조금만 찾아봐도 nodemon은 개발환경에서, pm2는 다른 환경 혹은 서비스 배포 후에 사용한다고 보았는데,

왜 그런지 찾아보면서 부족했던 지식을 공부할 수 있는 기회가 되었습니다.

 

 참고자료

[ReferenceUrl] : https://blog.appsignal.com/2022/03/09/a-complete-guide-to-nodejs-process-management-with-pm2.html 가장 큰 도움을 받은 참고자료 입니다.

[Nodejs Document #processenv] : https://nodejs.org/docs/latest-v17.x/api/process.html#processenv

[Pm2Docs] : https://pm2.keymetrics.io/docs/usage/pm2-doc-single-page/ 

[Pm2Github] : https://github.com/Unitech/pm2

[RefArticle] : https://engineering.linecorp.com/ko/blog/pm2-nodejs

+ Recent posts