카테고리 보관물: Front-End Development

Frontend Engineering

2000년대 초반까지만해도 Web은 정적이었습니다.
하지만, 그 이후 다이나믹한 웹애플리케이션 즉, 하나의 완전한 플랫폼으로써 웹은 발전했고, 지금도 계속 변화 하고 있습니다.

OS의 응용프로그램에 버금가는 애플리케이션이 웹에서 구현이 가능해짐에 따라 다양한 브라우저, 다양한 Device, 다양한 요구사항
즉, 다양한 환경에서 사용자에게 질높은 서비스를 제공하기 위해 관련 지식을 연구하고 개발에 적용하는 사람들을 Frontend 개발자라고 합니다.

Frontend Engineer 직군을 현업에 종사하는 분들도 협업 해보지 않으셨다면, 생소한 분들이 많습니다.
이에 대해 야후에서 Frontend Engineer가 하는일을 잘 정리한 글이 있어 링크합니다.

[번역/요약] Professional Frontend Engineering

 

IE에서 스크롤값 구하기.

window의 스크롤된 X축과 Y축을 IE를 제외 하고는 아래와 같이 좌표 정보를 동일한 방법으로 얻을 수 있습니다.
scroll값 구하기
또 하나, 최신 브라우저는 (window.pageXOffset == window.scrollX) 동일한 값을 반환하니, IE를 제외하고는 사용하셔도 됩니다.

하지만, IE는 동작하지 않아 별도의 처리가 필요합니다.

// IE에서 스크롤값 구하기
document.body.parentNode.scrollTop 
document.body.parentNode.scrollLeft

jQuery의 JSONP을 사용한 크로스도메인간 통신

웹은 Same origin policy이 동일한 도메인상의 요청만 가능하도록 제한하였지만,
도메인간 데이터 통신으로부터 다이나믹한 웹구현을 위한 방법으로 JSONP가 나오게 된것이다.

jQuery의 ajax를 이용한 두가지 jsonp 요청 방법을 지금부터 소개 하겠습니다.

첫번째, 요청 URL뒤에 ?callback=? 추가하여 jsonp 요청 구현하기

jQuery 1.2부터는 JSONP 호출에 대한 네이티브 지원이 제공되고 있다. JSONP 콜백을 지정한 경우 다른 도메인에 있는 JSON 데이터를 로드할 수 있으며 JSON 콜백은 url?callback=? 라는 구문을 사용하여 지정할 수 있다.

$.getJSON() 방식을 살펴보면 url 맨 끝에 callback=이라는 문자열과 함께 실제 함수 이름 대신 ? 기호를 콜백 함수 이름으로 입력하는 것을 볼 수 있다.

이는 jQuery가 ? 기호를 인라인 함수를 호출하는 생성된 함수 이름(예:jsonp1234568416)으로 바꾸기 때문이다. 굳이 ? 을 적을 필요는 없고 따로 처리하는 콜백 함수가 있다면 해당 함수의 이름을 적어줘도 무방하다. (익명 메소드로 바로 처리할 경우 반드시 ? 를 써줄 것)

Client

$.getJSON("https://codejs.mycafe24.com/jsonp.json?callback=?",
  function(data) {
    console.log('성공 - ', data);
  }
);

Server (jquery에서 생성한 익명의 callback함수명을 받아 감싸서 응답 준비를 합니다.)

protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
    request.setCharacterEncoding("UTF-8");
    response.setCharacterEncoding("UTF-8");
         
    String id = request.getParameter("id");
    String callBack = request.getParameter("callback");
 
    JSONObject obj = new JSONObject();
    obj.put("result", id);
    obj.put("go", "테스트");
         
    PrintWriter out = response.getWriter();
    out.write(callBack + "(" + obj.toString() + ")");
    System.out.println(callBack + "(" + obj.toString() + ")");
    out.flush();
    out.close();
}

두번째, 응답 json에 callback함수로 한번 감싸서 jsonp 구현하기

Client

$('a').click(function() {
  $.ajax({
    url: "https://codejs.mycafe24.com/jsonp.json",
    dataType: 'jsonp',
    jsonpCallback: "myCallback",
    success: function(data) {
      console.log('성공 - ', data);
    },
    error: function(xhr) {
      console.log('실패 - ', xhr);
    }
  });
});

