Cache (캐시)

productuidev·2022년 8월 17일
4

IT/CS 지식 쌓기

목록 보기
19/24
post-thumbnail

Cache (캐시)

Intro

🤔 에피소드 1

이미 라이브된 웹 사이트에서 사용자가, 특정한 경우에 자바스크립트 에러가 난다는 것을 리포팅했다. 팀장이 그 이야기를 듣고 당장 고쳐놓으라고 주문한다. 급하게 JavaScript 파일인 .js 파일을 열어서 수정한 다음 서버에 업로드를 마쳤다. 그리고 팀장에게 '수정 완료했습니다'라고 보고를 한다. 그런데 왠일인지 팀장이 확인해보더니 '아직 그대론데?'라고 한다. 살펴보니 아까 그 페이지를 보았을 때 사용된 .js 파일은 팀장의 웹 브라우저가 웹 캐시에 저장해되어 있고, 그 캐시를 그대로 사용하여 페이지를 불렀기 때문에 갱신이 안된 것이다.
'Ctrl+F5 (새로고침) 을 눌러서 캐시를 무시하고 리로드 해보세요' 그렇게 하더니 팀장은 '어.. 이제 되네. 수고했어'라고 한다. 그런데 그렇게 만만한 팀장은 아니다. '근데 말이야, 다른 사용자들도 Ctrl+F5 안 누르면 나처럼 다 에러나는 거 아냐?' 맞는 말이다.
그래서 개발자는 이야기한다. '시간이 좀 지나서 서서히 갱신될 겁니다.. IE가 다 그렇죠 뭐~' 하지만 역시 만만한 팀장은 아니다. '무슨 소리를 하는거야, 무슨 수를 써서든 사용자들이 갱신된 .js 파일을 적용받도록 해!'

이런 일, 웹 개발자들이 한번씩 경험하는 일이라고 생각하는데..
이 때 어떻게 해결하는 것이 가장 현명할까?

출처 - (2007년) JS/CSS 파일 인터넷 캐쉬 문제 관리하기

🤔 에피소드 2

제목 : CSS를 담당하는 사람인데.. 정말 이해가 안대서요..
작성자 : 🦰 임OOO
내용 : CSS를 작업을 하는 사람인데요. CSS 작업 때문에 이미지를 덮어씌워도 반영이 느리게 되는게 CSS때문에 그런건지요??? 이미지를 덮어씌우고 핸드폰으로 확인하면 바로 반영되는데 PC에서 확인하면 새로고침을 엄청 눌러야 보입니다.

제목 : 캐시 문제
작성자 : 🦰 홍O
내용 : 프론트엔드 문제로 클라이언트와 프리 개발자 사이에 껴서 커뮤니케이션 하고 있는데.. 클라는 반영이 안된 거 같다 그러고 프리는 반영이 됐다 그러고... 개발소스를 못보니 답답하네요 ㅠㅠ 빨리 잘 해결이 돼서 마무리 됐으면 좋겠어요...

출처 - 하드코딩을 하는 사람들 (퍼블리셔 카페)

🦱 댓글(웹OO) : 캐시 삭제를 해보시면 되요~!
🦱 댓글(코OOO) : 매번 노래를 부르고 다닙니다. 캐시~ 캐시~
🦱 댓글(뜅OO) : 파일의 원활한 갱신?을 위해 서버 올릴 때 변수 처리된 값이 붙어요. 주소창에 ? 같이 물음표로 올라가는 건 변수 선언이에요. 대부분 올린 날짜 시간 같은걸로 자동으로 만들어지고요. 기존 style.css 올리시면 새로운 변수로 선언돼서 연결될 거에요!
🦱 댓글(엘O) : was는 안써봤지만 배포 문제이지 않나 싶네요. 특정서버에다 올리라고 하면 알아서 배포되는 환경일거 같긴한데 개발환경은 10개의 회사면 5개는 달라서, 출근하셔서 물어보시는게 빠를거 같습니다.
🦱 댓글(COOOOOOO) : 기존에 css, js 파일이 남아 있는 것 같습니다. 캐시 안지우고 연결하려면... css, js 불러오는 코드에 src="script.js?v=1.0"과 같이 파라미터를 붙여서 연결해 보세요... 그러면 파라미터 비전에 따라 css, js 파일을 다시 불러와 적용시킬겁니다.
🦱 댓글(이ㅇㅇ) : 개발자가 소스에 캐쉬나 쿠키 관련 줄 넣어주는게 정답일듯
🦱 댓글(시OOOO) : 보통 ?뒤에 타임스탬프 값같은 걸 넣어줘서.. 자동 갱신되게 '-')a
🦱 댓글(멀OO) : 주소 뒤의 쿼리스트링이 매번 바뀌어야 다른 것으로 인식을 하게 되는데 매번 페이지마다 바꿔줄 순 없잖아요 ;;;; 개발단에서 쿼리스트링 값을 변경시켜 적용되도록 처리해 주어야 합니다.

