피키팜을 개발하면서 항상 마음에 걸렸었던게,,, 진짜 개발을 1도 모르던 시절에 시작한것이다 보니 최적화 보단 우선 기능이 동작하는게 먼저였다. 그런데 막상 실 서비스에 돌입하니, 은근 페이지 로딩속도가 너무 느린것... 항상 마음속에 담아만 뒀는데 오늘 드디어 하나씩 뜯어고쳐보기 시작했다.
tailwindcss,,, 사실 html의 클래스 이름으로 스타일을 주는 프레임워크는 부트스트랩이 제일 유명하다. 근데 왜 이걸 썼느냐,,, 그때만 해도 니꼬선생님이 쓰라고 했으니 쓴거지 뭐...
하여튼 지금 받아오는 파일은 모든 경우가 다 담겨있는 파일을 받아오다 보니까 css하나가 뭔 4mb씩이나 차지하고 그랬었다. (styles.css
)
13만 라인... 대충 정신이 아득해진다.
용량때문에 렌더링에 큰 영향을 차지하는건 물론이거니와, 페이지 이동할 때 마다 4메가나 되는 파일을 다운받고 있어야 하니까 UX에서 하여튼 아주 안좋았다. 최적화가 시급했다.
tailwindcss에서 알려주는 최적화 방법
공식 문서에 따르면, tailwind.config.js
파일의 purge
항목에 원하는 파일들을 넣으면, 그 파일들을 분석하여 쓰이고 있는 스타일만 딱 최적화를 해 준다고 한다.
// tailwind.config.js
module.exports = {
purge: {
enabled: true,
content: ['./templates/**/*.html'],
},
// ... some configs
참고로 enabled
가 true
로 되어있으면 NODE_ENV
가 development
인 경우에도 최적화해준다. 디폴트는 production
시에만 최적화.
따라서 $ npx tailwind build -o output.css
를 입력하면 최적화된 파일이 output.css
라는 이름으로 나온다. 아웃풋 파일 지정 안하면 터미널에 주르륵 뜨니까 주의.
136k -> 2k로 줄었으니 단순 계산해봐도 83~4%정도 줄였다.
생각보다 꽤 줄여가지고 은근히 쾌감이 있다. 개발자 도구 열어놓고 페이지 리로딩하면서 뭐가 문제인지 더 찾아보니 생각보다 많아서,,,, 이왕 하는거 좀 더 손을 봤다.
현재 피키팜은 구글의 notosans KR을 사용하고 있다. 웹폰트 형식으로 불러오다 보니 이것 또한 네트워크 통신량에 큰 부분을 차지하는데, 폰트가 이미 css에서 @import
를 통해 불러오고 있는데 이걸 CDN으로 또 불러오고 있었던 것이다!.. 황급하게 놀라서 CDN을 지웠다. 단 1밀리초라도 아끼자.
피키팜은 정말 많은 스크립트 파일들이 있는데,,, html 파일 내에 스크립트를 임베디드로 작성하는 경우도 꽤 많았다. 왜냐? 파일 만들기 귀찮으니까... 물론 이제는 자동완성도 그렇고 최적화 문제도 있으니 스크립트를 따로 작성하는데, 스크립트를 불러오는 과정에서도 최적화가 가능하다.
html이 파싱되는 과정에 <script>
태그를 만나게 되면 파싱을 멈추고 스크립트를 다운받고 실행하게 된다. DOM이 모두 로드되려면 html이 모두 파싱되어야 하는데 중간에 스크립트의 다운과 해석을 위해 시간이 지체되는 것이다. 그래서 보통 script는 html의 body가 끝나기 직전에 두는것이 일반적이다.
그래서.. 파일들을 최대한 뒤로 옮기는 방법을 사용할 수 있다.
저 scripts block에 모든 스크립트가 들어간다.
또한 script 태그에 옵션을 줄 수 있는데, async
, defer
의 두가지가 있다.
async
: 파싱중 스크립트를 만나면 스크립트를 다운로드 하는데, 비동기로 다운을 받는다. 그래서 파싱은 계속 진행되고 다운로드가 완료되면 파싱을 멈추고 스크립트를 해석한다.defer
: async
와 같이 스크립트를 비동기로 다운받으나, 파싱이 끝난 이후에 해석이 시작된다.따라서 스크립트가 위에 있다 하더라도 파싱을 계속 이어나갈 수 있다.
수많은 defer의 행렬...
스크립트를 뒤로 땡겨서 최적화 할 수도 있지만 불러오는 파일의 갯수가 많다면 그거를 각각 불러오는 것도 엄청난 시간이 들게 된다. 그래서 보통 이런 경우에 webpack을 써서 스크립트들을 번들링하고 난독화까지 해서 정말 극도의 최적화를 이뤄내곤 한다.
그런데,,, webpack의 경우 모듈화 된 스크립트에 대해서 번들링해주지 각각 나눠져 있는 파일을 불러오는 현재의 방식은 사용이 불가능하다. JS의 모듈 시스템이란걸 모를 때 열심히 만들어왔기 때문에... 눈물나게도 웹팩은 아직 못쓰는걸로... 얼른 모듈화를 해서 극도의 최적화 쥐어짜기를 해야할 것 같다...
생각보다 꽤 최적화를 이뤄낼 수 있었다.
기존의 홈페이지의 메인페이지를 로드할 때의 성능이다. DOMConetentLoaded
이벤트까지 무려 1.01초나 소요되는 모습을 볼 수있다.
최적화 후의 성능이다. DOMContentLoaded
이벤트까지 절반 이상이 줄었다. 여러번 리로드 해봐도 보통 550밀리초를 넘지 않는다.
defer
를 통해 HTML 파싱을 최적화할 수 있다.