성능개선 - svg sprite 적용
프로젝트내 svg를 사용 하는 방법은 크게 2가지가 있습니다.
- jsx 내 svg를 직접 주입하는 방법
- public 폴더내 svg 파일을 저장하여 활용하는 방법
jsx내 svg를 직접 주입하는 방법의 경우 사용하기 편하다는 장점이 있지만 js 번들 크기가 늘어날 수 있다는 단점이 있어 성능에 영향을 줄 수도 있습니다.
public 폴더 위치 시켜 불러오는 방법의 경우 js 번들에 포함되지는 않지만 파일이 많아 질 수도록 관리가 힘들어져 유지보수가 어렵습니다.
과연 어떤 방법을 통해 svg를 관리하는데 좀 더 쉽고 성능적으로 최적화 할 수 있을까요..? 고민하며 서칭을 하다보니
svg sprite
기법을 활용하면 된다는것을 알게되어 관련하여 작성해보고자 합니다. SVG Sprite
svg sprite의 기본 원리는 이미지 스프라이트와 동일합니다. 이미지 스프라이트는 단일 이미지에 배치된 이미지 모음으로 좌표 값과 width, height를 가지고 필요한 이미지만 잘라내어 사용하는 이미지 최적화 기법입니다.
svg
의 경우 백터 그래픽 이미지로, xml 기반으로 화면에 그려지기 때문에 코드로 조정 할 수 있습니다. svg sprite
는 여러개의 svg를 하나의 svg로 묶어 필요한 부분만 사용하는 것으로 다음과 같은 형식을 가지게 됩니다.- 각 아이콘의
svg
태그는symbol
로 변경되며 id 값을 가지게 됩니다.
svg sprite
내 아이콘은use
태그와href
속성을 사용하여 불러올수 있습니다. (use에 대해서 더 알아보기)
그렇다면 사용시 사이트 성능 방면으로 어떤 이점이 있을까요?
- 한 번의 요청으로 여러 이미지를 로드:
- 하나의 파일 안에 여러개의 svg가 포함 되어 있어 하나의 요청으로 여러 이미지를 가져올 수 있어 네트워크 요청의 수를 감소시켜 로딩 속도를 향상 시킬 수 있습니다.
- 메모리와 대역폭을 절약:
- 하나의 스프라이트로 결합되어 중복 데이터가 줄어, 브라우저와 서버는 더 적은 메모리와 대역폭을 사용하게 됩니다.
SVG sprite 생성
svg sprite를 생성하는 방법은 2가지가 있습니다. 각자 편한 방법을 선택해서 활용합니다.
- 툴을 활용하는 방법
- 스크립트를 작성해서 생성하는 방법
SpriteBot
툴을 활용하는 방법
툴의 경우 저는
SpriteBot
을 사용 했으며 생성하는 방법은 매우 간단합니다. svg들을 묶어 sprite로 만들기 위한 폴더를 준비하고 SpriteBot
툴을 사용하여 Sprite를 생성합니다.스크립트로 자동화하여 생성하는 방법
동일한 폴더들어 있는 svg들을 sprite로 결합하기 위한
generateSvgSprite.ts
를 생성하고, glob
라이브러리를 설치합니다. - (파일 목록 조회를 하는 용도)globSync
를 사용해 각 아이콘의 경로를 배열로 가져옵니다fs
를 사용하여 각 svg내 코드를 읽어옵니다.svgElement 내 id, viewBox 및 필요 속성들을 추출하여 symbolElement로 옮겨줍니다
이후 symbols 문자열 배열을 선언하여 각 symbolElement를 문자열로 변환하여 저장한 뒤
<svg>
내에 위치시킨 뒤 fs.writeFileSync
를 통해 sprite.svg
로 저장합니다이제 작성한 코드를 실행하면 다음과 같이
public
경로에 sprite.svg
가 생성된것을 확인 할 수 있습니다.Sprite 사용하기
이제 sprite를 사용해보도록 하겠습니다.
우선
IconProvider
컴포넌트를 생성하여 내부에 sprite 코드를 넣어줍니다.이렇게 한 이유는 sprite를 body 태그 내에 삽입하여
서버로 부터 한 번만 받아오도록
하기 위해서 입니다. 넣어주는 방법으로 portal을 활용하는 방법도 있지만 저의 경우 nextJS를 사용하고 있어
_document
파일내 body 내부에 SpriteIconProvider
를 넣어주었습니다.- public 경로내에서 매번 sprite를 불러와도 상관 없다면 이 과정은 생략해도 됩니다.
다음으로 Icon을 sprite에서 불러와 사용하기 위한
SpriteIcon
컴포넌트를 생성합니다이제 아래와 같이 컴포넌트를 통해 화면에 svg가 불러와지는것을 확인 할 수 있습니다.