🤔 에피소드 3

제목 : 브라우저 캐시
작성자 : 🦰 JOOOOO
내용 : 하이브리드로 브라우저를 사용하다보니 브라우저 캐시가 남는데 이것 때문에 수정된 코드가 적용 안될 때가 있자나요. 그때는 어떻게 처리하시나요? 청크 코드 사용해서 네임을 바꿨는데도 리플레시가 안되는거 같아서요

🦱 댓글(hOOOOO) : Parcel이나 Webpack 같이 파일명 뒤에 해시를 붙여줘서 코드가 변경되면 파일명이 바뀌게 해서 어느정도 캐시랑 무관하게 돌아가게끔 하면서 AWS CloudFront 같은 곳에서 캐시 무효화 가끔씩 쓰고 있어용
🦰 대댓글(JOOOOO) : filename: isEnvProduction ? 'static/js[name].[contenthash:8].js' : 'isEnvDevelopment && 'static/js/bundle.js' 이 부분 말씀하시는 건가요?
🦱 대댓글(hOOOOO) : 네네 웹팩이면 그렇게 처리 가능하겠네요

🤔 에피소드 4

제목 : 캐시
작성자 : 🦰 sOOOOO
내용 : 예를 들어서 사이트에 최초 접속 시 js 파일을 14일간 저장해라고 설정했습니다. 이후 접속자가 접속을 할 때마다 그 시점으로부터 14일이 새롭게 갱신되는건가요? 아니면 최초 접속한 시점을 기준으로 14일이 지나면 캐시가 삭제되고 그이후 접속할 때 다시 캐시가 생성되나요?

🦱 댓글(현OOO) : 최초 접속일 겁니다. date값을 가지고 있으니

에피소드 5

웹사이트를 운영하다보면 JSP 단에서 css 또는 js 파일을 수정하는 일이 종종 있는데, 파일을 수정 후 새로 배포를 해도 브라우저에서 js/css파일을 캐시로 저장하기 때문에 수정한 파일이 아닌 브라우저에 먼저 저장되어있는 js/css파일을 사용하기 때문에 수정한 부분이 작동하지 않거나 화면이 깨져 보일 수 있다.
브라우저 캐쉬의 동작은 URL을 기준으로 기존에 동일한 URL에 요청한 적이 있었는지를 판단하게 된다. Ctrl + F5키를 눌러서 해당 페이지의 캐시를 삭제하면서 새로고침해서 수정한 js/css파일을 새로 가져올 수 있으나 사이트를 이용하는 모든 유저들에게 "저희가 이번에 js/css파일을 수정했으니 Ctrl + F5키를 눌러서 캐시삭제 후 사이트를 이용해주세요"라고 할 순 없으니...

출처 - [Front] js/css 파일 캐시 방지 처리

캐시란?

웹 캐쉬란 client가 요청하는 html, image, js, css등에 대해 첫 요청 시에 파일을 내려받아 특정 위치에 복사본을 저장(USING SPACE)하고, 이후 동일한 URL의 Resource요청은 다시 내려 받지 않고 내부에 저장한 파일을 사용하여 더 빠르게 서비스(SAVE TIME)하기 위한 것입니다. 서버를 통해 내려 받는 양이 적어지니 응답 시간이 감소하고 네트워크 트레픽이 감소되니 server와 client 모두가 win-win할 수 있는 최고의 tradeoff 인 셈입니다.

