웹 개발 입문자를 위한 Vue.js 프레임워크 소개

누구나 쉽게 시작할 수 있는 Vue.js 프레임워크와 학습 자료 소개

Advertisements

들어가며

요즘 프런트엔드 개발에 관심을 갖는 분들이 점점 많아지고 있습니다. 컴퓨터 공학을 전공한 대학생 뿐만 아니라 비전공자, 퍼블리셔, 디자이너 분들도 점점 멋진 웹 화면을 개발하기 위해 스스로 정보를 찾아가며 웹 개발하는 법을 배우고 있는 것 같아요.

웹 개발을 위한 기초 HTML, CSS, 자바스크립트를 배우고 나면 제일 먼저 찾게 되는게 바로 프런트엔드 프레임워크입니다. React, Angular 처럼 널리 알려진 프레임워크 사이로 요즘 새롭게 떠오르는 쉽고 강력한 프레임워크가 있습니다. 바로 Vue.js 입니다.

이번 글에서는 Vue.js에 대해서 간단히 소개하고, 웹 개발 입문자도 쉽게 프레임워크를 배울 수 있는 자료들을 안내하려고 합니다.

Vue.js 프레임워크란?

먼저 Vue.js 프레임워크가 무엇인지 소개를 하자면 Vue.js는 웹 사이트를 만들 수 있는 웹 개발자들의 도구입니다.

웹 사이트를 만들기 위해서는 HTML, CSS, Javascript와 같은 웹 기술이 필요합니다. 이 3가지 웹 기술로도 요즘 저희가 많이 사용하는 페이스북, 네이버, 구글 등 여러 가지 유형의 사이트를 만들 수 있습니다.

그런데 왜 프레임워크를 사용해서 만들까요? 그 이유는 더 쉽고 빠르게 웹 사이트를 만들 수 있기 때문입니다. 정형화된 방식으로 미리 만들어진 기능들을 편하게 가져다가 다시 사용하기 때문에
백지상태에서 시작하는 것보다는 확실히 더 빠르게 일정 이상의 좋은 품질로 개발할 수 있죠.

화면을 쉽게 개발할 수 있는 프런트엔드 프레임워크는 2000년대 중후반부터 등장했습니다. 그리고 많은 프런트엔드 프레임워크를 거쳐 지금의 Vue.js에 이르기까지 수많은 프레임워크가 등장했죠. 그래서 요즘 웹 사이트를 개발한다고 하면 엄청나게 많은 도구의 선택지가 있습니다.

좋죠. 일단 선택지가 많으니 뭐든 잘 배워서 개발할 때 써먹으면 되니까요. 하지만, 반대로 생각해보면 정말 너무 많습니다. 네 저도 지금 4년 동안 회사에서 웹 개발을 해왔는데 배우는 걸 멈춰본 적이 없습니다. 맨날 새로운 게 튀어나오고 그러면 또 배우고..

그래서 요즘에는 이런 상황에 고통받는 웹 개발자들이 한 둘이 아닙니다. 제 주변만 봐도 그렇거든요. ‘아 또 나왔네……’라면서 한숨을 쉬는 개발자들이 있습니다. 저도 한숨까지는 아닌데 아 공부할게 하나 더 늘었구나라고 생각은 하죠 🙂

Vue.js 프레임워크는 이런 현재 상황에서 가장 쉽게 접근할 수 있는 프레임워크입니다. 요즘 업계에서 많이 사용되는 앵귤러, 리액트와 다르게 HTML, CSS, 자바스크립트 이외에 꼭 알고 있어야 하는 기술도 없으며 프레임워크 자체가 가볍고 쉬운 프레임워크를 지향하기 때문에 배우기가 쉽습니다.

또한 배우기가 쉽다는 점 때문에 더 많은 입문자들에게 관심을 받고 있다고 생각합니다. 그리고 기존에 프런트엔드 개발을 하지 않았던 다른 분야의 개발자들도 Vue.js로 쉽게 웹 개발을 시작하고 있습니다.

서적을 집필하면서..

책을 잠깐 소개하겠습니다.

Do it! Vue.js 입문서는 Vue.js 프레임워크를 처음 배우는 사람들이 쉽게 프레임워크를 배울 수 있도록 집중한 책입니다.

처음 출판사와 도서를 기획하고 목차를 구성하면서 어떻게 하면 이 쉬운 Vue.js 프레임워크를 더 쉽게, 빠르게, 재밌게 알려줄 수 있을까? 라는 고민을 했습니다. 작년에 패스트 캠퍼스인프런에서 강의를 하면서 검증했던 교재와 자료들을 중심으로 수업 중간중간에 수강생들이 이해하지 못하던 부분들, 특히 질문이 많았던 부분들을 어떻게 책에 잘 녹여낼지에 대한 고민을 가장 많이 했습니다. 생각해보면 이 책을 가장 필요로 하는 웹 개발 입문자, 퍼블리셔, 대학생, 실무자를 대상으로 수업을 진행했기에 수업에서 나온 피드백이 정말 소중했었죠.

처음에 초고를 쓸 때 그 내용을 책 안에 담는 게 쉬운 작업은 아니었습니다. 기술 서적을 처음 집필하는 입장에서 어떻게 써야지 독자들이 더 쉽게 읽을 수 있을지 감이 잘 안 왔었거든요. 그때 다행히 기술서 편집 경험이 많은 노련한 편집자님을 만나 요약된 정보 위주로 전달하는 블로그 글 형식에서 더 친절하고 쉽고 자세히 설명하는 글 형식으로 탈바꿈할 수 있었습니다.

