이번 글에서는 웹 리소스(CSS,JS, 외부 라이브러리 등)와 이미지, 동영상, 오디오, 검색에 이르기 까지 전반적인 웹 최적화 방법에 대해 정리해보았습니다.
웹 리소스 최적화
웹 개발 시 사용되는 CSS, JS를 비롯한 외부 오픈소스 라이브러리들의 로드 시점을 잘 분산하면 웹페이지 로드 시간을 최적화 할 수 있습니다.
1. preload
preload는 현재 페이지에서 필요한 리소스를 미리 가져오게 할 수 있는 속성값 입니다.
<link rel="preload" href="styles.css" as="style">
<link rel="preload" href="main.js" as="script">
<link rel="preload" href="font.woff2" as="font" crossorigin>
<link rel="preload" href="hero-image.jpg" as="image">
반드시 as 속성으로 브라우저에 리소스 유형을 알려줘야 하며, href 속성에 정의되어 있는 리소스 유형 또한 맞게 설정되어야 합니다.
preload는 중복 선언 시, 선언된 수만큼 리소스를 가져오기 때문에 중복에 유의해야 합니다. preload를 통해 가져와진 리소스가 현 페이지에서 3초 이내에 사용되지 않는다면 console 창에 경고 메시지가 출력되므로, 페이지 로드 시 바로 사용되지 않는 리소스는 preload로 가져올 필요가 없습니다.
따라서, 페이지에 바로 적용되어야 하는 폰트, CSS, 페이지 렌더링에 관여하는 JS가 이에 해당됩니다.
2. preconnect
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://cdn.example.com" crossorigin>
<link rel="preconnect" href="https://api.example.com">
preconnect는 외부 도메인의 리소스를 참고하는 것이 있다면 브라우저에게 알려 미리 외부 도메인과 연결할 수 있게 합니다. 이를 통해 DNS, TCP, TLS 등과 같이 연결에 필요한 시간을 절약할 수 있습니다.
3. prefetch
<link rel="prefetch" href="next-page.html">
<link rel="prefetch" href="product-details.js">
<link rel="prefetch" href="secondary-styles.css">
미래에 사용될 것으로 예상되는 리소스를 prefetch 로 미리 가져와 브라우저 캐시에 저장할 수 있습니다. prefetch를 통해 가져온 리소스는 당장 사용되는 것이 아니므로, 브라우저 렌더링에 영향을 미치지 않습니다.
prefetch로 너무 많은 리소스를 가져오면 네트워크 통신이 많이 일어나 페이지 렌더링이 오래 걸릴 수 있으므로, 적절하게 사용해야 하며, 쇼핑몰에서 원하는 제품을 클릭해서 제품 상세페이지로 이동하는 예상되는 사용자 행동에 대해 관련되는 리소스를 미리 가져올 수 있습니다.
4. loading = lazy
페이지 내 삽입된 img 또는 iframe 태그의 loading 속성으로 필요한 시점에 콘텐츠가 로드되게 할 수 있습니다.
예를 들어, 특정 페이지가 세로로 여러번 스크롤하며 봐야할 정도로 콘텐츠 양이 많다면, img 태그의 loading 속성을 사용해 이미지를 사용자가 스크롤을 내려 해당 이미지 페이지가 노출되는 순간 로드함으로써 웹 속도를 개선할 수 있습니다.
<!-- 이미지 지연 로딩 -->
<img src="image.jpg" alt="설명" loading="lazy">
<!-- iframe 지연 로딩 -->
<iframe src="embedded-content.html" loading="lazy"></iframe>
이미지 최적화
1) 권장되는 크기와 비율로 사용하기
웹 사이트 내에서 이미지는 크게 배경 이미지, 히어로 이미지, 배너 이미지, 블로그 이미지, 로고, 파비콘 으로 사용됩니다.
각 이미지 유형별로 권장되는 크기와 비율은 아래와 같습니다.
이미지 유형별 권장되는 크기와 비율, 형식
배경 이미지 | 1920x1080px | 16:9 | JPEG, WebP |
히어로 이미지 | 1600x900px | 16:9 | JPEG, WebP |
배너 이미지 | 1200x300px | 4:1 | JPEG, PNG |
블로그 이미지 | 800x450px | 16:9 | JPEG, WebP |
로고 | 200x200px 또는 250x100px | 1:1 또는 5:2 | PNG (투명) |
파비콘 | 32x32px, 16x16px | 1:1 | ICO, PNG |
로고의 경우 1:1 비율 또는 5:2 비율을 사용하며 투명도를 지원하는 PNG 형식 사용이 권장되며 최대 높이 100px 를 넘지 않는 것이 좋습니다.
2) img 태그의 srcset, sizes 속성 사용
img 태그에는 이미지 경로 지정을 위한 src 속성 외에도 여러 이미지를 한 번에 설정할 수 있는 srcset 속성이 있습니다.
srcset 속성은 sizes 속성을 함께 사용해 브라우저 너비에 따라 적절한 크기로 이미지가 보여지도록 설정해야 합니다.
<img
src="image-800w.jpg"
srcset="image-480w.jpg 480w,
image-800w.jpg 800w,
image-1200w.jpg 1200w"
sizes="(max-width: 600px) 480px,
(max-width: 900px) 800px,
1200px"
alt="반응형 이미지 예시">
3) picture 태그
<picture>는 미디어 쿼리나 자바스크립트 없이 반응형 웹 이미지를 표현할 수 있게 해줍니다.
picture 태그는 img 태그 src 리소스에 대해 다중 이미지 리소스를 정의할 수 있도록 해주는 img 태그에 대한 컨테이너 태그 입니다. 따라서, 하나의 img 태그와 0개 이상의 source 태그를 포함합니다.
media 속성
<picture>
<source media="(min-width: 1200px)" srcset="large.jpg">
<source media="(min-width: 768px)" srcset="medium.jpg">
<source media="(min-width: 480px)" srcset="small.jpg">
<img src="fallback.jpg" alt="반응형 이미지">
</picture>
type 속성
<picture>
<source type="image/webp" srcset="image.webp">
<source type="image/jpeg" srcset="image.jpg">
<img src="image.jpg" alt="최적화된 이미지 형식">
</picture>
srcset 속성과 sizes 속성
img 태그에서의 속성 사용법과 동일합니다.
4) map 태그
하나의 이미지에 여러 링크를 넣어야 할 때 사용하는 태그로, 하나의 이미지를 영역별로 구분하고 각 영역에 하이퍼 링크를 적용할 수 있게 해줍니다.
이미지와 연결된 <map> 태그를 작성하고, 자식 요소인 <area>는 이미지 안의 클릭 가능한 영역 지정을 위해 사용됩니다.
<img src="navigation.jpg" alt="사이트 내비게이션" usemap="#navigationmap">
<map name="navigationmap">
<area shape="rect" coords="0,0,100,100" href="home.html" alt="홈으로">
<area shape="circle" coords="150,150,50" href="about.html" alt="소개">
<area shape="poly" coords="250,150,300,200,250,250,200,200" href="contact.html" alt="연락처">
</map>
영역의 shape 별 coords 지정 방법은 아래와 같습니다.
<!-- 사각형(rect): 좌상단 x,y 및 우하단 x,y 좌표 -->
<area shape="rect" coords="x1,y1,x2,y2" href="link.html" alt="사각형 영역">
<!-- 원형(circle): 중심점 x,y 및 반지름 r -->
<area shape="circle" coords="x,y,r" href="link.html" alt="원형 영역">
<!-- 다각형(poly): 각 꼭지점의 x,y 좌표들을 순서대로 나열 -->
<area shape="poly" coords="x1,y1,x2,y2,x3,y3,...,xn,yn" href="link.html" alt="다각형 영역">
Image Map Generator를 사용하면, 이미지 안에 특정 위치에 대한 좌표 뿐 아니라 <map> 태그를 자동으로 생성할 수 있습니다.
map 태그를 사용하면 한 장의 이미지에 여러 링크를 적용할 수 있지만, 이미지 크기가 고정된 경우에만 사용할 수 있다는 단점이 있습니다. 반응형웹 구현시에는 미디어 쿼리 설정에 따라 여러 개의 map 태그를 준비해야 하거나 고정된 이미지 크기일 때만 사용해야 한다는 점에 주의해야 합니다.
웹 비디오와 오디오 최적화
비디오와 오디오를 최적화 하기 위해선 preload 속성을 반드시 고려해야 합니다. 사용자가 반드시 비디오나 오디오를 사용할 것이라는 확신이 없다면 preload의 속성값을 auto로 사용해서는 안됩니다. 따라서, preload에 대해선 실제 사용자의 웹 사이트 사용을 모니터링 하고 이에 맞게 적절한 속성값 (auto, metadata, none)을 설정해야 합니다.
웹 공유 최적화
오픈 그래프 프로토콜
오픈 그래프 프로토콜은 콘텐츠 공유 시 콘텐츠에 대한 풍부한 정보를 제공하는데 도움을 줍니다.
오픈 그래프 프로토콜은 HTML 문서의 <head> 태그 안에 <meta> 태그를 사용해 정의할 수 있으며, 공유하는 콘텐츠의 제목, 설명, 대표 이미지, 크기 등의 정보를 정의해 사용자 방문을 유도하는 UI를 제공할 수 있습니다.
반드시 정의해야하는 4가지 기본 프로퍼티 속성 값
<meta property="og:title" content="페이지 제목"> <!-- 공유될 콘텐츠 제목 -->
<meta property="og:type" content="website"> <!-- 콘텐츠 유형 (website, article, book 등) -->
<meta property="og:url" content="https://www.example.com/page"> <!-- 콘텐츠 표준 URL -->
<meta property="og:image" content="https://www.example.com/image.jpg"> <!-- 대표 이미지 URL -->
선택적인 속성 값
<meta property="og:description" content="페이지에 대한 간략한 설명">
<meta property="og:site_name" content="사이트 이름">
<meta property="og:locale" content="ko_KR"> <!-- 리소스 언어 -->
<meta property="og:locale:alternate" content="en_US"> <!-- 대체 언어 -->
og:image, og:video, og:audio의 구조화된 속성
<!-- 이미지 관련 오픈 그래프 태그 -->
<meta property="og:image" content="https://example.com/image.jpg"> <!-- 공유 시 표시될 이미지의 URL -->
<meta property="og:image:secure_url" content="https://secure.example.com/image.jpg"> <!-- HTTPS 프로토콜을 사용하는 이미지 URL -->
<meta property="og:image:type" content="image/jpeg"> <!-- 이미지의 MIME 타입 지정 (jpeg, png, gif 등) -->
<meta property="og:image:width" content="1200"> <!-- 이미지의 너비 (픽셀 단위) - 페이스북 권장 크기는 1200x630 -->
<meta property="og:image:height" content="630"> <!-- 이미지의 높이 (픽셀 단위) -->
<meta property="og:image:alt" content="이미지 설명"> <!-- 이미지에 대한 대체 텍스트 (접근성 향상) -->
<!-- 비디오 관련 오픈 그래프 태그 -->
<meta property="og:video" content="https://example.com/video.mp4"> <!-- 공유 시 표시될 비디오의 URL -->
<meta property="og:video:secure_url" content="https://secure.example.com/video.mp4"> <!-- HTTPS 프로토콜을 사용하는 비디오 URL -->
<meta property="og:video:type" content="video/mp4"> <!-- 비디오의 MIME 타입 지정 (mp4, webm 등) -->
<meta property="og:video:width" content="1280"> <!-- 비디오 플레이어의 너비 (픽셀 단위) -->
<meta property="og:video:height" content="720"> <!-- 비디오 플레이어의 높이 (픽셀 단위) -->
<!-- 오디오 관련 오픈 그래프 태그 -->
<meta property="og:audio" content="https://example.com/audio.mp3"> <!-- 공유 시 표시될 오디오의 URL -->
<meta property="og:audio:secure_url" content="https://secure.example.com/audio.mp3"> <!-- HTTPS 프로토콜을 사용하는 오디오 URL -->
<meta property="og:audio:type" content="audio/mpeg"> <!-- 오디오의 MIME 타입 지정 (mpeg, wav, ogg 등) -->
og:type 의 공유 콘텐츠 타입 설정 속성
og:type 속성을 사용하면 공유되는 콘텐츠가 어떤 타입인지 정의할 수 있습니다.
<!-- 일반 웹사이트 타입 - 가장 기본적인 타입으로 일반 웹페이지에 사용 -->
<meta property="og:type" content="website">
<!-- 기사 타입 - 뉴스, 블로그 포스트 등 기사 형식의 콘텐츠에 사용 -->
<meta property="og:type" content="article">
<meta property="article:published_time" content="2023-01-01T00:00:00+00:00"> <!-- 기사 발행 시간 (ISO 8601 형식) -->
<meta property="article:author" content="저자 이름"> <!-- 기사 작성자 정보 -->
<meta property="article:section" content="기술"> <!-- 기사가 속한 섹션/카테고리 -->
<meta property="article:tag" content="웹 최적화"> <!-- 기사와 관련된 태그/키워드 -->
<!-- 도서 타입 - 책, 출판물에 관한 정보를 표시할 때 사용 -->
<meta property="og:type" content="book">
<meta property="book:author" content="저자 이름"> <!-- 책의 저자 정보 -->
<meta property="book:isbn" content="978-3-16-148410-0"> <!-- 책의 국제 표준 도서 번호 -->
<meta property="book:release_date" content="2023-01-01"> <!-- 책의 출간일 -->
<!-- 프로필 타입 - 사용자, 인물 등의 프로필 페이지에 사용 -->
<meta property="og:type" content="profile">
<meta property="profile:first_name" content="홍"> <!-- 프로필 사용자의 이름 -->
<meta property="profile:last_name" content="길동"> <!-- 프로필 사용자의 성 -->
<meta property="profile:username" content="honggildong"> <!-- 프로필 사용자의 사용자명 -->
<!-- 비디오 관련 타입 - 영화, TV 프로그램, 에피소드 등에 사용 -->
<meta property="og:type" content="video.movie"> <!-- 영화 타입 -->
<meta property="og:type" content="video.episode"> <!-- TV 에피소드, 웹 시리즈 등의 단일 에피소드 -->
<meta property="og:type" content="video.tv_show"> <!-- TV 프로그램, 웹 시리즈 등의 전체 쇼 -->
콘텐츠 공유 시 유의할 사항
오픈 그래프 프로토콜로 소셜 미디어에 한 번 공유된 정보는 해당 소셜 미디어에 기록됩니다.
만약, 개발자가 HTML <meta>태그에 의해 실시간으로 반영하는 오픈 그래프 프로토콜 설정을 확인하기 위해서는 각 소셜 미디어에서 제공하는 공유 디버거 페이지에서 캐시 초기화 또는 다시 스크랩을 해야합니다.
웹 검색 최적화
구글은 구글 검색 엔진만을 위한 meta 태그를 제공합니다. meta 태그는 검색 엔진과 웹페이지에 대한 추가 정보를 제공하는 데 사용되는 HTML 태그입니다.
meta 태그 설정
검색 엔진 크롤링과 색인 생성을 위한 meta 태그에는 <meta name="robots">와 <meta name="googlebot">이 있습니다. 전자는 모든 검색 엔진에 적용되지만, 후자는 구글 검색 엔진에만 적용됩니다.
구글에서 지원하는 로봇 메타 태그에 적용할 수 있는 지시어
<meta name="robots" content="noindex"> <!-- 페이지 색인 생성 금지 -->
<meta name="robots" content="nofollow"> <!-- 페이지 내 링크 추적 금지 -->
<meta name="robots" content="noarchive"> <!-- 페이지 캐시 저장 금지 -->
<meta name="robots" content="nosnippet"> <!-- 검색 결과에 스니펫 표시 금지 -->
<meta name="robots" content="notranslate"> <!-- 번역 제안 금지 -->
<meta name="robots" content="noimageindex"> <!-- 이미지 색인 생성 금지 -->
<meta name="robots" content="max-snippet:-1"> <!-- 스니펫 최대 길이 제한 (-1은 제한 없음) -->
<meta name="robots" content="max-image-preview:large"> <!-- 이미지 미리보기 크기 (none/standard/large) -->
<meta name="robots" content="max-video-preview:-1"> <!-- 비디오 미리보기 최대 길이 (초 단위, -1은 제한 없음) -->
<meta name="robots" content="unavailable_after: 2023-12-31"> <!-- 특정 날짜 이후 색인 생성 중단 -->
<!-- 구글봇 전용 -->
<meta name="googlebot" content="noindex, nofollow"> <!-- 구글봇에게만 적용되는 설정 -->
<meta name="googlebot-news" content="noindex"> <!-- 구글 뉴스봇에게만 적용되는 설정 -->