출처 - 더 빠른 웹을 위하여 - 웹 캐시

Static Asset을 캐싱한다

대표적 정적 자산
1. 이미지 - 로고, 사진, 백그라운드 등
2. HTML
3. CSS
4. JavaScript

출처 - HTTP 웹 기본 지식 캐시 기본 동작

서버에 자원 요청하기

  1. 브라우저가 요청을 한다.
  2. 정적 파일(html, css, js)을 요청하는 경우 웹서버에서 바로 응답한다.
    2-1. 동적 파일(jsp 또는 ejs)의 경우 웹 서버가 웹 어플리케이션 서버(이하 was)에 요청을 넘기고 was는 데이터베이스 서버를 요청하여 그 결과로 html을 만들어 웹 서버에 넘긴다. 웹 서버는 브라우저로 응답한다.
  3. 브라우저는 받은 html을 위에서 아래로 차례대로 파싱한다. 파싱하면서 css나 js를 만나면 웹 서버에 요청하여 응답을 받는다.

    그림을 통해 웹 사이트 접속시 어떤 일이 일어나는지 알게 되었다. 우리가 매번 주소창을 입력하거나 링크를 누르면 그림의 과정이 반복된다. 그런데 생각해보면 참 비효율적이지 않은가? 동적 파일은 말 그대로 데이터베이스의 상태와 조회에 따라 결과가 달라지지만 정적 자원은 달라질 일이 거의 없다. 새로운 기능이 추가되거나 디자인이 변경되지 않은 이상 우리는 항상 동일한 css와 js 파일을 매 요청마다 응답받는다. 이는 매우 비효율적이다. 그래서 똑똑한 브라우저는 응답 받은 정적 파일을 캐시라는 임시 공간에 넣는다. 그리고 같은 정적 자원을 요청하는 경우 웹 서버에 요청하지 않고 브라우저내 캐시에서 가져온다.

    첫 요청

    다음요청

    현대의 브라우저는 정말로 똑똑하다. 캐시 기능 이외에 자원을 아껴주는 많은 기능이 존재한다고 한다. 이에 대해서는 추후에 포스팅을 적어보겠다. 어째든 브라우저 덕분에 불필요한 요청이 줄어들어 서비스 제공자 입장에서는 비용에서 이득을 보았다고 볼 수 있겠다!

    그런데 말입니다..

    우리의 홈페이지의 css가 변경되었다고 가정해보자! 그리고 이것을 실서버에 반영한다. 이러면 무슨 일이 일어날까?

    캐시문제

    우리가 css를 변경하긴 했지만 이름은 그대로 index.css이기 때문에 기존 캐시에 있는 파일을 계속 요청하여 변화가 없는 것이다!

    이쯤되면 왜 정적 파일 뒤에 숫자가 붙는지 알 수 있을 듯하다. 동일한 이름을 그대로 요청하는 경우 캐시에 있는 파일을 그대로 사용한다. 그래서 변경사항이 있는 정적 파일을 배포하려면 기존 파일 이름과 다른 이름으로 배포해야한다. 흔히 뒤에 버전 이름을 명시하거나 해시 값을 추가한다.

    출처 - [실제 문제 고민하기] 정적 파일(css, js)에 붙은 숫자는 뭐지?

해결방법 References

1) 캐시 사용 금지

웹페이지의 헤더에 내용을 추가해서 캐시를 사용하지 않도록 설정할 수 있다.
html 문서의 와 사이에 다음 내용을 추가한다.

<meta http-equiv="Pragma" content="no-cache"> <!-- ← HTTP 1.0에서 사용하던 방법 -->
<meta http-equiv="Cache-Control" content="no-cache">
<meta http-equiv="Expires" content="0"/>