책 전체를 교정하는 과정에서 특정 부분은 최소 7번 이상 다시 썼던 것 같아요. 편집자님이 쉽고 자세한 설명을 요구했었기 때문이기도 했지만 제 스스로도 다시 읽었을 때 이상하다 싶은 부분들은 그냥 넘어가지 않고 몇 번이고 다시 고쳤습니다. 그렇게 전체 원고를 최소 8번 넘게 정독한 것 같습니다.

또한, 글로 쉽게 설명하기 어려운 부분들은 도형과 그림으로 풀어냈습니다. 그림과 도형 같은 경우에도 제가 한번 쓱 그리고 끝내는 것이 아니라 1차로 제가 작업한 그림을 개발 지식이 있는 전문 디자이너 분께 2차 작업을 맡겼고, 3차로 다시 디자이너 분과 논의하면서 도형을 다듬었습니다. 그리고 4차, 5차 작업을 편집자님, 개발을 모르는 기획자분께 검토 받으며 어느 관점에서 보든지 그 글을 쉽게 이해할 수 있는 그림으로 선정했습니다.

책 작업을 하는 내내 생각했던 1가지는 ‘내 스스로도 납득이 가지 않는 글은 책에 담지 않는다’ 였습니다. 그렇기에 글의 흐름, 단어 설명, 도형과 그림, 예제 코드 등 책의 모든 부분을 하나도 빠짐없이 꼼꼼히 읽고 검토했습니다.

그리고 그 검토 작업에 고맙게도 많은 분들이 도움을 주셨어요. 모든 집필/편집 과정을 함께해준 편집자님, 직관적인 그림과 도형을 그려준 디자이너 겸 개발자님, 전체적인 책의 오탈자와 구성 오류를 검토해준 기획자님, 그리고 베타 리딩과 기술 검수를 맡아준 개발자 두 분까지 합하면 벌써 이 책에는 저 혼자가 아닌 6명의 노력과 시간이 들어갔네요. 그 외에도 조판하는 회사의 직원과 이 책을 함께 검토해주는 출판사 직원까지 생각하면 정말 많은 분들이 좋은 책을 내기 위해 함께해주신 것 같습니다.

그래서인지 이번에 출간된 Do it! Vue.js 입문 책을 자신 있게 추천할 수 있습니다. 혹시 웹 개발을 시작하고 싶다면 Do it! Vue.js 입문 책으로 시작해보시는 건 어떨까요? 🙂

읽어주셔서 감사합니다.
저자 장기효 올림

P.S : 여러 명의 땀과 노력이 들어간 Do it! Vue.js 입문 도서는 아래 링크에서 구매하실 수 있습니다 🙂
Do it! Vue.js 온라인 구매 링크

Vue.js 학습 자료

성능 덕후를 위한 자바스크립트 코딩 패턴 (중급 이상)

이 글은 CodeSchool 의 Javascript Best Practices 를 듣고, 주요 내용을 정리한 글입니다.

Ternary Conditional (삼항 연산자)

  • 다음과 같은 예문이 있다.
var isArthur = true;
var weapon;

if(isArthur) {
  weapon = "Excalibur";
} else {
  weapon = "Longsword";
}
  • 삼항연산자를 이용하면 위의 if else 문을 아래와 같이 바꿀수 있다.
var weapon = isArthur ? "Excalibur" : "Longsword";
  • 또한 삼항 연산자를 다음과 같은 형태로도 사용이 가능하다.
// 두개 이상의 변수를 이용하여 값을 받는 경우
isArthur && isKing ? (weapon = "Ex", helmet = "Goose") : (weapon = "ln", helmet = "Iron")

// 즉시 실행함수로 값을 받는 경우
isArthur && isKing ? function () {
                                   // ...
                     }();
                     :
                     function () {
                       // ...
                     }();

Logical Assignment 1 (OR)

  • OR 연산자 : “falsy” 하지 않은 가장 첫번째 마주친 값을 갖는다.
  • 아래의 삼항 연산자를 OR 연산자를 이용하여 다음과 같이 줄일 수 있다.
// 삼항연산자 사용
function addSword(sword) {
  this.swords = this.swords ? this.swords : [ ];
  this.swords = push.(sword);
}

// OR 연산자 사용
function addSword(sword) {
  this.swords = this.swords || [ ];
  this.swords = push.(sword);
}

// OR 연산자 잘못 사용한 예
function addSword(sword) {
  this.swords = [ ] || this.swords;
  this.swords = push.(sword);
}
// 위의 경우 계속 new array 를 할당함.
  • OR 연산자의 잘못된 사용 예를 더 본다.
// 잘못된 OR 연산자 사용 예
var result1 = 42 || undefined; // undefined 를 절대로 마주치지 않는다.
var result2 = ["Sweet", "array"] || 0; // 0을 절대로 마주치지 않는다.
var result3 = {type: "ring", stone: "diamond"} || ""; // "" 를 절대로 맞추지지 않는다.

// 위를 고쳐보면,
var result1 = undefined || 42;
var result2 = 0 || ["Sweet", "array"]; // 0을 절대로 마주치지 않는다.
var result3 = "" || {type: "ring", stone: "diamond"}; // "" 를 절대로 맞추지지 않는다.

Logical Assignment 2 (And)

  • OR 연산자와는 다르게 두개의 “truthy” 값이 있으면, 마지막으로 확인한 truthy 값이 리턴된다.
  • “falsy” 값의 경우에는 OR 연산자와 동일하게 동작한다.
