웹 표준 및 성능 최적화의 방법과 필요성

최동민·2022년 11월 6일
1

성능을 테스트해볼 수 있는 SITE

https://caniuse.com/-
내가사용할 css가 어느 브라우저까지 지원하는지 확인할 수 있는 사이트다.
자신이 사용할 속성값을 쓰면, 어디까지 지원을 해 주는지 알 수 있다.

https://coding-levup.tistory.com/5
W3C 웹 표준 검사하기

https://developer.chrome.com/docs/lighthouse/overview/
라이트하우스 체크

https://pagespeed.web.dev/


웹 성능 최적화란

웹은 무수히 많은 프로토콜과 많은 실행 환경 속에서 동작이 되고 있기 때문에 웹 성능 최적화 위한 방법들을 단순히 정의하는게 쉽지 않다. 웹 어플리케이션은 복합적인 환경에 따라 비슷한 듯 다른 듯 동작하며 같은 데이터를 이용해도 빠를수도 느릴 수도 있다. 또 사용자가 인지적으로 느끼는 성능 향상은 상당히 주관적이다. 지표 상으로 구체적인 성능 향상을 보여도 사용자는 인지하지 못할 수도 있다.

성능 최적화는 단순히 각종 비용을 줄이는 측면에서 볼 수 있다. 프로그램은 컴퓨터의 리소스를 소모하면서 동작한다. 소모하는 리소스에는 메모리 사용량, 처리 시간 등이 있다. 처리해야 될 작업이 복잡 하고 클수록 리소스를 더 많이 소모하게 되고 이는 성능 저하로 이어 진다. 웹 프론트앤드 환경에서는 각종 파일들을 주고 받으며 화면을 띄우고 화면을 업데이트하는 과정속에서 비용을 소모한다. 웹 프론트앤드 성능 개선을 위해서 웹 개발자는 최소한의 데이터로 가장 빠른 시간에 사용자가 불편함을 느끼지 않는 최적의 화면을 띄워야 한다. 성능 최적화를 하게 되면 곧 사용자 경험의 개선으로 이어지고 기업의 실적으로도 이어진다. 성능 최적화를 위해 어떤 부분을 신경 써야 하며 어떤 전략들을 쓰고 있는지 알아보도록 하겠다.

최근의 성능 측정에서는 사용자가 직접 느끼는 부분을 중요시 하기 때문에 다음과 같은 사용자 기준으로 성능을 측정한다.

FP(First Paint) : 처음 뭔가 그리기 시작
FCP(First Contentful Paint) : 텍스트나 이미지 그리기 시작
FMP(First Meaningful Paint) : 의미 있는 데이터 그리기 시작
TTI(Time to Interactive) : 사용자가 행동을 취할수 있는 시점

같은 혹은 더 빠른 DOMContentLoaded, load 이벤트 시점이라도 사용자는 점차적으로 보이는 화면을 더 빠르다고 판단한다.

성능을 개선하기 위해 고려해야 할 것들

프론트 엔드 성능 최적화 정리 참고 링크

사용하지 않는 css 제거

  • Unused css는 구글 크롬 라이트하우스(Lighthouse)를 통해 확인할 수 있다.

애니메이션 최적화

  • 애니메이션을 구현할 때에는 자바스크립트 api, 라이브러리 보다 css를 통해 구현하는 것이 성능면에서 이득이다.
  • transform은 리플로우와 리페인트 모두 발생시키지 않고 합성만 발생시키는 속성이다.
    때문에 애니메이션에서 사용 시 렌더링 속도를 향상시킬 수 있다.

HTML 마크업 최적화

  • HTML은 태그의 중첩을 최소화하여 단순하게 구성한다. 또한 공백, 주석 등을 제거하여 사용한다. 권장하는 DOM 트리의 노드 수는 전체 1500개 미만, 최대 깊이는 32개, 자식 노드를 가지는 부모 노드는 60개 미만이다. (참조: Excessive DOM) 불필요한 마크업 사용으로 인해 DOM 트리가 커지는 것을 막고, HTML 파일 용량이 늘어나지 않도록 해야 한다.

불필요한 태그, 공백, 주석 사용 (최적화 전)

<html>
  <head>
    ...
  </head>
  
  <body>
  
    <div>
    
            <div>
                <!-- blar blar blar -->
                <p>hello</p>
            </div>
        
    </div>
  </body>
</html>

간결한 마크업 사용 (최적화 후)

<html>
  <head>
    ...
  </head>
  <body>
    <p>hello</p>
  </body>
</html>

JS(Javascript) 최적화