위의 방법은 모든 캐시를 사용하지 않기 때문에 페이지를 로드할 때마다 새로 파일을 불러오기 때문에 사용자에게 바로 적용이 된다는 장점은 있지만, 반대로 파일의 변경이 없을 때에도 무조건 계속 새로 불러오기 때문에 속도에서도 손해를 볼 뿐만 아니라 트래픽을 쓸데없이 낭비하게 된다는 단점이 있다.

<!-- 다음 코드를 헤더에 삽입한다.-->
	
 <!-- 
 Cache-Control
 no-cache : 캐시를 사용하기 전에 재검증을 위한 요청을 강제함.
 no-store : 클라이언트의 요청, 서버의 응답 등을 일체 저장하지 않음
 must-revalidate : 캐시를 사용하기 전에 반드시 만료된 것인지 검증을 함.
 Ex) Cache-Control: no-cache, no-store, must-revalidate
 -->
 <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">

 <!-- 
 Expires
 리소스가 validate 하지 않다고 판단할 시간을 설정함
 유효하지 않은 날짜 포맷(0)과 같은 경우 리소스가 만료 되었음을 의미함.
 Ex) Expires: Wed, 21 Oct 2015 07:28:00 GMT
 -->
 <meta http-equiv="Expires" content="0">

 <!-- 
 HTTP 1.0 버전에서 HTTP 1.1의 Cache-Control 헤더와 같은 역할을 함
 Ex) Pragma: no-cache
 -->
 <meta http-equiv="Pragma" content="no-cache">
<META HTTP-EQUIV="Pragma" CONTENT="no-cache"> <!-- no-cache는 캐싱을 방지하는 메타태그 -->
<META HTTP-EQUIV="Expires" CONTENT="-1"> <!-- 캐시된 페이지를 즉시 만료시킨다. -->

참고자료

웹서비스 캐시 똑똑하게 다루기

HTTP 캐시를 효율적으로 관리하기 위해 다양한 생명 주기를 가지는 캐시를 다루면서
Cache-Control 헤더를 섬세하게 조절하는 노하우 공유

웹 성능 개선을 위한 웹캐시 설정
서버와 브라우저는 HTTP 요청, 응답을 주고받는데 이때 응답에 포함된 cache-control header에 따라 resource의 생명 주기가 결정된다.

2) 파일 로드 방법의 변경

파일이 변경될 때마다 파일 이름을 바꾸어서 브라우저가 새로 파일을 불러오게 하는 방식이다. 이렇게 하면 파일이 변경되었을 때에만 다시 불러오게 되므로 훨씬 효율적이다. 다만 실제로 파일의 이름을 바꾸는 것은 아니고, 파일의 url 뒤에 사용하지 않는 파라미터를 덧붙여 브라우저가 다른 파일명으로 인식하게 하는 것이다. 가장 깔끔하고 효율적인 방법이다. 예를 들면 a.js라는 파일을 불러올 때 원래는 이렇게 불러오게 되는데, 그 대신 이런 식으로 불러오는 것이다.

echo '<script src="a.js?'.filemtime('a.js').'"></script>';

// html출력
<script src="a.js?1487009730"></script>
<!--
 실제 파일 변경이 이루어졌을 때, 버전을 명시해주면 캐시를 사용하지 않고 새롭게 로드
 다만 JSP 같은 경우 스크립트릿을 삽입하여 자동화 할 수 있는데 
 순수 HTML 문서에서는 수동으로 고쳐줘야할 듯 하다.
 -->
 <script type="text/javascript" src="./jquery-3.3.1.min.js?ver=1.0"></script>

3) 캐싱된 유저 CSS 파일 강제 재 로딩(캐시 방지 처리)

첫 번째로 C태그를 이용해 오늘 날짜를 자동으로 붙이는 것이다. 단순히 오늘 날짜가 들어가는 것보다 마지막으로 수정한 날짜와 시간인 timestamp가 들어간다면 더 확실할 것이다.

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"  %>
<jsp:useBean id="today" class="java.util.Date" />
<fmt:formatDate value="${today}" pattern="yyyyMMdd" var="today"/>
<link rel="stylesheet" type="text/css" href="<c:url value="/resources/css/common.css"><c:param name="dt" value="${today}"/></c:url>"/>