var result1 = "King" && "Arthur";
console.log(result1); //Arthur
var result2 = "Arthur" && "King";
console.log(result2); // King

Switch Blocks

  • 반복되는 if else 문과 switch 문의 차이점은, 순차적으로 모든 if 문을 도느냐. 아니면 해당하는 case 로 바로 가서 불필요한 연산을 줄이느냐의 차이이다.
var regimnet = 3;

if (regiment == 1) {
  ...
} else if (regiment == 2) {
  ...
} else if (regiment == 3) { // 앞 1,2 를 거쳐 3으로 온다.
  ...
}

switch (regiment) {
  case 1:
    ...
  case 2:
    ...
  case 3: // 3으로 바로 온다.
    ...
}
  • break 문을 사용하지 않고, 공통된 property 를 상위 case 에서 부터 순차적으로 접근하여 추가하는 방법도 있다.

Loop Optimization

  • 컴퓨터 메모리 관점에서 일반적인 for 문의 연산 순서를 보자.
treasureChest = {
  necklaces: ["A", "B", "C", "D"];
};

for (var i = 0; i < treasureChest.necklaces.length; i++) {
  console.log(treasureChest.necklaces[i]); 
} 
  • 위 for 문에서 메모리 연산이 필요한 부분은 다음과 같다.
    1. i 값 탐색
    2. treasureChest 객체 탐색
    3. necklaces 속성 탐색
    4. necklaces 속성의 배열 인덱스 탐색
    5. length 프로퍼티 검색 > 위의 연산을 최적화 해보자 : Cache the necessary values in the local variables
// 1. length property 를 한번만 접근 (기존 for 문은 반복시 마다 접근)
var x = treasureChest.necklaces.length;
for (var i = 0; i < x; i++) {
  console.log(treasureChest.necklaces[i]);
}
  • 위의 리팩토링으로 연산 수가 다음과 같이 줄어들었다.
  • 위 코드는 더 개선할 수 있다.

// 2. for 문의 초기 선언문 쪽에서 x 값을 선언하면, 전역 변수로 var x 를 선언하지 않아도 되어 메모리가 더 효율적이게 된다.
for (var i = 0, x = treasureChest.necklaces.length; i < x; i++) {
  console.log(treasureChest.necklaces[i]);
}
  • 주의할 점 : 자바스크립트는 {} 로 스코핑이 되어 있지 않기 때문에, 위의 for 반복문이 끝나면 x 값은 최종 값으로 할당되어 있다는 사실

  • 또 다른 개선 포인트

// 3. 각 반복 싸이클마다 treasureChest 객체의 속성에 접근을 할 필요가 없다.
var list = treasureChest.necklaces;
for (var i = 0, x = treasureChest.necklaces.length; i < x; i++) {
  console.log(list[i]); } 

모든 인덱스를 접근할 때에는 for loop 문이 좋고, 때로는 for in 보다 성능이 나은 경우가 있다. for in 은 prototype 에 접근하여 기존의 기 정의된 메서드까지 포함하여 출력하므로 비효율적

Performance (Script Loading)

  • Work Intensive javascript 는 body 마지막 태그 맨 위나 async 속성 이용하여 페이지 첫 로딩을 빠르게 한다.

Performance (Inheritance)

  • 자바스크립트에서 상속은 prototype 을 이용
  • 공통으로 쓰는 메서드는 모두 prototype 에 집어 넣는다.
function SignalFire(id, logs) {
  this.id = id;
  this.logs = logs;
  this.functionality1: function() {

  },
  this.functionality2: function() {

  },
  this.functionality3: function() {

  },
}
  • 위 함수의 경우 매번 객체를 생성할 때 마다 사용하지 않는 메서드들을 메모리에서 사용하는 낭비가 발생한다.
  • 따라서, 매번 객체 생성시 필요한 속성이나 메서드만 가져가도록 하고, 공통 메서드는 다음과 같이 prototype 으로 뺀다.
  SignalFire.prototype = {
  functionality1: function() {

  },
  functionality2: function() {

  },
  functionality3: function() {

  },
}

Performance (Indivdual DOM)

  • list 를 배열로 갖는 DOM 요소에 append 메서드를 이용하여 DOM 을 추가하면 전체 리스트가 reflow 된다. 이는 성능에 악영향을 준다.
  • 성능 향상을 위한 해결법은 Fragment 를 사용한다.
var fragment = document.createDocumentFragment();
fragment.appendChild(element);
list.appendChild(fragment);

Performance (Get rid of var redundancy)

  • var 지정어를 사용할 떄, 다음과 같이 코드량을 줄일 수 있다.
var a = 1;
var b = "hello";
var c = ["a","b","c"];

var a = 1,
b = "hello",
c = ["a","b","c"];

// 코드의 가독성이 높아지고, 간결하다.

Performance (String Concatenation)

  • 문자열의 길이에 따라 += 연산자와 join() 메서드의 성능차이가 발생한다.
  • 문자열이 짧을 떄 : += 연산자가 성능이 더 빠르다.
  • 문자열이 길고, 문자열이 배열안에 리스트 형태로 저장되어 있을 때 : join("\n") 메서드가 성능이 우월하다.
var page = "";
for (var i = 0, x = newPageBuild.length ; i < x ; i++) {
  page += newPageBuild[i];
}

// join() 메서드 활용
page = newPageBuild.join("\n");

