스킨 리뉴얼은 아니지만 이것도 리뉴얼은 리뉴얼이니까

호기롭게 만든 아이콘 사이트
로딩이 느리다.
거짓말 안 하고 67개 아이콘 불러오는데 거진 10초가 걸린다

리소스 페이지에 써둔 글인데 사실 내가 말하고도 이게 말이가 방구가.. 싶기는 했다 심지어 살짝도 아니었음 #구라_지려
솔직히 나는 뭐.. 내가 만든 사람이니까 대충 감안하고 쓴다고 쳐도 Solar icon을 메인으로 쓴 스킨을 처음으로 출시하게 되면서 다른 사람들한테는 다소 용납되지 못할 속도라는 생각이 들었다
실은 나도 용납 안 됐는데 체력이 더 거지라서 대충 즙짜면서 쓰고 있었음
아무튼 스킨 출시에 앞서 뭔가 수를 써야겠다는 생각이 들었고 기존에 생각만 하던 방법을 직접 구현했다

(구조 자체는 간단한데 svg 코드가 길어서 파일이 이 모양이다)
그 방법이 뭐냐면, svg 코드를 텍스트로 변환해서 데이터 포맷 중 하나인 JSON 파일에 넣고 그 파일에 루프(반복문)를 돌리는 방식이다.
-
① svg 코드를(HTML) 추출해서 JSON 파일에 저장
② 그 JSON 코드를 불러옴
③ 반복문으로 JSON에 저장된 코드를 한번씩 돌면서 조건에 맞게(커스텀/검색어 등) 적용해줌
④ 최종 코드를 화면에 출력함
요런 방식이다

왜냐하면 초기에는 fetch를 써서 아이콘을 하나하나 다 불러왔었다. 사실 초기에 코드를 썼을 때도 퍼포먼스 부분이 걱정되긴 했다. fetch로 파일 데이터를 불러오는 것부터 퍼포먼스에 영향을 주는데 그 안에서 루프까지 돌려버려서 아주 최적화를 개박살낸 거나 다름 없었으니까
근데 코드를 작성할 때까지만 해도 난 이 정도일 줄은 몰랐다.. 로컬에서 돌렸을 땐 되게 빨랐는데 서버에 올리니까 속도가 개같아지더라... #저는정말몰랐어요
뭐 당연 로컬이 빠르긴 하겠지만 서버와 그렇게 극명하게 차이가 날 줄 몰랐다 (ㅠㅠ)
그러고 나니까 그냥 코드를 직접 따서 그 텍스트를 HTML에 낑겨주는 게 제일 빠르겠단 생각이 들었다. 그러기 위해서는 모든 svg 코드를 파일에 저장해야 되는데 코드를 하나하나 다 따야 한다는 개큰 단점이 등장함
아이콘이 총 1,250개인데 4개의 스타일이 있으니 1,250 × 4 = 5,000개의 코드를 추출해서 저장해야 되게 생겼음
처음에는 바보같이 일일이 할까 생각을 했었지만?
(이렇게라도 최적화를 하는 게 도리... 뭐 그런 거라고 생각을 했었다...)

코드로 추출하는 게 정신병에도, 내 척추에도, 내 체력에도 좋겠단 생각을 해서 당장 콘솔 열었다. 사람은 머리를 써야 한다더라
linear, duotone, bold, bulk 이렇게 4종류가 있으니까 카테고리마다 루프 4번씩만 돌리면 객체로 svg 코드를 뱉어내게끔 코드를 짜면 됐고 그게 위의 사진과 같다. (innerHTML은 나중에 outerHTML로 바꿔줬음)
그걸 처음에는 그냥 자바스크립트 파일에 저장해서 import / export 해줄까, 아님 위에 말했던 것처럼 JSON을 이용할까 고민을 굉장히 많이 했다.
1) import / export의 장점
말 그대로 코드를 다른 파일에서도 사용할 수 있게 외부로 쏴주는 작업이다. export로 코드를 내보내고 다른 파일에서 import로 해당 파일이 있는 상대경로를 지정해주면 내가 쏴준 코드를 사용할 수 있게 된다. 따라서 비동기 방식인 fetch를 안 써도 된다는 장점이 있고 속도가 빠르다.
2) import / export의 단점