단순히 오늘 날짜가 들어가는 것보다 마지막으로 수정한 날짜와 시간인 timestamp가 들어간다면 더 확실할 것이다.

<script type="text/javascript"
/* 소스 업데이트 */
    function getFetchVersion(file) {
        try {
            fetch(file).then(r => {
                let lastModGmt = new Date(r.headers.get('Last-Modified'));
                let lastModUtc = new Date(lastModGmt.getTime() + (lastModGmt.getTimezoneOffset() * 60000));
                return fetchCallback(file + '?' + lastModUtc.toLocaleString());
            });
        } catch (er) {
            return er.message;
        }
    }

    function fetchCallback(path) {
        let link = document.createElement("link");
        link.type = "text/css";
        link.rel = "stylesheet";
        link.href = path;
        document.getElementsByTagName("head")[0].appendChild(link);
    }

    getFetchVersion('/resources/css/common.css');
</script>

4) 숫자를 붙이는 방법

간단한 서비스의 경우 개발자가 명시적으로 버전을 하나씩 올려주면 되겠지만 실제 상용 서비스는 정적 파일이 무진장 많기 때문에 개발자가 일일이 버전을 명시하는게 불가능하다. 내가 알고 있는 몇가지 방법에 대해서 소개한다.

  1. 정적 파일을 관리하는 서버 사이드 변수 지정
    배포할때마다 버전 값을 하나씩 수동으로 늘려주는 방법이다. 비효율적인 방법이지만 내가 다니고 있는 회사는 이렇게 관리를 하고 있는 듯하다.
  2. 서버 사이드에서 현재 날짜를 문자열로 변환하여 정적파일 뒤에 붙이기
    1번과 동일한 듯 다른 방법이다. 현재 날짜를 조회하여 초로 변환하여 정적 파일 뒤에 붙여준다. 이 방법은 캐시를 사용하지 않는 것과 동일한 효과를 가진다. 이렇게 하면 캐시의 장점을 누리지 못해 비효율적이지만 배포를 할때는 걱정이 없을 듯하다.
  3. 현대적인 도구를 사용하자.
    내가 알고 있는 도구는 webpack이 있다. 아래 글을 한번 읽어보면 이해가 빠를 듯 하다.
    일정 수준의 코드를 변경하고 빌드하면 자동으로 파일 이름 뒤에 해쉬가 붙는다!

5) JSP/JSTL에서 캐시처리

브라우저 캐쉬의 동작은 URL을 기준으로 기존에 동일한 URL에 요청한 적이 있었는지를 판단하게 된다.

<jsp:useBean id="today" class="java.util.Date" />
<fmt:formatDate value="${today}" pattern="yyyyMMddHHmmss" var="nowDate"/>
 
<script type="text/javascript" src="/kor/css/test.css?ver=${nowDate}"></script>
<script type="text/javascript" src="/kor/js/test.js?ver=${nowDate}"></script>
[출처] [Front] js/css 파일 캐시 방지 처리|작성자 헬리코

만약 jstl을 사용한다면

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<jsp:useBean id="now" class="java.util.Date" />
<fmt:formateDate value="${now}" pattern="yyyyMMddHHmmss" var="nowss"/>

<script type="text/javascript" src="temp.js?ver=${nowss}">
<link rel="stylesheet" type="text/css" href="temp.css?ver=${nowss}">

JSP에서 CSS, JS 파일을 작성하고 서버에 업로드 후 작성한 JSP 페이지를 확인할 때 CSS, JS 파일이 캐시로 인해 적용이 바로 안될 때가 있는데 이를 방지하는 방법을 알아보도록 하겠습니다. 강력한 새로고침 [CTRL]+[SHIFT]+[R] 하는 방법도 있지만. 제가 알려드릴 방법은 CSS, JS 파일이 서버에 업로드된 시간을 가져와 실시간으로 캐시를 방지할 수 있는 방법입니다.