Namespacing

  • 팀 프로젝트 시 많은 양의 자바스크립트 코드를 작성할 때, 타 팀원이 작성한 전역변수가 overwrite 되는 경우가 발생한다.
  • 이를 막기 위해 namespacing 을 활용한다.
var a = ["Apple", "Banana", "Coil"];
var c = function () {
  console.log("this is not what I want.");
};

var nameSpace = {
a : "1",
b : 23,
c : function() {
  // ...
}
};

// HTML Element click event
onClick=nameSpace.c();

Google Trips 사용기

Google Trips 사용기

16.10.04 ~ 16.10.10 일주일 간 첫 런던 여행을 하면서 사용한 후기를 적어 공유한다.
Application 의 디자인, 성능, 사용성 보다는 전체적인 기능에 대한 사용후기를 주로 작성하였다.

Overview

  • Google Trips 는 강력한 오프라인 경험, 철저히 개인화 된 개인 여행 일정 관리, 여행지에 대한 정보를 빠르게 학습 할 수 있는 Mobile Application 이다.

Personalized Trip Management

  • 앱이 돋보일 수 있는 기능 중의 하나는, 개인적으로 다른 어떤 여행 앱들보다 여행의 전반적인 일정과 정보를 과거의 여행지부터 여행 예정지 까지 전체적으로 관리해 준다는 점이다.
  • 예를 들어, Google Trips 에 연동된 gmail 에 비행기 티켓이나 일정표 관련된 메일이 있다면, 그게 자동으로 이 Google Trips 어플리케이션과 연동되어 관리가 된다. (별도로 비행기나 숙박 일정을 추가하지 않아도 되는 편리함)
  • 예전에 갔던 여행지에 대한 정보들이 메일에 남아있다면, 다 동기화가 되기 떄문에 앞으로 여행할 때 꾸준히 사용한다면 내 인생의 여행기를 모두 Google Trips 안에 담아 관리할 수 있을 것 같다.

Best Offline Experience

  • 여행할 도시에 대한 모든 정보 (식당, 관광지, 할 일, 지도) 를 모두 미리 다운 받아, 가는 비행기 안에서 정독할 수 있는 것은 현존하는 어느 여행앱에서도 제공되지 않는 강력한 기능인 것 같다.

Not trusted Hot Spots

  • 기존의 구글 맵에서 제공하는 리뷰와 평점 데이터를 연계하여, 맛집과 명소들을 목록화 한 것 같은데, 여태까지의 4 번의 해외여행 시에 사용했던 Trip Advisor 와 달리 정보의 신뢰성이 떨어진다.
  • 예를 들어, 처음에 Google Trips 에서 제공하는 Hot Spots 의 평점이 높은 맥주집과 맛집을 돌았으나, 생각보다 맛이 있지 않았다. (나중에 Trip Advisor 를 통해 간 식당들이 더 합리적인 가격에 맛까지 있었음)
  • 리뷰 및 평점 데이터가 아직 많지 않아 신뢰할만한 데이터가 구성되지 않은 것 같다.

Personal Saved places

  • Hot Spots 에서 제공하는 장소들 중 마음에 드는 명소나 맛집을 즐겨찾기 해놓으면, 이게 리스트 형태로 쉽게 관리가 된다.
  • 리스트에 있는 장소들의 상세 페이지로 들어가면, 영업시간, 지도, 리뷰 및 평점, 참고 사항 과 같은 세부 정보들이 나와 매우 요긴하게 사용할 수 있다. 이 기능들 또한 Offline Service 형태로도 제공된다.

Customized Day Plans

  • Google Trips 에서 제공하는 기능 중 Software Engineer 에게 가장 흥미 있을 법한 기능이다. (240 년 된 알고리즘을 사용했다는 소문이..)
  • 테마별로 장소를 골라 하루에 갈 수 있는 코스를 짜주는 기능인데, 예를 들어 3일 여행이라고 치면 1일 차에는 어디, 어디, 2일 차에는 어디, 어디, 이런 식으로 쉽게 개략적인 루트를 확인할 수 있다.
  • 알고리즘이 아마 최단 거리나, 근접한 명소 들을 골라 테마별로 제공하는 것 같아. 굳이 이 일정대로 전부 따라가지 않아도, 어느 정도 갈만한 지역들과 명소들을 그룹핑 할 수 있는 좋은 기능이다.
  • 제공되는 루트 말고도, 직접 지도에서 표시되는 명소들을 골라 자기가 새로운 일정을 짤 수도 있다. 나는 이 기능을 이용하여, 2일 차에 한번 여행을 가보았는데, 전체적인 루트를 한 눈에 파악할 수 있고, 그걸 지도 위에서 쉽게 확인할 수 있어서 런던 시내의 지도 감각을 빠르게 익히는데 도움이 되었다.

Sightseeing the city

  • Google Trips 에서 제공하는 지도가 결국에는 Google Map 과 연계가 되는데, 보통 나는 여행할 때 로밍이나 USIM 을 쓰지 않는 편이라, 런던 시내를 자전거로 돌아다니는 과정에서 Offline Google Map 을 사용하였다.
  • 중간 중간 현재 위치만 확인할 수 있도록 GPS 를 잘 활용하면, 방향 감각이 조금 있는 사람들에게는 무리없이 런던 시내를 자전거로 활보 할 수 있을 것 같다.

