제가 여러분이 생각하시는 것보다 상당히 많은 레이아웃 및 게시판 스킨을 다뤄봤습니다.

 

그런데 이러한 스킨들을 보다보면 성능이 이상하게 느린 레이아웃이 있는 반면에 성능이 괜찮은 레이아웃이 있기 마련입니다.

 

스킨이 HTML 으로 갖춰져 있어서 아무런 생각없이 HTML으로 돌겠지라는 가볍게 생각하시는데, 거기에서 PHP함수라던지 쿼리 하는 경우 적지않게 많이 봅니다.

 

그래서 성능이 안좋아 질 수 있는 요인들중 한가지를 집어서 말씀해보려고 합니다.

 

보면 이런 형태로 스킨을 작성하시는 분들이 있습니다. (이는 하나의 예시일뿐이며 그냥 참고용으로 봐주세요)

 

1번 예시

{@

$args = new stdClass;

$args->module_srl = $module_srl;

$output = executeQuery('document.getDocumentList', $args);

}

위와 같이 직접 쿼리하는 경우가 많습니다.

 

그런데 이렇게 만드는 경우도 있습니다.

 

2번예시

{@

$args = new stdClass;

$args->module_srl = $module_srl;

$args->page = 1;

$output = executeQuery('document.getDocumentList', $args);

}

 

앞으로는 이렇게 하지말아주세요.

 

우선 이 방법이 나쁜이유는 다음과 같습니다. 

 

스킨이라는 것은 HTML문서가 아니라 작성한 HTML 과 템플릿의 문법을 PHP으로 변환하는 과정을 거칩니다.

 