<%@ page import="java.io.*, java.util.*" %>
 
<%
	/* CSS/JS 파일 캐시 방지 */
	String styleCss = application.getRealPath("/css/style.css");
	File style = new File(styleCss);
	Date lastModifiedStyle = new Date(style.lastModified()); 
 
	SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMddhhmmssSSS");
%>
 
<link rel="stylesheet" type="text/css" href="tyle.css?ver=<%=fmt.format(lastModifiedStyle)%>" />

적용 결과

<link rel="stylesheet" type="text/css" href="/css/style.css?ver=20180427122255000" />

6) 이미지 캐시 방지

파일의 내용을 수정해도 반영이 안되어 있을 경우를 가끔 보실 수 있습니다. 심지어 수정본을 배포하고 나서도 어떤 사용자가 이전에 사이트에 접속하고 나서 인터넷 사용 기록 및 캐시 지우기를 하지 않은 이상 배포 이전의 css, js, image 파일들이 그대로 사용되고 있어서 오류가 나거나 버그가 생기는 케이스가 생기곤 합니다. 이런 문제가 발생할 때마다 사용자보고 오래된 캐시(stale cache) 좀 지워주세요 라고 한다거나 새로고침 좀 해주세요 라고 한다거나 시크릿 브라우저로 한번 해보시겠어요 라고 하는 건 정말 어려운 일이겠죠. 기본적으로 캐쉬의 동작은 URL을 기준으로 기존에 동일한URL에 요청한 적이 있었는 지를 판단합니다. 그렇기 때문에 당연히 URL이 변경되면 기존의 캐시의 영향을 받지 않게 됩니다. 그래서 이런 문제가 생기는 것을 방지하기 위해서 개발자가 수정한 파일의 URL 뒤에 ?version=1.7 와 같은 파일의 버전 정보가 담긴 query string을 붙여서 적어주는 것입니다. 그러면 브라우저가 해당 파일을 새로운 파일로 인식하고 캐시에서 가져오는 것이 아니라 새로운 파일을 다운 받도록 동작합니다.

<img src="./image/domdomdi.jpg?t=1324" />

// javascript
var rand = Math.floor((Math.random() * 10000));
document.write('<img src="./images/domdomi.jpg?"'+rand+'" />');

// flask jinja2 template engine
<img src="./images/domdomi.png?t={{ range(1111, 9999)|random }}" />

출처 및 관련 자료

생각해볼 점

운영 시

1) 수정한 파일의 이름 변경
개발자가 새 배포때마다 변경 파일명으로 바꿔줘야 함

2) 수정한 파일에 쿼리스트링 붙이기
개발자가 최초 지정해주면 용이하나 CI/CD가 안될 경우 개발자가 버전 변경을 퍼블리셔에게 말해줘야 함

3) 캐시 삭제 : 내부 관계자면 배포했다는 걸 인지하니까 삭제하면되는데 재방문해서 브라우저에 이전 캐시가 남아있던 사용자라면? (저희가 배포했으니 캐시 삭제하고 봐주세요 라고 할 수도 없고..)

4) 웹뷰, 인앱브라우저
디바이스/OS 사용자마다 다른 브라우저 환경 (마지막으로 열었던 브라우저)

5) 정적 자산을 통한 성능 최적화를 고려하지 않는 건 아니지만..

성능 최적화