Getting Around the city

  • 이 기능 역시 가는 비행기 안에서 읽으면 좋은 기능이다.
  • 가장 처음에 보이는 페이지에서는 공항에 도착해서 숙소나 도시로 어떻게 이동하는 방법인 여러가지 교통 수단에 대해 상세하게 적혀있다.
  • 그 다음부터는, 도시 내에서 어떻게 대중교통, 자전거, 자가용, 도보를 이용하여 이동할 수 있는지에 대해 상세하게 적혀 있어, 해당 도시에 대해 아무런 지식이 없을 때 가볍게 개념을 잡는데 도움이 된다.

유럽 배낭여행에서 느낀 Offline Web App 의 무한한 성장가능성

10월 한 달간 유럽 배낭여행을 하면서 느낀 Offline Service 에 대해서 생각을 정리해보았습니다.

  • 초당 10MB 가 넘는 데이터를 무리 없이 제공하는 한국에 있다 보니 자연스럽게 인터넷이 느린 사용자의 입장에서 생각을 하지 않고, 한국의 빠른 인터넷 속도 기준으로 어플리케이션을 제작해왔다.
  • Software 분야에서는 한국이 결코 후진국이라는 말이 있고, 나 또한 그렇게 믿고 있었지만, 내가 경험하고 본 유럽의 현황은 사실 우리나라 보다 더 뒤처져 있는 것 같았다.
  • 느린 통신사 data 망과 길거리에서 찾아보기 힘든 Public Wifi 는 현지인들이 지하철에서 핸드폰보다는 책이나 신문을 더 보게 하고, 관광지에 놀러 온 여행객들은 Google Trips 처럼 offline 에서도 작동하는 앱을 사용하기보다, 언제나 그래왔듯이 꾸준히 지도를 펼쳐가며 방향을 잡고 주민들에게 물어보며 장소를 찾아가는데 한 몫을 한다.
  • 물론, Google Trips 앱이 나온 지가 얼마 되지 않았고, 사람들에게는 Google Map 보다 관광 지도로 보는 것이 더 편하고 익숙하겠지만. 대다수를 위한 서비스를 하기 위해서는, 그 대다수가 선호하는 방식을 알고 있어야 하고, 그 패턴을 분석해서 보다 더 나은 서비스를 제공할 수 있는 통찰력이 필요하다는 생각이 들었다. 그리고 이러한 안목으로 서비스를 개발해 나가는 것이 세상을 더 편리하게 하는 Software Engineer 가 함양해야 할 자세가 아닐까?
  • 어플리케이션 성능을 최대한 최적화 해서 빠른 사용자 경험을 제공한다고 하더라도, 인터넷이 느린 국가에서는 사실 그렇게 의미가 많지 않은 작업이라고 생각이 든다. 그렇기 때문에 구글에서도 Progressive Web App 이라는 새로운 Web Application 개념으로, 보다 더 많은 사용자들이 Offline Service 로 혜택을 볼 수 있게끔, Web 기술을 발전시켜 나가고 있는 게 아닐까 라는 생각이 들었다.
  • Offline Web Service Era 가 도래할만한 충분한 배경과 현실이 있는 세상이다. Offline Service 부분에 좀 더 집중해서 나처럼 배낭 여행하는 여행객들과 현지인들이 편하게 여행하고, 지하철에서도 충분히 자기가 원하는 서비스들을 offline 으로 제공받는데 도움이 되었으면 좋겠다.

To be continued after this backpacking trip..

(번역) 웹 개발에서 img 태그 다루는 법

이 글은 Don’t ruin your 라는 미디엄 글을 번역한 것입니다.

서론

  • 개발자와 디자이너에게 있어서 최고의 사용자 경험을 제공하는 것은 가장 중요한 일입니다.
  • 더 나은 사용자 경험을 위해서 중요한 한 부분을 차지하는 것은 Image 인데요.
  • 대부분의 개발자들은 이런 이미지에 대해서 src 속성을 추가하는 것과 크기 조절하는 것 외에는 크게 신경쓰지 않습니다.
  • 이번 가이드에서는 이미지 사용에 있어 흔한 문제들을 살펴보고, 해결하는 방법에 대해서 알아보겠습니다.
  • 참고 : 이미지 사용에 있어서 대표적인 문제점들을 여기에 올려 두었습니다. 같은 이미지가 사용되었으니, 다른 유형들을 확인할 때 강력 새로고침으로 캐쉬를 비워주세요.

이미지 용량 줄이기 (Cut images down to size)

  • 웹 동작방식에 대해서 간단히 얘기 드리면,
    1. 웹 브라우저에 접속하면 HTML 페이지가 웹 브라우저로 전송됩니다.
    2. 브라우저는 이 HTML 페이지가 갖고 있는 모든 자원들(Javascript, stylesheet, images)을 다운받아야 합니다.
    3. 각 자원들을 로드하기 위해서는 시간이 소요되고, 파일이 클수록 이 시간이 길어집니다.
  • 우리는 종종 Javascript 파일을 압축하여 더 작은 파일로 만드는데요. Image 도 동일하게 해줘야 합니다.
  • 여기서 이미지의 쓸데없는 용량 낭비를 막는 방법 중 한 가지는 이미지의 픽셀 크기를 조절하는 것입니다. 이미지가 쓸데 없이 클 필요는 없으니까요.
  • 예를 들어, 당신이 사용하려는 웹사이트의 이미지가 960px 인데, 이미지 파일의 실제 너비는 1800px 이면 로딩시간이 필요이상으로 지체가 됩니다. 특히나, 느린 인터넷을 사용할 때는 이 고통이 더 극심해지죠.
  • 이미지의 실제 치수를 알 때에는 SketchAffinity Designer 를 이용하여 이미지 크기를 재 조정 할 수 있습니다.
  • 더 가시적인 사례로 예를 들어보겠습니다.