(자세한 정보는 이전 게시글 https://xetown.com/topics/1229684 링크를 참고하세요)

 

처음 변환하고 난다음 스킨파일을 수정하지 않는한 기존의 파일들을 만든 PHP파일을 계속 호출하는 방식으로 사용자의 브라우저에 출력해줍니다.

 

그런데 그 말은 사용자가 홈페이지에 접속 -> 페이지이동할때마다 해당 PHP파일이 실행이 같이 된다는 뜻이 됩니다.

 

즉 하나의 PHP파일을 실행하는 것이고 그 실행하는 곳에 쿼리가 있으면 한번의 페이지 이동 혹은 페이지 접속때마다 쿼리가 하나씩 늘어난다는 겁니다.

 

1번 2번 예시에서 만들어둔 쿼리가 있으면 이게 지속적으로 계속 쿼리를 실행하게 된다는 뜻이 됩니다. 

 

근데 이건 직접적으로 디비를 쿼리한 것이 되기 때문에 캐싱도 안됩니다. (캐싱된 템플릿 파일은 그저 HTML을 PHP으로 실행하기 위해서 만들어둔 파일에 불가하고 거기에서 저런 쿼리문이 존재한다면 그 쿼리를 실행하게되는거죠)

 

그런데 이걸 한두개정도만 쓰신다면 상관없는데 XETown의 오른쪽 목록 처럼 여러게 붙이게 되면 환장합니다.

 

1번 예시이면 그나마 괜찮은데, 2번 목록일경우 대환장 파티하는 것이죠. 1번과 2번의 차이는 page가 들어간 것인데 이게 들어가면 일반 쿼리보다 훨신 많이 느려집니다... (게시물이 많아지면 많아질수록 느려질 수 밖에 없는 쿼리 방식입니다..)

 

그럼 바람직한 방법은 뭘까요..

 

사실 저렇게 사용되는 항목들은 대부분 위젯으로 대처가 가능합니다. {@으로 입력하셨던 항목들은 대부분 PHP항목입니다. 그렇다는건 위젯도 제작할 수 잇는 단계가 됩니다.

 

위젯으로 처리해주세요.

 

레이아웃 스킨등에서 직접쿼리하는 것과 위젯으로 직접 쿼리하는 것의 차이는 다릅니다.

 

스킨에서 바로 쿼리하게되면 스킨의 PHP코드가 캐싱되는것이라 실제 PHP코드는 다시 돌아가므로 매번 페이지 이동 접속시마다 디비를 쿼리하게됩니다.

 

그런데 위젯을 만들게되면 위젯에서 위젯캐시를 구성할 수 있습니다. (슈퍼캐시 혹은 위젯캐시모듈 자체에서 직접 가능합니다.)

 

이렇게 된다면 직접 쿼리한 결과값을 가지고 위젯스킨이 만든 결과물있죠? 그걸 직접 캐시하는 겁니다. 

 

즉, 매번 실행시마다 쿼리하는게 아니라 거기에서 정한 시간마다 쿼리할 수 있게 되는 것 입니다.

 

바람직하게 코딩하는 방법은 이렇게 위젯을 활용하는 것이예요.

 

직접 쿼리하지말고 좀 작업이 번거롭더라도 이렇게 한번 해보세요.

 

여러분이 흔히 알고있는 대부분의 대형사이트들에서도 이런 호환성이나 성능을 고려했더라면 환호할 것입니다.

 

대형사이트들이 만들줄 몰라서 기능을 빼는게 아니라.. 추가하면 할수록 성능을 갈아먹으니 추가를 안하는 겁니다.

 

그런 부분 배려한번 해주신다면 좀 더 좋고 퀄리티 높은 제품으로 많은 사랑 받으실 수 있을거예요!

 

다들 화이팅! 으샤으샤 합시다~!!

 

람보

profile
람보입니다.
  • profile
    저도 db에 데이터를 실시간으로 조회해야 하는 것이 아닌 것을 매번 조회하는 것에 대해 고민해 본 적이 있는데요.

    그런데 스킨에서 특정 값을 구하기 위해 쿼리하는 것을 모두 위젯과 위젯스킨을 만들어 업로드해서 위젯의 코드를 생성해서 위젯코드를 스킨에 넣어 위젯의 템플릿이 출력되도록 해야 하나 하는 것에는 약간 갸우뚱 하게 됩니다.

    이론적으로야 위젯에서 캐싱을 할 수 있기에 반복적인 db 쿼리를 줄일 수 있긴 하겠지만 이런 저런 이유로 db에서 값을 확인해야 할 경우가 많다면 단순히 이 결과 확인을 위해 위젯을 만들고 업로드해서 생성된 코드를 삽입하고 하는게 관리적인 측면에서 가능한지 의문이기도 합니다.

    물론 위젯으로 만들어야 할 사이즈이면서 템플릿까지 꾸며야 한다면 위젯으로 당연히 제작하는게 맞죠.

    저는 말씀 하신 부분에 고민을 스킨에서도 db에 조회해서 얻은 결과를 쉽게 캐시적용해서 그 캐시 만료 시간에 따라 쿼리 하는 코드에서 반환되는 것으로 할 수 있을 것 같은 고민은 해본적이 있습니다.

    그런데 실제로 그렇게 하지 않은 이유는 그냥 매번 쿼리해도 큰 문제가 일어나지 않아서 그냥 매번 쿼리하도록 두고 말았죠.
  • profile profile
    말씀하신 것처럼 특수한 상황의 경우 직접 쿼리하는게 맞습니다.

    그런데 이 글의 제목과 같이 레이아웃 템플릿 제작자를 타겟으로 본다면 특수한 상황이 많이 연출되지 않고 대부분의 쿼리가 게시글인 점도 많아서 적었던 글입니다.

    일반적으로 이럴경우 위젯을 활용해달라는 것이고, 말씀드린 특수한 경우도 왼만하면 XE함수내에서 처리할 수 있으면 XE함수를 사용하는 것이 좀 더 바람직합니다.

    ex) 회원정보 가져오는것,
    1.
    getModel('member')->getMemberInfoByMemberSrl($member_srl);

    2.
    $args = new stdClass;
    $args->member_srl = $member_srl;
    $output = executeQuery('member.getMemberInfoByMemberSrl', $args);

    1번의 경우 오브젝트 캐시를 사용한다면 쿼리를 하지 않습니다.

    2번의 경우 매번 쿼리를 반복적으로 하겠지요.

    즉, 저는 범용적인 레이아웃 템플릿 스킨들을 판매 또는 배포하시는 분들에게 좋은 방법의 예시를 드린 것으로 인지해주시면 좋을 것 같습니다.ㅎㅎ
  • profile profile
    네. 어떤 의미인지 알고 위젯에서 캐시가 쉽게 되는 것에 관해서는 매력적이긴 하나 개인적으로 생각했던 부분은..

    부득이하게
    $args = new stdClass;
    $args->member_srl = $member_srl;
    $output = executeQuery('member.getMemberInfoByMemberSrl', $args);

    이런 코드로 결과를 구해야 하는 상황이 발생한다면

    $output 을 캐시를 적용할 수 있지 않을까 하는 궁금증이 있었습니다.

    XE 라이믹스의 php 에서는 캐시를 적용할 수 있으니
    템플릿에서도 {@ } 로 php 언어를 사용하니 캐시를 주어서 위젯이 캐시되는 것과 같은 결과를 낼 수 있지 않냐 하는 의문을 가지고 있는 상태입니다.

    물론 제가 가능하지 않은 것을 꿈꾸고 있는 거라면 알려주시면 꿈 깨도록 하겠습니다. ㅋㅋㅋ
  • profile profile
    템플릿스킨은 약간 달라서 그런 방식으로는 어렵죠 ㅎㅎ
    조건문 만드는것도 어렵고 ㅠㅠ..

    그리고 캐시 주기나 어디서 어떻게 캐시를 적용할지에 대한 시점을 확인하기가 애매하기도 하죠 ㅎㅎ
  • profile profile
    다른 자료에서 캐시 클래스에서 제공하큰 간단한 함수를 쓴 적이 있었는데
    https://github.com/rhymix/rhymix/blob/be1fbc9d65ec59cabc554706365ba7d7144e7d11/common/framework/cache.php#L209
    어지간하면 템플릿에서도 쓸 수 있지 않을까 싶어요.
    라이믹스라면...!
  • profile profile
    네. php 가능한거 템플릿에서도 가능하다고 생각하고 있습니다.
    다만 템플릿에서 php 코드 작성이 조금 까다로울 뿐이죠.
  • profile profile

    if (♡☆@):
    ~~~~~~~;
    endif;
    로 가야죠ㅜ
  • profile profile
    네. 제가 필요하다면 그렇게 캐시를 ttl 까지 설정해서 사용해 보려고 했는데 그렇게 까지 해야할 상황이 오진 않더라구요.

    물론 외부에 접속해서 결과까지 받아오는 그런 코드를 템플릿에 직접 사용했다면(불가피하게..) 템플릿에 직접 캐시를 적용해서 컨트롤 하려고 생각만?? 하고 있는 뭐 그런....
  • ?
    손이 많이 가는 문제 때문인 것 같아요.
    필요에 따라 위젯 만들고 위젯 스킨 만들고 배포용이라면 각각 배포해야하고 그걸 또 같이 설치하라고 설명해야하고.. 오래된 문제죠.

    잘못 본건지 모르겠지만 플러그인(2.0 계획에서 취소된 테마말고 오래전에 본 것 같은..)이라는 명칭으로 통합한 형태에 대해 이야기가 있었던 것 같은데 그게 되었으면 조금은 편했을 것 같습니다.
  • ?
    https://github.com/rhymix/rhymix/issues/82
    이거군요.
  • ? profile

    현재 라이믹스 2.0에서 class.php controller.php 와 같이 꼭 규칙을 따르지 않더라도 아무런 클래스 이름으로 호출할 수 있어요.

    그래서 모듈이 거의 준플러그인처럼 작동시킬 수 잇죠.

    class classname extends modulename

    이렇게 잘만 잡아주면 자동으로 autoload 된다능...ㅋㅋㅋ

     

    그래서 따로 인클루드 없이 classname::getLib() 와 같이 활용하시면 되요!

     

    이를 잘활용해서 스킨에서도 가능하죠!

  • ? profile
    테마와 플러그인은 2.x 버전대에서 멀지 않은 미래에 적용될 예정입니다.^^
  • profile ?
    오토로드;;;
  • profile ?
    시간이 많이 필요한 일이죠.
    디비나 클래스 구조에 의존하지않은 방법으로 hook도 지원되면 좋겠네요.
  • profile

    사실 저런 이슈 때문에 왠만해서는 템플릿 내에서 직접 쿼리하는 것을 지양하는 편이긴 합니다만, 캐싱이 되면 안되는 경우들이나 레이아웃과의 데이터 교환이 필요한 케이스는 위젯을 사용하기가 어려운 편이 있습니다.

    물론 여러모로 방법은 존재하겠지만 이를 위한 진입장벽이 꽤 있다보니(당장에 XE1 API 명세도 가독성이 심히 떨어지는 관계로...) 결국은 템플릿 내에서 쿼리를 하게 되는 문제가 생기는 것 같습니다. 그리고 위의 특수한 케이스가 아니더라도 현재의 위젯 시스템은 번거로운 부분이 꽤 있습니다. 유저가 직접 사용할 수 없고 레이아웃 내에서만 사용되는 위젯이라 할지라도 결국은 위젯 페이지에 노출되며, 위젯의 정해진 설계 방식에 따라 편집 가능한 형태(usable? 사용자 지향? 뭐라 표현해야할지 좀 애매합니다)로 구현해야 하며, 위젯만의 정해진 규격이 있기 때문에 궁극적으로 프로젝트의 부피가 밸류에 비해 커지는 경향이 생깁니다.

    개발 편의성이 어떤 식으로 해소될지는 모르겠지만 준비 중인 테마 기능이 굉장히 기대되는 부분입니다.

  • profile profile
    넵 그런 경우가 있다는건 인지하고 있습니다.

    그렇지만 늘어나는 항목만큼 잘 활용한다면 대형 사이트에서도 좀 더 편안하게 사용할 수 있는 레이아웃이 되지 않을까 라는 생각이 듭니다.
  • profile
    저희 같은 경우 1번 예시처럼
    게시물 추천인을 직접 쿼리 하여
    리스트로 만들어서 출력해주고있는데요.
    추천, 비추천이 수시로 바뀌는데 이것도 위젯으로 캐시 처리를 하면 효과가 있는건지 궁금합니다~~
  • profile profile
    수시로 바뀌더라도 2분 3분 마다 갱신해 준다면 동접 100명이상인 사이트에서는 엉청 도움 됩니다
  • profile profile

    추천이나 비추가 발생할 때마다 트리거를 사용해서 갱신해 주면 딱 좋겠네요.
    1000명이 읽는 동안 추천수는 20명도 안 되는 경우가 많으니, 캐시는 딱 20번만 갱신하고
    나머지 980명의 눈팅족은 캐시된 내용을 보면 되겠지요. 쿼리 98% 감소!^^

  • profile ?

    트리거를 사용하려면 모듈을 만들어야 겠네요.
    아니면 아래와 같은 꼼수를...
    https://github.com/wstackme/wst_addon_boilerplate/blob/main/functions.php#L128-L129

  • ? profile
    꼼수랄 것도 없이 라이믹스에서 기본 지원하는 함수를 쓰면 됩니다.^^
    https://github.com/wstackme/wst_addon_boilerplate/blob/main/functions.php#L115
  • profile ?

    아.. 위에거가 라이믹스군요.

    좋네요 =_=b

  • profile

    물론 위젯으로 처리하면 좋겠지만, 위젯을 일일이 만들어서 처리하기 번거롭기도 하고...

    각 게시물 본문에서 입력된 정보를 바탕으로 다른 게시판의 게시물을 불러오는 형태라 

    전 이렇게 스킨에서 이런 식으로 캐시 처리를 한 적이 있었네요 ㅎㅎㅎ

     

     

    1616176551803.jpg