"브라우저 호환 문제만 아니면 대대적인 이미지 포맷 전환 공사가 필요하겠네요. WebP도 2020년 몇월?부터 사파리 지원한다고 공식 발표를 하긴 했지만 jpeg2000도 WebP도 IE 지원은 안합니다. IE 고려하지 않고 몇가지 미지원 속성 이슈만 고려될 필요없는 수준이라면 사용해도 나쁠 것 같진 않지만, 신규라면 fallback을 사용해도 서비스중인 사이트라면 서비스 전에 테스트하는게 만만치 않을겁니다. 사진 이미지는 jpg가 고품질이면서 저용량이고, 투명 백이 필요한 경우는 png, 고해상도 모바일에서도 깨끗하게 보여야 하는 심볼, 아이콘 등의 이미지는 벡터인 svg를 최대한 활용하면서 퀄리티가 너무 떨어지지 않는 수준에서의 압축을 해 최적화를 진행하는 수 밖에 없어요. 최적화 작업을 해 봤는데 Sprite 이미지랑 작은 이미지 아무리 손 대봤자 사이즈 큰 고품질 jpg와 png 많으면 결국 이 이미지 불러 오느라 네트워크 속도 측정에서 시간 다 잡아 먹더라구요. 일단 사용자는 눈에 보이는게 빠르면 빠르다고 착각하기 때문에 흰색으로 텅 비어 있다거나 움직이는 화면인데 버벅거리고 멈춰 있거나 계속 로딩중인걸로 보여주면 안되므로 비주얼 요소를 빨리 보여주는게 정말 중요한 거 같긴 해요"

"현대는 pre-processor, post-processor, 개발 환경이 잘 되어 있기 때문에 개발자끼리의 커뮤니케이션만 고려하고 최적화는 도구에 맡기면 되는 상황이라 (NHN 코딩) 컨벤션은 현대와는 그다지 맞지 않는다고 봐야 합니다. (CSS pre-processor가 탄생 전, 최적화를 손으로 해야 하는 때에 만들어진 컨벤션, 코드 최적화면서도 개발자 간의 커뮤니케이션 만족을 위한 규칙)"
(pre-processor를 사용할 수 없는 환경이라면..?)

출처 - 하드코딩을 하는 사람들

6) 내가 희망하는 작업방식

  • sass/scss로 파일 분리해 작업 후 1개의 css 파일로 빌드/컴파일한 후 minify 파일로
  • 개발자가 해당 최종 css 파일에 대해 쿼리스트링을 통해 버전 관리하여 캐시 삭제 하지 않아도 바로 확인 가능
  • node 런타임 환경 webpack : bundle.js > css/js 번들링
  • Image Sprites
  • 파일 갯수 줄이기?
  • 개발자가 배포 요청한 시점에 정적 resources를 직접 퍼블리셔가 웹서버에 업로드 후 purge/flush 처리하여 운영 반영 가능
  • 젠킨스로 커밋만 해도 바로 배포되게 자동화 (퍼블리셔까지)
  • 테스팅 툴로 배포 전 개선/수정 구간 체크 (도입 대비 효과, 비용 문제..)

(미래에 어느 곳에서...)

퍼지(Purge)는 이미 캐싱된 변경 전 파일을 캐시 서버에서 제거하는 기능입니다. CDN 원본 서버의 파일이 변경됐을 때, 캐시 서버에 캐싱된 파일이 남아있다면 원본 서버의 파일 변경사항이 캐시 서버에는 반영이 되지 않습니다. 퍼지는 캐시 서버의 콘텐츠를 제거하여 원본 서버의 최신화된 콘텐츠로 갱신되도록 합니다. 퍼지 요청 후, 모든 캐시 서버에 퍼지가 적용되기까지는 다소 시간이 소요될 수 있습니다.

현실적인 작업 환경과 조건 고려하기

  • 주 브라우저(PC? 모바일? 인앱?)
  • 이용자 수에 따른 서버 자원 관리 (이용자 수가 많은가? 적은가?)
  • 타겟 디바이스/OS (내국향/글로벌향)
  • B2C? B2B? B2B2C?
  • 서비스 성장단계는 어디쯤인가
  • 납기 준수 ↔ 퀄리티(성능최적화)
  • 프론트엔드 코드 유통기한 : 1년 미만 (빠른 변화, 잘 만들어도 리뉴얼 or 개편 고려)
    ㄴ 프론트엔드 코드의 가치 = 서비스의 가치
  • 회사별로 다른 서비스 운영, 개발 환경, 권한, 배포 정책 => 이터레이션이 용이한 환경인가?
  • 작업자 성향, 작업자 간의 hand-off 방식 (관리 포인트)
  • 휴먼 에러 줄이기 : 효율성+정확성
  • 업종 이해 (금융권 - 법 - 보수적인 배포 시스템/프로세스)
  • node.js 사용불가..