image_1
– 위 그림에서, 브라우저에서 사용할 이미지의 크기는 960px 인데, 여기서 사용되는 이미지 파일의 실제 너비는 5183px 입니다. 적절한 크기의 이미지를 사용하게 되면, 크기가 90% 감소 / 로딩시간은 6초 향상 됩니다. 이 도표는 사실 인터넷의 속도에 따라 천차만별이 됩니다. 느릴 인터넷 일수록 더 차이가 많이 날 것입니다.

이미지 압축 하기 (Use compression)

  • 이미지 치수를 줄여서 파일 크기를 줄일 수도 있지만, 압축을 이용해서 더 줄일 수 있습니다.
  • 이미지 압축은 이미지 파일의 크기를 줄이고, 이미지의 품질을 살짝 저하시킵니다.
  • 이미지 압축은 metadata, embedded thumbnails, color profiles 등의 불필요한 값들을 제거해줍니다.
  • 맥 사용자의 경우 ImageOptim 프로그램으로 이미지 압축을 할 수 있고, GruntGulp 같은 task runner 를 활용하여 프로젝트 빌드시에 이미지 압축을 자동화 할 수도 있습니다.
  • 아래 그림은 압축한 이미지로 크기를 13% 줄이는 모습입니다.

image_3
– 이 것도 역시 Wifi가 아닌 3G 와 같은 느린 인터넷에서는 더 많이 차이가 나겠죠?

미디어쿼리로 반응형 이미지 적용 (Use media queries to make images responsive)

  • 앞 두 단계에서 이미지 파일을 줄였지만, 나은 사용자 경험을 위해서 저희가 더 해야 할 일은 이미지를 반응형으로 만드는 것입니다.
  • 종종 반응형 이미지를 제공하지 않아, 사용자가 일일이 브라우저 스크롤을 왼쪽 오른쪽으로 움직여 이미지를 확인해야 하는 사이트가 있습니다. 이런 사이트는 사용자 비친화적인 사이트로 분류됩니다.
  • 미디어쿼리를 사용하여 브라우저가 특정 크기가 되면, max-width: 100% 와 같이 이미지 치수를 조절하세요.
  • 예제 를 보시면 반응형 이미지가 항상 브라우저의 크기에 맞춰지기 때문에 사용자가 이미지 확대나 축소를 할 필요가 없어집니다.

예술 감독한테 물어보세요 (Ask an art director)

  • 앞 단계들에서 축소한 이미지들은 대개 저희가 원하는 품질을 가지고 있지 않습니다.
  • 위 예제 에서 사용된 사진 속 뉴욕 엠파이어 스테이트 빌딩은 브라우저의 크기가 작아졌을 때, 거의 알아보기가 힘듭니다.
  • 이럴 때 picture 나 source 같은 HTML5 태그를 이용하여 이미지의 부분을 자르거나 변경합니다. 이를 예술 감독 이라고 합니다.
  • 위 태그는 사용된 미디어쿼리에 따라 브라우저에게 어떤 이미지를 요청하고 사용할 지를 알려줍니다.
  • 예제 를 확인해보시면, 브라우저 사이즈에 따라 다른 이미지를 요청하게 되는 걸 볼 수 있습니다.

서비스워커로 캐싱하기 (Use service workers to cash in on caching)

  • 반응형 디자인은 상대적으로 새로운 컨셉입니다. 어떤 디스플레이를 사용하든 웹사이트를 이쁘게 보이게 해야하죠.
  • 그런데, 요즘은 웹 사이트를 마치 Native Apps 처럼 느끼게 해주는 새로운 트렌드가 나왔습니다.
  • 이 트렌드를 Progressive Web Apps 이라고 하고, 인터넷 연결 없이도 웹사이트가 돌아가게 해주는 Service Worker 를 포함하고 있죠.
  • 이러한 PWA 가 이미지에게 의미하는 바는 뭘까요? 사이트 접속 시 자주 업데이트 되지 않는 로고나 기타 정적인 이미지는 캐쉬 되는 것이 성능 관점에서 효율적입니다. 캐쉬가 된 파일들은 Client 브라우저에 저장됩니다.
  • 캐쉬를 하게 되면, 이후에 사용자가 웹 사이트에 접속할 때 HTTP 요청을 날리기 전에 먼저 캐쉬를 확인합니다.
  • 보통 캐쉬를 활용하는 것이 HTTP 요청보다 더 빠르기 때문에, 로딩시간이 더 빨라집니다.
  • 그리고, 이미지를 캐쉬하였기 때문에 인터넷 연결 없이도 이미지를 사용할 수 있습니다.
  • Service Worker는 브라우저와 인터넷 사이의 Middleware 역할을 하는 강력한 기술 입니다.

접근성이 높은 이미지 만들기 (An accessible image is a friendly image)

  • <img /> 태그를 사용할 떄, alt 속성을 꼭 사용합니다.
  • 눈이 안보이는 시각 장애인 분들의 경우, 웹 페이지의 내용을 확인할 때. 스크린 리더 라는 도구를 활용합니다.
  • 이 도구는 이미지를 스캔할 때, alt 속성을 확인하죠. 따라서, alt 속성을 지정하지 않으면 이미지를 그냥 무시하고 지나갑니다.
  • 이런 이유로, 이미지에 alt 속성을 넣는 것은 시각 장애인 분들에게 친화적인 사이트가 됩니다.