Server

myCallback({"message":"You got an AJAX response via JSONP from another site!"});

JSONP로 ajax 호출을 하기 위해선 위와같이 함수안에 json 문자열이 들어간 형식으로 서버에서 리턴을 해줘야 가능하다.

서버에서 파라메터로 응답 JSON함수명을 생성하여 보안을 강화하는 방법도 있으니,
그부분은 http://stove99.tistory.com/10 이곳을 참고 하면됩니다.

세번째, jsonpCallback 옵션없이 사용하기.

Client

$('a').click(function() {
  $.ajax({
    url: "https://codejs.mycafe24.com/jsonp.json",
    dataType: 'jsonp',
    success: function(data) {
      console.log('성공 - ', data);
    },
    error: function(xhr) {
      console.log('실패 - ', xhr);
    }
  });
});

Server

jQuery18305806868467951786_1366340807385({"key":"value"});

jQuery18305806868467951786_1366340807385(요청시 마다 바뀜)은 jsonpCallback을 지정하지 않으면 jQuery에서 자동으로 callback 요청 매개변수를 자동 생성해서 요청한다.
요청을 받은 서버에서는 callback 매개변수값을 함수 호출 하듯 감싸서 응답하면 된다.

참고 : http://warmz.tistory.com/739

웹사이트 성능 향상 개발 방법

  1.  Make fewer HTTP requests
    • Image Maps – 이미지 맵은 하나의 이미지로 여러장의 이미지 효과를 나타낸다. 또한 같은 사이즈를 가지고 많은량의 http request를 줄여준다.
    • Css Request – 이미지맵처럼 필요한 이미지를 한장에 담고 css 스타일 적용으로 필요한 부분만 보이게 한다.
    • Inline Images – data:URL scheme를 이용하여 페이지에 이미지 데이터를 삽입시킨다. 따라서 html 페이지의 사이즈는 엄청 커지는데 반해 요청은 줄게 된다.
    • Comblined Files – 스타일시트, 스크립트 파일을 모두 통합하여 하나의 파일에 포함시켜 http request를 줄인다.
  2. Use a CDN(Content Delivery Network)
    • CDN 서비스라고 하면 사용자의 위치에 따라서 가장 가까운 서버에 접속해서 데이터를 가져오는 서비스를 말한다. 데이터를 가장 빠르게 받을수 있는 서버에서 데이터를 받는다면 당연히 페이지가 빨리 뜰것이다.  야후의 경우 약 20%정도의 성능향상이 있었다고 한다.
  3. Add an Expires header
    • 웹페이지가 점점더 richer해지면서 각종 script, css, images등이 증가 하게 되며 이는 많은 http request를 유발시킨다. 하지만 expire header를 추가 한다면 이것들을 캐싱시킬수 있다.
    • Expire header를 사용하면 그 날짜가 지나기 전에는 각 컴퍼넌트를 재 호출하지 않는다. 만약 아파치서버를 사용중이라면 ExpireDefault값을 이용하여 지정을 해줄수 있다.
  4. Gzip Components
    • 원초적인 해결방법으로 대역폭이나 캐싱가지고 해결이 안된다면 압축을 하는 방법도 있다. 즉 http request(1.1)의 헤더에 accept-encoding헤더를 붙여서 보내면 서버는 압축을 하며, 지정된 엔코딩 방식으로 압축후 response할때 그 엔코딩 방식으로 같이 붙여서 보내며, 이를 브라우저가 해석하는 방식이다. (가장 많이 쓰이는것이 gzip방식)
    • gzip의 경우 약 70%의 압축률을 보여주며, 현재 90%의 인터넷 브라우저가 gzip을 지원한다. 다만 압축방식의 경우 image와 같은 이미 압축이 되어있는 파일을 대상으로 할경우에는 오히려 사이즈가 더 커지는 문제가 있으므로, script같은 text로 이루어져있는 컴포넌트 같은경우 매우 효율적일 수 있다.
  5. Put CSS at the top
    • 원초적인 해결방법으로 대역폭이나 캐싱가지고 해결이 안된다면 압축을 하는 방법도 있다. 즉 http request(1.1)의 헤더에 accept-encoding헤더를 붙여서 보내면 서버는 압축을 하며, 지정된 엔코딩 방식으로 압축후 response할때 그 엔코딩 방식으로 같이 붙여서 보내며, 이를 브라우저가 해석하는 방식이다. (가장 많이 쓰이는것이 gzip방식)
  6. Move scripts to the bottom
    • <head> 대신 </body> 앞에 스크립트를 넣어 DOM이 먼저 그려진 후 Script가 load되도록 한다.
  7. Avoid CSS expressions
    • CSS expression을 피하라 : width: expression(~~~) 식의 표현을 자제하면 된다.
  8. Make JS and CSS external
    • 자바스크립트와 CSS를 외부로 빼내라
  9. Reduce DNS lookups
    • DNS lookup시간을 줄여라
  10. Minify JS
    • 스크립트의 사이즈를 최소화하라
    • js, css 파일을 압축 : 다른 리소스들(이미지와 같은)은 http connection이 모두 사용되어 다운로드를 하지만 유독 js만은 하나의 커넥션으로만 진행됨
    • 캐싱되는 문제점을 보완하기 위해서 <script src=”script1.js?v=001″></script> 식으로 버전관리 필요
    • 자바스크립트 압축 사이트 http://closure-compiler.appspot.com/home
  11. Avoid redirects
    • 리다이렉트 페이지를 피하라
  12. Remove duplicate scripts
    • 중복 스크립트를 제거 하라.
  13. Configure ETags
    • ETag는 HTTP/1.1 에 명시되어있는 response header로서, cache validation으로 사용될 수 있는 값을 나타낸다. caching을 수행하는 측에서는 If-Modified-Since로 validation – caching되어있는 object가 새로 갱신하지 않아도 되는 유효한 object 인지 확인하는 작업 – 을 수행할 때, 저장되어있던 ETag값을 같이 이용하여 좀 더 확실한 validation을 할 수 있다.
      문제는, 아파치의 경우 ETag값을 파일의 i-node, size, last-modifed time (mtime) 을 이용하여 계산한다는 것이다.
      만약 아파치 웹서버들이 Round-Robin 방식으로 클러스터를 구성하면 웹서버들마다 같은 파일이라도 다른 i-node 값을 갖게될 가능성이 매우 크므로, caching을 수행하는 측의 cache hit-ratio가 매우 떨어지게 된다.
      이 문제를 해결하기 위해서는 아파치가 ETag를 계산하는 방식을 바꿈으로써 각 웹서버들마다 같은 파일에 대하여 같은 ETag 값을 보내주도록 한다. 아파치의 FileETag directive를 사용하여 다음과 같이 한다.

      FileETag MTime Size 

      FileETag directive는 아파치가 ETag를 계산할 때 파일의 어떤 속성값들을 사용할지를 지정한다. 위와 같이 last-modified time과 size 속성값만을 사용하여 ETag를 계산하도록 하면, 같은 파일에 대하여 여러 웹서버들마다 동일한 ETag값이 계산되도록 할 수 있다.
      단, FileETag directive는 아파치 1.3.23 이후부터 지원되는 directive 이다. 이전버젼들에 대해서 사용하고 싶을 경우는 아파치 소스를 수정하여 사용할 수 밖에 없을 것이다. (아파치 모듈로 해결가능한지는 확인해보지 않았다.)

      그리고 위의 13가지의 항목의 우선순위를정해 가중치를 둬 우선순위가 높은 항목부터 우선 적용해서 효율적인 웹 서비스를 할 수 있도록 합시다.

[우선순위]

  • 중요도 10
    • Add an Expires Header
    • GZip Components
    • Configure ETags
  • 중요도 9
    • Use a Content Delivery Network
    • Put CSS at the Top
    • Minify JavaScript
    • Avoid Redirects
    • Make Fewer Requests (css, js, img)
  • 중요도 5
    • Reduce DNS Lookups
    • Move Scripts to the Bottom
    • Remove Duplicate Scripts
  • 중요도 3
    • Make Fewer Requests (CSS background images)
  • 중요도 2
    • Avoid CSS Expressions

 

참고 : http://www.mimul.com/pebble/default/2007/05/11/1178878320000.html