Bleeding edge

티스토리 성능 개선 본문

HTML & CSS

티스토리 성능 개선

codevil 2024. 2. 17. 23:49

이번에 노마드 코더 슬랙채널에서 티스토리 성능 개선하는 방법에 대한 질문의 글이 올라와서 그냥 스레드에 글을 남기기엔 긴 것 같아서 블로그에 정리를 하게 되었다. 우선 슬랙채널에 올라온 스킨은 #1 였고, 나는 #2 였다. 스킨이 다르더라도 공통되는 진단사항을 수정하는 것이 좋을 것 같아서 그 사항을 수정하려고 한다.

# 2스킨에서 진단하였을 때 나온 문제점은

요렇게 5가지가 있었고 공통되는 사항은 4가지였다.이 중에서 차세대 형식이미지 제공은 jpeg를 webp로 바꾸는 것을 의미하고, 효율적으로 이미지 인코딩 역시 이미지 사이즈를 변경하는 것이니, 코드로 해결할 수 있는 것에 한계가 있음으로 생략하겠다

 

# 0 스킨 편집하는 페이지로 이동

1번을 시작하기에 앞서 우선 스킨을 편집하는 페이지로 이동하는 방법은 다음과 같다.

1. 사용중인 스킨 편집

 

2. 우측의 html 편집 클릭

 

다음과 같은 화면이 좌측에 나온다면 OK! 이제부터 문제를 해결해보자

#1 렌더링 차단 리소스 제거하기

렌더링 차단 리소스 제거같은 경우, 안쓰는 자바스크립트 파일을 제거하거나, 큰 용량의 script를 비동기 속성을 넣어서 DOM을 그리는데 지연시키지 않도록 수정하는 방법이 있다. 모두 async 처리를 할 필요는 없기에 images/script 부터 async 처리하였다

진단을 다시한 결과 아직 빨간색이 뜨는 것을 봐서는 남아있는 Jquery도 처리해야할 것 같다. 

 

?! 분면 Jquery를 처리해서 시간을 줄였는데도! 라고 생각해서 Jquery 검색해보니 Jquery를 두번 import하는 것을 알 수 있었다. 그래서 스킨에 있는 Jquery는 그냥 삭제하였다. async 처리된 jquery를 없앤 것이기 때문에 사실 렌더링 차단 리소스에는 영향이 없었지만.. 이제 마지막으로 수정할 수 있는 것은 (저 위에 있는 Kakao에 관련된 것은 스킨에서 수정할 수 없기 때문에) css를 preload화 시킬 것이다.

<link rel="preload stylesheet" as="style" href="./style.css" />

<link rel="preload stylesheet" as="style" href="./images/font.css" />

MDN을 보면 rel을 preload 하나로만 사용하여 표현을 하였는데, 문제는 preload 하나만 넣었을 때 브라우저의 환경에 따라 css가 불러와지지 않는 경우가 있어 보험을 위해 stylesheet를 넣었다. => 클리어!

 

 

# 2 콘텐츠가 포함된 최대 페인트 요소

2번의 원인은 # 2 스킨같은 경우 mFeature라는 HTMLElement였다.

mFeature에 그려지는 이미지가 어떤식으로 그려지는 지를 확인해 보기 위해 DevTools를 켰다

음.. 느릴만했던 것 같다. 우선, background-image가 image 태그로 바꾸었다. 

<link rel="preload" as="image" href="https://t1.daumcdn.net/tistory/0/Ray2/images/header_default.jpg" />
    
<img src="https://t1.daumcdn.net/tistory/0/Ray2/images/header_default.jpg" style="
    width: 100%;
    height: 100%;
    object-fit: cover;"
    decoding="async"
>

로드지연이 15초에서 4초로 줄어들었다. 많이 줄었지만 빨간색이 아직 있기에 이를 수정하기 위하여 이미지 placeholder를 적용하였다.

Imageplace holder란?

처음에는 저화질의 이미지를 가지고 있다가, 이미지가 다 받아진 이후에 이미지의 src를 바꿔주는 방법이다. 우선 저화질의 이미지를 src에 그리고 고화질의 이미지를 data-src에 넣어주었다. 저화질의 이미지를 어디에 올리는 과정은 너무나 귀찮은 과정이기 때문에 1px의 이미지를 base64로 만들었다. 아래의 사이트를 이용하면 쉽게 만들 수 있다.

https://png-pixel.com/

 

Transparent PNG Pixel Base64 Encoded

Embed PNG pixels directly in your source code If you don't like having small 1x1 pixel images in your projects, you can embed the base64 encoded pixel directly in your css or html source files. CSS background-image: url(data:image/png;base64,); HTML <img s

png-pixel.com

 

<img 
    class="async_image"
    data-src="https://t1.daumcdn.net/tistory/0/Ray2/images/header_default.jpg" style="
    width: 100%;
    height: 100%;
    object-fit: cover;"
    src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mOUrgcAALsAnJT8wwsAAAAASUVORK5CYII="
>

이제 이미지가 로드되었을 때 바꿔주는 코드를 넣어보자

<script>
window.onload= () => {
  const objects = document.getElementsByClassName('async_image');  Array.from(objects).map((item) => {
    const img = new Image();
    img.src = item.dataset.src;
    img.onload = () => {
      return item.src = item.dataset.src      
  };
  });
};
</script>

 

초기 렌더링이 굉장히 빨라졌다는 것을 볼 수 있다. 다른 시도를 해서 빨간색을 없애고 싶었지만 이미지의 용량이 3MB나 되다보니 렌더링 지연까지 없애는 것은 힘들어서 -_= 이정도로 만족하였다.