결론

  • Service Worker 에 대해 더 알고 싶으시면 여기를 참고하세요!
  • 빠르고 사용자 친화적인 웹 사이트에 대해 더 알고 싶으면 이 책을 참고하세요.

(번역) 알고리즘 쉽게 이해하기 : 시간 복잡도와 Big-O 표기

(번역) 알고리즘을 쉬운 영어로 : 시간 복잡도와 Big-O 표기

오늘 번역글은 medium 의 freecodecamp 글입니다.
알고리즘, 시간 복잡도, Big-O 를 사례를 들어가며 이해하기 쉽게 풀어서 설명된 글입니다.
원문 의 모든 부분을 번역하지는 않습니다. 주요 부분만 발췌하여 번역합니다.

서론

  • 모든 개발자는 자신만의 시간 관념이 있습니다. 개발자들은 대부분의 시간을 사용자들에게 쏟아붓기 때문에, 최대한 시간을 효율적으로 사용하고 싶어하죠. 시간복잡도 를 최소화 함으로써 이게 실현가능해집니다.
  • 프로그래밍에서 시간복잡도를 이해하기 전에, 먼저 이 시간복잡도가 알고리즘에서 흔하게 활용된다는 사실을 기억해야합니다.

그래서 알고리즘은 뭔가요?

Algorithm is a series of contained steps which you follow in order to achieve some goal, or to produce some output

  • 알고리즘은 어떤 목적을 달성하거나 결과물을 만들어내기 위해 거쳐야 하는 일련의 과정들을 의미합니다.
  • 할머니가 케이크를 만드는 과정을 알고리즘으로 표현해보자면,
    function BakeCake(flavor, icing){
    /*
     1. Heat Oven to 350 F
     2. Mix flour, baking powder, salt
     3. Beat butter and sugar until fluffy
     4. Add eggs.
     5. Mix in flour, baking powder, salt
     6. Add milk and " + flavor + "
     7. Mix further
     8. Put in pan
     9. Bake for 30 minutes
    10." + if(icing === true) return 'add icing' + "
    10. Stuff your face
    */
    }
    BakeCake('vanilla', true) => deliciousness
    
  • 알고리즘은 각기 다른 모양과 형태를 지니고 있기에, 타임 복잡도를 설명하는데 자주 사용됩니다.

  • 애플파이 한 개를 100 가지 방법으로 자를 수 있는 것처럼, 한 문제를 여러가지의 알고리즘으로 풀 수 있습니다.
  • 시간복잡도를 분석 하는 것은 input n 에 대하여 알고리즘이 문제를 해결하는 데에 얼마나 오랜 시간이 걸리는 지를 분석하는 것 과 같습니다. 그리고 이는 Big-O 표기 를 이용하여 정의할 수 있습니다.

Big-O 표기란?

Big-O notation is a way of converting the overall steps of an algorithm into algebraic terms, then excluding lower order constants and coefficients that don’t have that big an impact on the overall complexity of the problem.

  • 개발자들에게는 위의 사전식 정의보다는 아래의 정의가 더 와닿을 겁니다.
    Regular       Big-O
    2             O(1)   --> It's just a constant number
    2n + 10       O(n)   --> n has the largest effect
    5n^2          O(n^2) --> n^2 has the largest effect
    
  • 이 예제가 의미하는 것은 다음과 같습니다. 시간복잡도에서 중요한 것은 정해진 표현식에 가장 큰 영향을 미치는 n 의 단위이다

  • 대표적인 시간 복잡도들을 간단하게 정의해봅니다.

    1. O(1) – 상수 시간 : 입력값 n 이 주어졌을 때, 알고리즘이 문제를 해결하는데 오직 한 단계만 거칩니다.
    2. O(log n) – 로그 시간 : 입력값 n 이 주어졌을 때, 문제를 해결하는데 필요한 단계들이 연산마다 특정 요인에 의해 줄어듭니다.
    3. O(n) – 직선적 시간 : 문제를 해결하기 위한 단계의 수와 입력값 n이 1:1 관계를 가집니다.
    4. O(n^2) – 2차 시간 : 문제를 해결하기 위한 단계의 수는 입력값 n의 제곱입니다.
    5. O(C^n) – 지수 시간 : 문제를 해결하기 위한 단계의 수는 주어진 상수값 C 의 n 제곱입니다.
  • 위 정의를 가지고 아래 예제의 시간복잡도를 계산해보겠습니다.
    var n = 16; -- 입력값 n 이 16일 때
    O (1) = 1 step "(awesome!)" -- O(1)는 시간복잡도가 1입니다.
    O (log n) = 4 steps  "(awesome!)" -- O(log n)는 시간복잡도가 4입니다. (log 의 밑이 2라고 가정)
    O (n) = 16 steps "(pretty good!)" -- O(n)는 시간복잡도가 16
    O(n^2) = 256 steps "(uhh..we can work with this?)" -- O(n^2)는 시간복잡도가 256
    O(2^n) = 65,536 steps "(...)"
    
  • 위와 같은 시간복잡도 계산을 코드에 적용해봅니다.
    // 아래와 같은 데이터 구조 기준으로 시간복잡도를 적용해봅니다.
    var friends = {
    'Mark' : true,
    'Amy' : true,
    'Carl' : false,
    'Ray' :  true,
    'Laura' : false,
    }
    var sortedAges = [22, 24, 27, 29, 31]
    