DOM의 속성을 변경하면 화면 업데이트를 위해 레이아웃이 일어날 수 있다. 원래 레이아웃은 비동기이나 특정 상황에서 동기적으로 레이아웃이 발생할 수 있다. 특정 속성을 읽을 때 최신 값을 계산하기 위해 레이아웃이 동기적으로 발생하며 이를 강제 동기 레이아웃이라고 한다. 강제 동기 레이아웃은 자바스크립트 실행 시간을 늘어나게 하므로 신경 써야 한다. 강제 동기 레이아웃이 일어나는 경우와 개선 방법은 다음과 같다.

계산된 값을 반환하기 전에 변경된 스타일이 계산 결과에 적용되어 있지 않으면 변경 이전 값을 반환하기 때문에 브라우저는 동기로 레이아웃을 해야만 한다. 최신 브라우저에도 동일하게 발생하는 부분이므로 강제 동기 레이아웃을 발생할 수 있는 코드를 최대한 사용하지 않도록 주의해야 한다.

로딩 최적화

  • css는 head, js는 body 하단에서 불러온다
    • 웹 페이지가 로드되면 html과 css가 동시에 파싱된다. html과 css는 바로 눈에 보이는 시각적 부분을 구현하기때문에 빠르게 그려질수록 좋다. 그래서 css는 head 내에서 임포트한다.
    • 웹 페이지는 파싱을 실행하면서 script를 만나면 html 파싱을 멈추고 해당 파일을 다운로드한 뒤 실행한다. 따라서 js를 제외한 구조들의 로드가 끝나고 js가 들어오는 것이 좋다. 일반적으로 body 태그를 닫기 직전에 script를 임포트 한다.
  • async / defer
    asyncdefer 속성은 스크립트 파일을 병렬로 다운로드하게 해준다. 즉, 로딩 시 웹페이지 해석을 멈추지 않고 스크립트를 다운로드 하는것이다.
    • async는 다운로드 후 즉시 실행한다.
    • defer는 웹페이지가 모두 그려지고 DOM이 들어왔을 때 스크립트를 실행한다.

< script >

< script async > : 병렬 다운로드 & 즉시실행

< script defer > : 병렬 다운로드 & 지연실행

<script> - 반드시 순서대로 실행되어야 할때
<script async> - 빨리 실행되어야 할때
<script defer> - 마지막에 파싱해도 상관없을때

이미지 최적화

  • img 지연로딩 활용하기
    loading 속성을 사용해서 이미지를 브라우저 화면에 지연/병렬 로딩할 수 있다.
    사용 가능한 값으로 auto, lazy, eager가 있다.
  • auto: 디폴트 값. loading 속성을 쓰지 않은 것과 같다.
  • lazy: 화상에 보이는 부분만 먼저 출력하고 화면 바깥쪽 이미지들은 로딩하지 않는다.
    사용자가 화면을 위로 올리면 아래쪽에 있던 이미지가 올라오면서 로딩된다.
  • eager: 화면 위치에 상관없이 페이지가 로딩되자마자 이미지를 로드한다.
 <img src="item.jpg" loading="lazy" alt>

웹팩(Webpack) 사용

모듈 번들러 웹팩(Webpack)을 사용해서 css와 js 파일을 번들링해(하나의 파일들로 묶어서) 리소스 요청을 줄일 수 있다

<html>
  <head>
    <link href="main.css" rel="stylesheet">
    <link href="sub.css" rel="stylesheet">
    <link href="sub2.css" rel="stylesheet">
  </head>
  <body>
    <div id="content">
      ...
    </div>
    <script async src="sample1.js" type="text/javascript"></script>
    <script async src="sample2.js" type="text/javascript"></script>
  </body>
</html>

웹팩 등을 통한 css/js 번들링 후 ⬇️

<html>
  <head>
    <link href="bundle.css" rel="stylesheet">
  </head>
  <body>
    <div id="content">
      ...
    </div>
    <script async src="bundle.js" type="text/javascript"></script>
  </body>
</html>

검색 엔진 최적화(Search Engine Optimization, SEO)

콘텐츠, 웹페이지를 제작함에있어 궁극적인 목적은 사용자에게 양질의 정보를 올바르게 전달하는 것이다.
잘 만들어진 콘텐츠, 잘 작성된 문서 일지라도 사용자가 읽지 않으면 그것은 콘텐츠, 문서로서 의미가 없다.

영향을 주는 요인을 살펴보자.

페이지 타이틀 < title >

title 태그는 html 문서 내 head 태그의 자식요소 중 하나이다.
브라우저 탭에 표시되며 본문 콘텐츠 내에서는 표시되지 않는다.
title 태그는 텍스트로만 구성되어야하고, JS를 통해 동적으로 생성된 타이틀도 크롤링된다. 단, 동적으로 생성 시 로딩되는 속도에 유의해야한다.
화면낭독기(스크린리더) 사용시 해당 웹페이지에 대한 정보를 제공하므로 간결하게 작성되어야하고, 각 세부 페이지마다 적절한 타이틀이 필요하다.

