...
1. 폰트 로딩 최적화
@import 사용 피하기
@import url(http://fonts.googleapis.com/earlyaccess/nanumgothic.css);
@import는 폰트를 불러오는데 브라우저 로딩을 잠시 멈춰 세운다.
폰트를 로딩하고 나서야 그다음 css을 로딩하기 때문이다.
@font-face 사용
따라서, link혹은 @font-face를 통한 웹폰트 로딩을 사용하도록 하자.
link태그의 href링크로 가보면 안에 @font-face로 코딩되어있는 페이지를 볼수있다. 즉 그게 그거이다.
<link href="https://fonts.googleapis.com/css2?family=Nanum+Gothic&display=swap" rel="stylesheet">
/* 웹폰트 로드 */
@font-face {
font-family: 'GmarketSansMedium';
src: url('https://cdn.jsdelivr.net/gh/projectnoonnu/noonfonts_2001@1.1/GmarketSansMedium.woff') format('woff');
font-weight: normal;
font-style: normal;
}
Web Font Loader 라이브러리
<script src="https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js"></script>
<script>
WebFont.load({
google: {
families: ['Droid Sans', 'Droid Serif']
}
});
</script>
@import와 비슷하지만 비동기로 실행된다. 속도측면에서는 위의 link/@font-face 보다는 느리지만 폰트가 바뀔때 깜빡이는 현상등을 잡을 수 있는 이점이 있다.
2. CSS 로딩 최적화
비동기 link 로딩
media 방법
<link
rel="stylesheet"
href="non-critical.css"
media="print"
onload="this.media='all'"
/>
"Print" 미디어 타입이란,
사용자가 페이지를 프린트를 하려고 하는 경우에만 브라우저가 해당 스타일 시트를 불러오는 것으로 렌더링에는 영향을 미치지 않는다.
그리고 여기에 onload 이벤트로 this.media='all'를 추가한다면,
스타일 시트가 로드가 완료되면 미디어 속성을 다시 all로 바꾸면서 스타일 시트가 적용된다.
즉 기존에는 블록킹 방식으로 불러와서, dom로드가 멈추었다면,
이런 우회적인 방법을 통해서 논블록킹 방식으로 백그라운드에서 css를 로드하고 load가 완료되면 스타일 코드를 적용하는 식으로, 비동기를 구현 할 수 있다.
preload 방법
<link rel="preload" as="style" href="x.css" onload="this.onload=null;this.rel='stylesheet'">
preload는 웹브라우저가 미리 로딩을 시작한다.
IE에서는 지원하지 않으며 필수로 사용할 폰트등 일부 파일만 preload를 시켜놓으면 속도향상이 있다.
웹브라우저가 페이지를 읽어오면서 아직 로딩이 안되었더라도 동시에 로딩하는 h특성을 이용하여,
html 로딩중에 link태그가 보이면 로딩부터 해놓고 (나중에 어짜피 쓸것 이라고 개발자가 지정했으니)
나중에 끼워 맞춰주는 방식이다.
<link> 태그 규칙
rel="preload" // 고정
href="" // 로딩하려는 url
as="" // 파일 형식, 파일형식은 아래와 같다.
(audio / document / embed / fetch / font / image / object / script / style / track / worker / video)
crossorigin="crossorigin" // 외부에서 로딩시 필수로 넣어야 된다.
너무 남발시 초반 로딩속도가 길어지는 부작용이 생길수 있다.
3. 이미지 로딩 최적화 (Lazy Load)
웹에서 가장 큰 비중을 차지하는 데이터는 이미지다.
심지어 경우에 따라선 압축기술이 발전된 동영상보다도 더 많은 용량을 차지하는 게 이미지 다.
그래서 웹개발자들은 LazyLoad라는 깔끔한 기법을 만들었다.
보이는 곳에 있는 이미지만 로딩하고, 나머지 이미지는 나중에 로딩하자.
아래의 움짤을 보면, 스크롤을 내리자 개발자탭에 새로 로딩되는 이미지가 주르륵 뜨는 것을 볼 수 있다.
즉, 사용자가 안보는 곳(안보이는곳)엔 이미지 로드를 지연시켜놓고, 사용자가 스크롤을 내리면 그때서야 이미지를 로딩시켜 보다 초기 로딩을 향상시키는 기법이다.
티스토리 lazyload 적용방법
티스토리 스킨편집 html에서 다음 코드를 복붙 하면 된다.
원리는 매우 간단하다.
- 우선 고용량의 원래 이미지 url소스를 잠시 빼놓아 변수에 저장한다.
- 그리고 스크롤을 내리면 저장했던 변수의 이미지 url을 다시 불러들여 이미지를 로딩하는 원리이다.
<script src="https://cdnjs.cloudflare.com/ajax/libs/lazysizes/5.3.2/lazysizes.min.js"></script>
<script>
window.addEventListener('DOMContentLoaded', function (event) {
const imgs = document.querySelectorAll('img');
if (imgs.length > 0) {
imgs.forEach(function (img) {
if (img.getAttribute('srcset') != null) {
img.setAttribute('data-srcset', img.getAttribute('srcset')); // 원래 이미지를 잠시 data-변수에 저장
img.setAttribute('srcset', '대체할 저용량 이미지 경로'); // 그리고 그자리를 저용량의 이미지로 대체시킨다
}
if (img.getAttribute('src') != null) {
img.setAttribute('data-src', img.getAttribute('src'));
img.setAttribute('src', '대체할 저용량 이미지 경로');
}
img.classList.add('lazyload');
})
}
})
</script>
4. 자바스크립트 로딩 최적화
스크립트는 로딩시 html로딩을 일시중지 시킨다.
이를 비동기 적으로 실행할수 있는 두가지 방법이 있다. (defer / async)
<script defer src="https://javascript.info/article/script-async-defer/long.js?speed=1"></script>
<script async src="https://javascript.info/article/script-async-defer/long.js?speed=1"></script>
| 순서 | DOMContentLoaded |
async | load-first order. 문서 내 순서와 상관없이, 먼저 다운로드된 스크립트가 먼저 실행 |
src용량에 따라, DOMContentLoaded 이벤트 발생 전이든 이후이든 언제나 실행될 수 있습니다. |
defer | 문서에 추가된 순 | 지연 스크립트는 문서 다운로드와 파싱이 완료된 후에, DOMContentLoaded 이벤트 발생 전에 실행됩니다. |
5. DNS 미리 연결
먼저 DNS값을 가져오는 과정으로 페이지내 로딩하는 외부 리소스가 있다면 적용해 볼 수 있다.
미리 DNS를 가져와서 타 서버 초기로딩시간을 줄여주는 원리이다.
<!-- tistory<1~4>.daumcdn.net는 스킨 관련 리소스 위치이므로 스킨리소스를 images폴더에 올리지 않은경우 지워도 좋다. -->
<link rel="dns-prefetch" href="https://tistory1.daumcdn.net/" crossorigin>
<link rel="dns-prefetch" href="https://tistory2.daumcdn.net/" crossorigin>
<link rel="dns-prefetch" href="https://tistory3.daumcdn.net/" crossorigin>
<link rel="dns-prefetch" href="https://tistory4.daumcdn.net/" crossorigin>
<!-- 이미지를 업로드시 이 주소를 통해 전달받는다. 블로그 이미지를 아주 조금(0~200ms) 빠르게 받을수 있다. -->
<link rel="dns-prefetch" href="https://blog.kakaocdn.net/" crossorigin>
<!-- 카카오톡 공유하기 기능은 여기를 통해 리소스를 받는다. -->
<link rel="dns-prefetch" href="https://developers.kakao.com/" crossorigin>
이 기능으로 성능차이는 매우 적으므로(0~200ms : 0.2초 이하) 큰 기대는 할 필요없이 마지막으로 최적화를 마무리할 때 할만한 작업이라고 보면 된다. 해외 DNS서비스에 기반을 두어 DNS응답속도가 느렸다면 차이가 클 수 있다.
# 참고자료
https://yceffort.kr/2021/03/improve-css-performance
https://mjae404.github.io/2021/12/16/css-optimization/
이 글이 좋으셨다면 구독 & 좋아요
여러분의 구독과 좋아요는
저자에게 큰 힘이 됩니다.