개발자에게 할 수 있는 부탁

  • 위에 해결방법 References를 시도 요청하기 (웹뷰/인앱브라우저..) —-> 쿼리스트링 정도
  • Header에 만료 기한 넣기 (HTTP)
  • HTTP request 최소화
  • 1개 파일에 import 대신 link나 script 태그를 이용해 각각 직접 호출 (파일 버전 관리가 많아지는 단점...)
  • CSS/JS 위치 (HTML과 JSP(ib20 framewokr에서 위치 상이)
  • 캐시 기간 길게 설정 (캐시 기간이 길수록 동일한 파일 재요청하는 것 방지 가능, 페이지 로드속도 도움)

결론적으로 서비스 개발에 대한 책임은 (서버) 개발자에게 있고, 협업과 전체 프로세스를 고려하면 납기가 있기 때문에 간단한 1줄이어도 반영하거나 개선하기 까지 어려움이 있다.

프론트엔드/백엔드가 분리되지 않다 하더라도 방대한 영역을 다루는 개발자 입장에서는 퍼블리싱 파일에 대한 정적 리소스에 대한 개발은 전체 개발 범위에서 낮은 비중이고 이보다 사실 고려할 게 많겠지만 반대로 퍼블리셔 입장에서는 여러 직군의 요구사항에 맞춰서 작업해야 하기 때문에 비중이 크다. (또한 프론트엔드/백엔드가 분리된 회사라 해도 배포 시스템이나 개발 환경, 서비스도 회사마다 천차만별..)

다만 현재 어쨌든 환경이 이전 다녔던 금융권 회사들과 대부분 비슷하기도 하고, 이전 회사(NICE)에서 공유 문서를 볼 수 있는 시스템이 있었는데, 거기에 과거 오래 일했던 퍼블리셔 분들이 겼었던 시행착오나 과정(주로 퍼블리셔 - 개발자 간의 파일 관리, 싱크 문제..)이 직장이 바뀌었지만 매우 흡사하다.. sftp 업로드, 이클립스, diff툴 등등(그 회사에서 일했던 경험이 현재 협업이나 대응하는 데 도움이 된다) 그래서 포인트를 찾아 최대한 운영하기 용이한 방식을 고려중인데 작업 방식이 바뀌는 부분은 사실 대부분의 개발자들이 좋아하지 않으나 껍데기 화면을 만드는 퍼블리셔로선(JSP에 갖다 입히는 개념을 기준으로 말하면 view는 별도이니 껍데기..) 개발에서 해줘야 하는 상황들이 많은데… 그런데 또 이런 차이도 있다.

  • 각 서비스별 1~2명의 개발자(보통 1명) 지정 : 히스토리를 모두 알고 있다 (내가 대부분 경험했던 방식.. 난 작은 서비스를 동시에 여러개로 운영한 적이 있다. 그런데 그 작은 서비스들이 다 합쳐지면 코어나 메인 서비스보다 매출 규모가 더 컸다.. 물론 시스템은 대부분 코어를 따라가야 하나..)
  • 1서비스에 대한 다수의 개발자 : 개발자 간의 싱크가 다르거나 히스토리를 모두 공유한 상태가 아니라면...?
  • 정적 리소스에 대한 배포 권한이 있다/없다
  • 정적 리소스는 웹서버에 있다/아니다
  • 내부망에서 퍼블리싱/인터넷망에서 퍼블리싱 (형상관리 차이)
  • 서비스 검수 및 테스트에 대한 책임 (보통은 기획자(서비스운영자)/개발자)

잡스런 고민을 하다 폭풍서칭...
(하코사 서칭하면서 느끼는게 예전처럼 수작업하지 않고 퍼블리싱 하는게 현재는 일반적이니 어느 망에서 작업하든.. node가 안되는게 제일 문제다.. 나머지는 요청해서 해결할 수 있는 문제지만)

profile
필요한 내용을 공부하고 저장합니다.

0개의 댓글