코드 이 꼬라지 됨.
파일을 나누지 말고 한 파일에 넣는다 쳐도 이게.. svg 특성상 코드가 무식하게 길기 때문에 파일 하나에 넣어버리면 파일 용량이 커지니까 오히려 역효과가 난다. 그리고 내 코드 에디터도 제발 파일 좀 나누라고 소리 지를 듯..

실제로 리뉴얼에 쓰인 파일인데, JSON은 코드가 너무 길다며 퍼포먼스 이슈로 포맷조차 안 해줬다. 병크 오짐
근데 이 꼬라지로 길이가 진심.... 캡쳐해서 첨부하기 정말 미안할 정도로 졸라 길게 있다. 고작 파일 하난데... 이렇게 생각해보니 포맷 안할만도 함
3) JSON 장점
동적으로 파일을 불러오는 게 가능하고 또 간편하다
const res = await fetch(`/${BASE_URL}/data/${category}.json`);
이런 식으로 파라미터(=URL 주소 끝에 붙는 또다른 주소 ─ https://google.com/test일 때 test 부분)랑 해당 아이콘 코드가 담겨 있는 파일명을 일치시켜주면 난 주소가 바뀔 때를 추적하고 파라미터만 따서 인수로 넣어주면 코드가 알아서 파일 내용을 가져와준다.
4) JSON 단점
그러기 위해서는 일단 fetch를 사용해야 돼서 속도 면에서 단점이 되기도 하고 JSON 자체도 그리 빠른 포맷은 아니라고 하더라. 그치만 제 사이트는 아이콘 5천개만 불러오면 되는 개허접 소규모 사이튼데용?
이 정도 단점은 나한테는 큰 걸림돌이 아녔다
근데 아까 분명 fetch로 아이콘을 불러와서 로딩 속도가 개쓰레기 됐다고 했으면서 또 fetch를 쓴다고? 라고 생각할 수 있지만 사실은 굉장히 다른 게 뭐냐면 만약 한 카테고리에 아이콘이 50개가 있다면 초기 버전에서는 fetch를 50번을 써야 했었다. 아이콘을 일일이 fetch로 불러왔기 때문. 그리고 거기다가 루프를 돌렸다고 말했는데 그것도 심지어 이중으로 중첩돼 있는 루프였다. 50개를 한번씩 반복하는데 그 안에 있는 각각의 요소에도 루프를 또 돌려준다는 의미다. #루프지옥
JSON의 경우가 다른 이유는 뭐냐면 난 이미 텍스트 형태로 아이콘의 HTML 코드를 JSON 파일 하나에 (카테고리별로) 다 넣어놨기 때문에 한 카테고리에 필요한 정보는 한 곳에 다 담겨져 있고 그래서 fetch는 단 한번만 실행하면 된다. JSON 파일로 불러온 코드에도 루프를 돌리긴 하지만 용량이 작고 작업이 간단하기에 큰 영향을 주지 않는다.
그래서 JSON 포맷으로 결정했다

그 뒤부터는 수월했어요
아니 마냥 수월하진 않았는데 그건 그냥 내가 머리를 써도 반밖에 안 써서 벌어진 일이기에... 감내하면서 코드 짜고 구조 잡고 그랬다

코드를 대폭 수정해줘야 할 줄 알고 엄청난 김장감 상태였는데 생각보다 고쳐야 할 게 많이 없어서 시상식에서 호명된 지현우 됐다. 이 블로그에서만 지현우 두번 됐음
아무튼 로딩은 이제 1초도 안 걸린다 ^^
저는 이제부터 이걸 인간승리라고 부를랍니다

그래서 눈물을 머금고 없앴던 All 카테고리도 다시 살려서 넣었다
이 카테고리는 로딩이 좀 긴 편이긴 하다 근데 1,250개를 불러오는 거라서 그러려니 함
실전에서도 아이콘 불러오는 시간을 단축시키고 싶은 마음에 실제로 모든 아이콘 텍스트를 다 한 파일에 넣어봤는데 용량도 크고 거의 14,000줄이 나와서 때려쳤다. 이게 최선인듯함
