JS, TS

아이콘은 어떤 확장자로 써야할까? (SVG, PNG, JPEG, GIF, WebP)

Mitchell 2023. 9. 20. 00:31

아이콘 이미지는 어떻게 관리할 것인가?

여러 프로젝트에서 디자인시스템과 함께 일관된 아이콘을 제공해주기 위해서는 아이콘 또한 쉽게 import 할 수 있는 방법을 제공해야합니다. 이때 아이콘이미지를 어떤 파일로 제공할 것인지 결정하는게 중요한 포인트인데요. 이미지 확장자에 따라 용량, 특성이 모두 다르기 때문입니다. 

 

결론부터 말하자면, 아이콘은 SVG.

SVG로 아이콘을 제공하는 것이 가장 효과적이고 효율적인 방법이라고 생각되어 사내 디자인시스템 내에서는 모든 아이콘을 SVG 형태로 제공하도록 결정하였습니다. 정확히는 SVG를 이미지 형태로 제공한 것이 아니라, 리액트컴포넌트로 랩핑하여 제공합니다. 어떠한 특성 때문에 그렇게 가능한지 SVG가 무엇인지 알아보겠습니다.

SVG (Scalabe Vector Graphics)

  • 2차원 벡터그래픽을 표현하는 XML기반의 마크업 언어
  • 이미지 자체가 아니고 언어를 말하기도 한다.
  • 웹 표준에 맞게 잘 동작한다.
  • HTML 태그 안에서 사용 가능하다
  • 이미지 손실 및 품질 저하 없이 확대 축소하여 렌더링 가능
  • CSS, DOM, JS로 조작 가능

위 설명처럼 HTML태그 안에서 사용가능하며, CSS, DOM, JS로 조작가능하기 때문에 이미지파일로 렌더링하지 않고 아이콘 컴포넌트를 불러와서 렌더링 할 수 있게됩니다.

 

예를 들어 다음과 같이 "✕" 아이콘을 SVG 태그로 작성하고 export 할 수 있습니다.

import { IconWrap, IconWrapProps } from '../components/icon'

export const CloseIcon = (props: IconWrapProps) => (
    <IconWrap {...props}>
        <svg
            xmlns='http://www.w3.org/2000/svg'
            viewBox='0 0 24 24'
            fill='currentColor'
        >
            <path
                fillRule='evenodd'
                clipRule='evenodd'
                d='M12.0021 10.9415L18.9437 4L20.0044 5.06066L13.0628 12.0022L20.0044 18.9437L18.9437 20.0044L12.0022 13.0629L5.06066 20.0044L4 18.9437L10.9415 12.0022L4 5.06078L5.06066 4.00011L12.0021 10.9415Z'
            />
        </svg>
    </IconWrap>
)

 

IconWrap에서는 아이콘을 사용하는 곳에서 사용자가 원하는 형태로 아이콘이 보여질 수 있도록 속성을 변형하는 역할을 합니다.

여기에서는 간단히 색상과 사이즈를 받아 보여주도록 처리하고 있습니다.

import styled from '@emotion/styled'
import { PropsWithChildren } from 'react'

export type IconProps = {
    color?: string
    size?: 'sm' | 'md' | 'lg'
}

export type IconWrapProps = PropsWithChildren<IconProps>

const StyledIconWrap = styled.span<IconProps>`
    display: inline-flex;

    svg {
        width: 1em;
        height: 1em;

        ${({ color }) => color && `color: ${color};`}

        ${({ size }) => {
            if (size === 'sm') {
                return `font-size: 16px`
            }

            if (size === 'lg') {
                return `font-size: 32px`
            }

            return `font-size: 24px`
        }}
    }
`

export const IconWrap = ({ color, size, children }: IconWrapProps) => {
    return (
        <StyledIconWrap color={color} size={size}>
            {children}
        </StyledIconWrap>
    )
}

 

특히 SVG를 이미지파일이 아니라 보여드린 구현 예제처럼 아이콘을 관리한다면, 아이콘의 색상, 크기 등 더 다양한 요소들을 동적으로 표현 할 수 있게 됩니다. 게다가 코드로서 제공하기 때문에 아이콘이 렌더링 되는 페이지에서 별도의 HTTP 요청을 통해 이미지를 로드할 필요가 없어 웹앱의 로딩 속도도 빠릅니다.

 

결론적으로 아이콘을 웹사이트 내에서 UI 형태로 렌더링 하는 목적만 있다면, 재사용성, 조작용이성, 로딩속도, 벡터이미지의 특성 덕분에 아이콘에 있어서는 SVG를 선택하는 것이 좋아보입니다.


SVG에 대해 코드예제와 함께 특성과 선택 이유를 알아보았는데요. 웹앱에서 주로 쓰이는 다른 확장자들은 어떤 특성이 있는지도 파악하여 알맞은 곳에서 알맞은 파일을 사용하도록 하겠습니다.

JPEG

  • 웹에서 가장 많이 쓰이는 파일 형식
  • jpg, jpeg, jpe, jif, jfif, jfi 확장자들 모두 JPEG
  • 용량이 작아 사진전송, 웹사이트 게시 등 유리
  • 손실압축 방법으로 이미지 원본이 깨질 수 있음

 

GIF(Graphics Interchange Format)

  • 주로 움짤이나 밈애니메이션 등 웹상에서 짧은 애니메이션들이 GIF
  • 용량이 작아 전송 속도 빠름
  • 무손실압축으로 이미지 품질 저하 없음.
  • 최대 8비트, 256가지 색상으로 비교적 제한된 표현
  • 짧고 빠른 애니메이션에 적합

 

PNG(Portable Network Graphic)

  • 고화질 이미지 표현에 적합
  • 1,600만개의 색상 표현 가능
  • 투명, 반투명 표현 가능 (누끼)
  • GIF, JPEG 보다 크기가 큼

 

WebP

  • GIF, JPG, PNG를 대체하는 웹 전용 확장자
  • 크기는 다른 확장자 보다 작으면서 품질을 높음
  • 대부분의 최신 브라우저에서는 지원하고 있으나, 제공하는 서비스 환경에 따라 체크가 필요함.
  • https://caniuse.com/webp