O(1) — Constant Time (상수 시간)

  • 값을 검색할 때, 객체에서 키를 알거나 배열에서 인덱스를 알고 있으면 언제나 한 단계만 걸립니다.
    //If I know the persons name, I only have to take one step to check:
    function isFriend(name){ //similar to knowing the index in an Array
    return friends[name];
    };
    isFriend('Mark') // returns True and only took one step
    function add(num1,num2){ // I have two numbers, takes one step to return the value
    return num1 + num2
    }
    

O(log n) — Logarithmic Time (로그 시간)

  • 배열에서 값을 찾을 때, 어느 쪽에서 시작할지를 알고 있으면 검색하는 시간이 두배로 줄어듭니다.
    //You decrease the amount of work you have to do with each step
    function thisOld(num, array){
    var midPoint = Math.floor( array.length /2 );
    if( array[midPoint] === num) return true;
    if( array[midPoint]  only look at second half of the array
    if( array[midpoint] > num ) --> only look at first half of the array
    //recursively repeat until you arrive at your solution
    
    }
    thisOld(29, sortedAges) // returns true
    //Notes
    //There are a bunch of other checks that should go into this example for it to be truly functional, but not necessary for this explanation.
    //This solution works because our Array is sorted
    //Recursive solutions are often logarithmic
    //We'll get into recursion in another post!
    

O(2^n) — Exponential Time (지수 시간)

  • 지수 시간은 보통 문제를 풀기 위해 모든 조합과 방법을 시도할 때 사용됩니다.
    //The number of steps it takes to accomplish a task is a constant to the n power
    //Thought example
    //Trying to find every combination of varters for a password of length n
    

마무리

it’s hard to say there is a single “right” or “best” answer to these problems. But it is possible to say there are “better” or “worse” answers to a given problem.

  • 문제를 해결하려고 할 때마다 시간복잡도를 분석하는 습관을 들이면 좋은 개발자가 될 수 있습니다.
  • 엔지니어에게 있어서, 문제라는 것은 정답이나 최선의 답의 관점에서 접근하는 것보다, 상황에 더 맞는 답인지 아닌지의 관점에서 접근해야 합니다.
  • 마지막으로 한번 더 요약합니다.
    1. O(1) – 상수 시간 : 알고리즘이 문제를 해결하는데 오직 한 단계만 거칩니다.
    2. O(log n) – 로그 시간 : 문제를 해결하는데 필요한 단계들이 연산마다 특정 요인에 의해 줄어듭니다.
    3. O(n) – 직선적 시간 : 문제를 해결하기 위한 단계의 수와 입력값 n이 1:1 관계를 가집니다.
    4. O(n^2) – 2차 시간 : 문제를 해결하기 위한 단계의 수는 입력값 n의 제곱입니다.
    5. O(C^n) – 지수 시간 : 문제를 해결하기 위한 단계의 수는 주어진 상수값 C 의 n 제곱입니다. (상당히 큰수가 됩니다)

(번역) CSS flex box 3분만에 배우기

이 글을 통해 CSS flexbox 레이아웃의 가장 중요하고 기본적인 컨셉을 배웁니다.

 

The container and the item

  • flex box 레이아웃에서 가장 중요한 컴포넌트 두 개는 container(파랑)items(빨강) 입니다.
  • 이 컴포넌트들을 이용하여 예제를 설명하겠습니다.

수평 레이아웃

  • container 에 아래와 같이 CSS 를 줍니다.
.container {
display: flex;
}
  • 위 결과는 아래와 같습니다.
flex-2
여기서 주의할 점은 items 는 전혀 손대지 않고도, 수평축을 따라 알아서 정렬됩니다.

 

수직 레이아웃

  • 위 이미지를 보면, 중심축은 수평축이고 교차축은 수직축입니다.
  • 아래처럼 flex-direction: column 을 추가하면 이 두 개의 축을 전환할 수 있습니다.
.container {
display: flex;
flex-direction: column;
}
flex-3
이제 중심축은 수직축이고, 교차축이 수평입니다. 따라서 위처럼 items 가 수직으로 정렬되어 쌓입니다.

 

Justify content and Align items

  • items 을 다시 수평으로 만들려면, flex-directioncolumn 에서 row 로 바꾸면 됩니다.
  • 축을 이해해야하는 중요한 이유는 justify-contentalign-items 와 같은 속성들은, 중심축과 교차축에 기준하여 items 을 정렬하기 때문입니다.
  • justify-content 를 이용하여 items 들을 중심축의 중앙에 정렬해봅니다.
.container {
display: flex;
flex-direction: row;
justify-content: center;
}

flex-4

  • 이제, align-items 를 이용하여 교차축의 중앙에 정렬해봅니다.
.container {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}

flex-5

  • justify-contentalign-items 의 속성 값은 아래와 같습니다.

justify-content:

  • flex-start(default)
  • flex-end
  • center
  • space-between
  • space-around

align-items:

  • flex-start(default)
  • flex-end
  • center
  • baseline
  • stretch

Items

  • 축에 따른 전체적인 정렬 말고도, 각각의 아이템에 CSS 효과를 줄 수 있습니다.
  • 아래는 align-self 속성을 이용하여 첫 번째 item 의 위치를 조정한 것입니다.
.item1 {
align-self: flex-end;
}
/* align-self 는 align-item 속성과 같은 옵션 값들을 가집니다. */

flex-6

Conclusion

  • 위의 3가지 컨셉이 CSS flex-box 를 이해하는데 있어 가장 중요하고 응용하는데 사용된다.
  • 이 글의 원문은 여기를 참고하세요.