올바른 meta 태그 사용

  • charset
    캐릭터셋(charset)의 표준은 utf-8이다.
    utf-8로 설정 시 한글을 포함해 모든 언어를 해당 웹페이지에 표현할 수 있다.
<meta charset="UTF-8">
  • name="viewport"
    브라우저에 표시되는 화면에 대한 기준을 정해주는 메타 태그이다.
    해당 웹페이지가 모바일 디바이스에서도 볼 수 있도록 되어있는지에 대한 정보를 기입한다. 모바일 친화적인 웹이 높은 점수를 받는 것을 기억해야한다. 이를테면 반응형 웹.
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0">

<!--
width=device-width : 뷰포트=화면크기로 설정
user-scalable=no : 사용자가 화면 사이즈를 조정가능하도록 하는가=no
initial-scale=1.0 : 줌 비율=1
-->
  • name="robots"
    해당 페이지를 검색결과에 표시할지(index) 표시하지 않을지(noindex),
    그리고 페이지 안에 있는 링크를 따라 이동하게 할 것인지(follow) 아닌지(nofollow)를 지정할 수 있다.

nofollow의 경우 '크롤러가 페이지에 있는 외부 사이트 링트를 따라 이동하지 않도록 한다'는 것이 왜 필요한지 잘 와닿지 않았는데 댓글영역에 주로 사용된다고 한다.
방문자들이 입력한 링크로 크롤러가 멋대로 이동해서 연결된 페이지가 해당 페이지의 평가에 영향을 주지 못하도록 하는 것.
복수 지정이 가능하며 콤마(,)로 구분한다.

그 외에도 유효한 지시어로는
all - 기본값. 색인 생성이나 게재에 대한 제한 없음. 표시해도 어떠한 효과가 없다.
none - noindex, nofollow와 같다.
등이 있다.

<meta name="robots" content="all">
<meta name="robots" content="index,follow"> <!-- 기본값이며, all과 같다고 볼 수 있다 -->
<meta name="robots" content="noindex,follow"> 
<meta name="robots" content="index,nofollow"> 
<meta name="robots" content="noindex,nofollow"> <!-- none과 같다 -->
  • name="description"
    검색엔진의 검색결과 화면에 노출되는 텍스트. 사이트에 대한 설명을 작성한다.
<meta name="description" content="검색엔진 최적화 소개">
  • name="author"
    문서의 저작자를 표기한다.
<meta name="author" content="dmchoi">
  • name="keywords"
    구글을 비롯하여 많은 검색엔진들이 참고하지 않는 메타태그이다. 따라서 작성하지 않아도 무방하다.
    콘텐츠를 대표하는 키워드를 10개정도로 정의해야하는 일반적인 기준이 있음에도 많은 제작자 및 마케터들이 해당 속성에 지나치게 많은 키워드를 작성하는 경우가 많았고 이는 오히려 검색결과에 혼동을 준다고 판단했기때문에 키워드 메타 태그는 더 이상 사용하지 않는다.
<meta name="keywords" content="검색엔진최적화,SEO,검색엔진,최적화,웹성능최적화,Search Engine Optimization">

오픈그래프 Open Graph (OG)

오픈그래프는 어떤 HTML 문서의 메타정보를 쉽게 표시하기 위해서
메타정보에 해당하는 제목, 설명, 문서의 타입, 대표 URL 등 다양한 요소들에 대해서
사람들이 통일해서 쓸 수 있도록 정의해놓은 프로토콜이며
페이스북에 의하여 기존의 다양한 메타 데이터 표기 방법을 참조하여 만들어졌다.

og태그는 웹페이지를 공유 할 때 보여주는 미리보기이다.
크롤러가 해당 웹페이지를 먼저 방문 후 메타데이터를 크롤링해서 미리보기를 만들어준다. 페이스북에서 만들어졌고, 트위터 등 각종 SNS, 네이버, 카카오톡 등 다양한 사이트에서 사용된다.

기본적으로 웹에 설정해줘야하는 og 메타태그

<meta property="og:type" content="website">
<meta property="og:url" content="https://example.com/page.html">
<meta property="og:title" content="Content Title">
<meta property="og:image" content="https://example.com/image.jpg">
<meta property="og:description" content="Description Here">
<meta property="og:site_name" content="Site Name">
<meta property="og:locale" content="en_US">
<!-- 다음의 태그는 필수는 아니지만, 포함하는 것을 추천함 -->
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">

Naver 블로그, 카카오톡 미리보기 설정

<meta property="og:title" content="콘텐츠 제목" /> 
<meta property="og:url" content="웹페이지 URL" />
<meta property="og:type" content="웹페이지 타입(blog, website 등)" />
<meta property="og:image" content="표시되는 이미지" /> 
<meta property="og:title" content="웹사이트 이름" /> 
<meta property="og:description" content="웹페이지 설명" /> 

트위터 미리보기 설정

<meta name="twitter:card" content="트위터 카드 타입(요약정보, 사진, 비디오)" /> 
<meta name="twitter:title" content="콘텐츠 제목" /> 
<meta name="twitter:description" content="웹페이지 설명" /> 
<meta name="twitter:image" content="표시되는 이미지 " /> 

모바일 앱 미리보기 설정
모바일 앱이 존재하는 경우 앱으로 연결 시 노출

<--iOS-->
<meta property="al:ios:url" content=" ios 앱 URL" />
<meta property="al:ios:app_store_id" content="ios 앱스토어 ID" /> 
<meta property="al:ios:app_name" content="ios 앱 이름" /> 
<--Android-->
<meta property="al:android:url" content="안드로이드 앱 URL" />
<meta property="al:android:app_name" content="안드로이드 앱 이름" />
<meta property="al:android:package" content="안드로이드 패키지 이름" /> 
<meta property="al:web:url" content="안드로이드 앱 URL" />

모바일 친화적인 웹

스마트폰이 보급되고 일상생활의 필수 아이템이 되면서 모바일의 중요성이 강조되고있다.
그렇기에 반응형 웹은 꼭 필요하다.
meta name="viewport" 태그를 통해 검색엔진에 해당 사이트가 모바일 친화적이라는 것을 알려주는 것이 최적화 점수를 많이 받을 수 있는 방법.

시맨틱태그의 규칙 준수

올바르게 작성된 문서가 접근성과 성능향상에 기여한다.
보았을 때/들었을 때/css가 있을 때/없을 때 전달되는 정보의 차이가 없어야 좋은 웹문서, 콘텐츠라고 생각한다.

SSL(https) 사용 여부

https는 HTTP Secure의 약자로 HTTP protocol의 암호화된 버전이다.
http에 SSL을 적용하여 데이터 전송 기능의 보안을 강화한 전송기능(Hypertext Transfer Protocol Over Secure Socket Layer)으로 각종 바이러스 침투에 대비하는 기술들이 추가되어있으며, 구글에서 사용을 권장한다.

Google에서는 가능하면 모든 웹사이트에서 https://를 사용하기를 권장하고 있습니다. 
호스트 이름은 웹사이트가 호스팅되는 곳이며 일반적으로 이메일에 사용하는 것과 동일한 도메인 이름을 사용합니다. 
Google은 www 버전과 www가 아닌 버전(예: www.example.com 또는 example.com만)을 구분합니다. 
웹사이트를 Search Console에 추가할 때 http:// 버전과 https:// 버전을 모두 추가하고 
www 버전과 www가 아닌 버전도 추가하는 것이 좋습니다.

[출처] https://developers.google.com/search/docs/beginner/seo-starter-guide?hl=ko

핵심적인 웹 지표(LCP,FID,CLS)와 로딩속도

핵심적인 웹 지표(Core web vitals)란 실제 사용 데이터에 따른 페이지의 성능을 보여주는 지표이다. LCP, FID, CLS 세 가지 항목으로 구성되어있다.

페이지의 성능이 중요한 이유는 사용자의 이탈률 때문이다. 당연하게도 로드 시간이 길수록 이탈률이 높아진다.

페이지 로드 시간이 1초에서 3초로 늘어나면 이탈률은 32% 증가합니다.
페이지 로드 시간이 1초에서 6초로 늘어나면 이탈률은 106% 증가합니다.

[출처] https://support.google.com/webmasters/answer/9205520?hl=ko#about_data
  • LCP (최대 콘텐츠 렌더링 시간)
    사용자가 URL을 요청한 시점부터 페이지 내에서 시각적으로 가장 큰 콘텐츠를 그리는데에 걸리는 시간이다.
    사용자는 콘텐츠가 보여지면서 URL이 실제로 로드되고 있구나를 알기때문에 빨리 그려지는 것이 중요하다.
좋음: 2.5초 이하
개선필요: 4초 이하
느림: 4초 초과
  • FID (최초 입력 반응 시간)
    웹 페이지가 사용자의 동작(링크 클릭, 버튼 탭 등)에 반응할 때까지 걸리는 시간이다.
좋음: 100밀리초 이하
개선필요: 300밀리초 이하
느림: 300밀리초 초과
  • CLS (레이아웃 변경 횟수)
    누적 레이아웃 변경. 페이지가 덜컥거리면서 로딩되면 사용자는 원하는 곳에 빠르게 접근할 수 없다.
좋음: 0.1 이하
개선필요: 0.25 이하
느림: 0.25 초과

자세한 사항은 구글 코어 웹 바이탈 보고서 에서 추가로 확인할 수 있다.

profile
코드를 두드리면 문이 열린다

0개의 댓글