반복문 - Web 개발 학습하기

반복문
===

* 이전
* Overview: Building blocks
* 다음

다수의 기본적인 계산에서부터 완료해야 할 비슷한 작업들을 가지고 있는 상황들에 대해서까지, 프로그래밍 언어는 반복적인 작업을 빠르게 완료하는 데 대단히 유용합니다. 여기서 우리는 그러한 필요를 다루는 JavaScript에서 이용 가능한 반복문 구조를 살펴볼 것입니다.

|  |  |
| --- | --- |
| 필요한 사전 지식: |
 기본적인 컴퓨터 활용 능력, HTML과 CSS,
 JavaScript 첫걸음.
  |
| 목표: | JavaScript에서 반복문(loop)을 사용하는 방법을 이해합니다. |

저를 반복 속에 계속 잡아 두세요
------------------

반복, 반복, 반복(loop). 인기있는 아침 시리얼, 롤러 코스터 그리고 음악 제작과 연관되어 있는 것처럼, 반복은 또한 프로그래밍에서 중요한 개념입니다. 프로그래밍의 반복은 같은 것을 계속 그리고 계속 반복해서 하는 것에 모든 관계가 있는데, 이는 프로그래밍 언어에서 **반복**(iteration)이라고 일컫어집니다.

가족들이 일주일동안 먹을 식량이 충분한지 확신하기 위해 고민하는 농부의 상황을 봅시다. 그는 이것을 알기 위해 다음과 같은 반복을 사용할지도 모릅니다:

![](/ko/docs/Learn/JavaScript/Building_blocks/Looping_code/loop_js-02-farm.png)

반복은 보통 다음 기능의 하나 또는 그 이상을 가집니다:

* **카운터**(counter). 이는 어떤 값으로 초기화됩니다 — 이것이 반복문의 시작점입니다 (상기의 그림에서, "시작: I have no food").
* **조건**(condition). 이는 반복문이 계속 실행될지, 혹은 멈출지를 결정하는 true/false 테스트입니다 — 보통 카운터가 어떤 값에 도달했을 때입니다. 이것은 상기 그림의 "Have I got enough food?" 부분에 나와 있습니다. 그가 가족에게 먹일 10인분의 음식이 필요하다고 해 봅시다.
* **반복자**(iterator). 이는 보통 조건이 더 이상 true가 아닐 때까지 각각의 연이은 반복에서 조금씩 카운터를 증가시킵니다. 우리는 위의 그림에서 명시적으로 이를 보이지 않았지만, 농부가 시간당 2인분의 음식을 수집한다고 생각해 볼 수 있습니다. 매 시간 후마다, 그가 모은 음식의 양은 2인분씩 증가되고, 그는 충분한 음식을 가지고 있는지 확인합니다. 만약 그가 10인분에 도달했다면 (조건이 더 이상 참이 아닌 지점, 따라서 반복은 종료됩니다), 그는 수집을 멈추고 집에 갈 수 있습니다.

의사 코드(pseudocode)에서 이것은 다음과 같이 보일 것입니다:
```

loop(food = 0; foodNeeded = 10) {
  if (food = foodNeeded) {
    exit loop;
    // 우리는 충분한 음식을 가지고 있다; 집에 돌아가자
  } else {
    food += 2; // 2인분을 더 모으기 위해 1시간을 소모한다
    // 그리고 반복문은 다시 실행될 것입니다
  }
}
```

따라서 필요한 음식의 양은 10으로 설정되어 있고, 현재 농부가 소지하고 있는 양은 0으로 설정되어 있습니다. 반복문의 각 반복에서, 우리는 농부가 가진 음식의 양이 그가 필요한 양보다 크거나 같은지 확인합니다. 만약 그렇다면, 우리는 반복문을 종료(exit)할 수 있습니다. 만약 그렇지 않다면, 농부는 2인분의 음식을 모으기 위해 한 시간을 보내고 반복문은 다시 실행됩니다.

### 왜 굳이?

이 시점에서, 여러분은 아마도 반복문 뒤에 있는 고급 개념을 이해했을 것이지만, 여러분은 아마도 "좋아, 훌륭하군, 하지만 어떻게 이게 내가 JavaScript 코드를 더 잘 짜게 도와준다는 거지?" 라고 생각할 것입니다. 앞서 말했듯이, **반복문은 같은 것을 계속 그리고 계속 다시 하는 것에 모든 관련이 있는데**, 이는 **빠르게 반복적인 일을 완료**하는 데 뛰어납니다.

종종, 코드는 반복문의 각각의 연이은 반복에서 조금 다를 것인데, 이는 여러분이 비슷하지만 조금 다른 일더미를 완료할 수 있다는 것을 의미합니다; 만약 여러분이 수행할 많은 다른 계산들을 가지고 있다면, 여러분은 같은 것을 계속 그리고 계속 하는 것이 아니라, 각각의 다른 것을 하기를 원할 것입니다.

왜 반복문이 그렇게 좋은 것인지를 완벽히 보여주는 예제를 봅시다. 우리가 `<canvas>` 요소 위에 무작위의 원 100개를 그리고 싶다고 칩시다 (예제를 다시 실행하고, 다시 다른 무작위 집합들을 보기 위해 *Update*버튼을 누르세요):
```

<!doctype html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Random canvas circles</title>
    <style>
 html {
 width: 100%;
 height: inherit;
 background: #ddd;
 }

 canvas {
 display: block;
 }

 body {
 margin: 0;
 }

 button {
 position: absolute;
 top: 5px;
 left: 5px;
 }
 </style>
  </head>
  <body>
    <button>Update</button>

    <canvas></canvas>

    <script>
 const btn = document.querySelector("button");
 const canvas = document.querySelector("canvas");
 const ctx = canvas.getContext("2d");

 let WIDTH = document.documentElement.clientWidth;
 let HEIGHT = document.documentElement.clientHeight;

 canvas.width = WIDTH;
 canvas.height = HEIGHT;

 function random(number) {
 return Math.floor(Math.random() \* number);
 }

 function draw() {
 ctx.clearRect(0, 0, WIDTH, HEIGHT);
 for (let i = 0; i < 100; i++) {
 ctx.beginPath();
 ctx.fillStyle = "rgba(255,0,0,0.5)";
 ctx.arc(random(WIDTH), random(HEIGHT), random(50), 0, 2 \* Math.PI);
 ctx.fill();
 }
 }

 btn.addEventListener("click", draw);
 </script>
  </body>
</html>
```

지금 당장은 모든 코드를 이해할 필요는 없지만, 실제로 100개의 원을 그리는 코드 부분을 살펴봅시다:

```js
for (let i = 0; i < 100; i++) {
  ctx.beginPath();
  ctx.fillStyle = "rgba(255,0,0,0.5)";
  ctx.arc(random(WIDTH), random(HEIGHT), random(50), 0, 2 \* Math.PI);
  ctx.fill();
}
```

* 코드의 앞부분에서 정의한 `random()`은, `0`과 `x-1`사이의 정수를 반환합니다.
* `WIDTH`와 `HEIGHT` 는 내부 브라우저 윈도우의 너비와 높이입니다.

기본 개념을 잡아야만 합니다 — 우리는 이 코드의 100번의 반복(iteration)을 실행하기 위해 반복문을 사용하고 있는데, 각 반복은 페이지의 무작위의 위치에 원을 그립니다. 우리가 100개의 원을 그리든, 1000개의 원을 그리든, 혹은 10,000개의 원을 그리든 간에 필요한 코드의 양은 같을 것입니다. 오직 숫자 하나만 바뀌면 됩니다.

만약 우리가 여기서 반복문을 사용하지 않았다면, 우리가 그리고 싶은 모든 원에 대해 다음의 코드를 반복해야만 했을 것입니다:

```js
ctx.beginPath();
ctx.fillStyle = "rgba(255,0,0,0.5)";
ctx.arc(random(WIDTH), random(HEIGHT), random(50), 0, 2 \* Math.PI);
ctx.fill();
```

이것은 몹시 지루하고 아주 빠르게 유지보수하기 힘들 것입니다. 반복문은 정말로 최고입니다.

반복문의 표준
-------

몇몇 특정한 반복문 구조 탐구를 시작해 봅시다. 여러분이 대부분의 경우에 사용하게 될, 첫번째는 for 반복문입니다. 이것은 다음의 문법(syntax)을 가지고 있습니다:
```

for (초기화식; 종료 조건; 증감식) {
  // 실행할 코드
}
```

여기서 우리가 알 수 있는 것:

1. 괄호가 뒤따라오는 키워드 `for`.
2. 괄호 안에는, 세미콜론으로 구분되는, 세개의 항목이 있습니다:
    1. **초기화식**(initializer) — 이것은 보통 숫자로 설정된 변수인데, 반복문이 실행될 횟수(count)까지 증가됩니다. 이것은 또한 때때로 **카운터 변수**(counter variable)라고도 불립니다.
    2. **조건식**(condition) — 전에 언급했듯이, 이것은 언제 반복문이 반복을 멈춰야만 하는지를 정의합니다. 이것은 일반적으로 비교 연산자(comparison operator)를 특징으로 하는 표현식(expression)인데, 이는 종료 조건이 충족되었는지를 확인하는 테스트입니다.
    3. **증감식**(final-expression) — 이것은 반복문이 전체 반복을 거쳤을 때마다 항상 평가(혹은 실행)됩니다. 이것은 보통 카운터 변수를 증가 (혹은 몇몇 경우에는 감소)시키기 위해, 조건이 더 이상 `true`가 아닌 지점에 가까워지게 하기 위해 제공됩니다.
3. 코드 블럭을 감싸는 중괄호 — 이 코드는 반복문이 반복될 때마다 실행될 것입니다.

이것들이 무엇을 하는지를 더욱 확실하게 시각화할 수 있도록 실제 예제를 봅시다.

```js
const cats = ["Bill", "Jeff", "Pete", "Biggles", "Jasmin"];
let info = "My cats are called ";
const para = document.querySelector("p");

for (let i = 0; i < cats.length; i++) {
  info += cats[i] + ", ";
}

para.textContent = info;
```

이것은 우리에게 다음의 결과를 보여줍니다:
```

<!doctype html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Basic for loop example</title>
    <style></style>
  </head>
  <body>
    <p></p>

    <script>
 const cats = ["Bill", "Jeff", "Pete", "Biggles", "Jasmin"];
 let info = "My cats are called ";
 const para = document.querySelector("p");

 for (let i = 0; i < cats.length; i++) {
 info += cats[i] + ", ";
 }

 para.textContent = info;
 </script>
  </body>
</html>
```

**참고:** 여러분은 이 예제를 GitHub에서 또한 찾을 수 있습니다 (또한 실제로 작동하는 모습도 볼 수 있습니다).

이것은 반복문이 배열 안의 요소들에 대해 반복하고 그 각각의 요소들과 무언가를 하기 위해 쓰였다는 것을 보여줍니다 — 이것은 JavaScript에서 아주 일반적인 패턴입니다. 여기서:

1. 카운터 변수 (때때로 초기화식(initializer) 또는 반복 변수(iteration variable)으로도 알려져 있음) `i`는 `0`에서 시작합니다 (`let i = 0`).
2. 반복문은 `i`가 더 이상 `cats` 배열의 길이(length)보다 작지 않을 때까지 실행되라는 명령을 받았습니다. 이것은 중요합니다 — 조건은 반복문이 여전히 실행되는 것 아래의 조건입니다. 그래서 이 경우, `i < cats.length`가 여전히 true인 동안, 반복문은 계속 실행될 것입니다.
3. 반복문 안에서, 우리는 콤마와 공백(space)과 같이 있는 현재 반복 요소(item) (`cats[이 때 i가 무엇이든]`인, `cats[i]`)를 `info` 변수의 끝에 연결시킵니다. 그래서:
    1. 첫번째 실행 동안에, `i = 0`이므로, `cats[0] + ', '` (이는 `Bill,`과 같습니다)는 `info`에 연결될 것입니다.
    2. 두번째 실행 동안에, `i = 1`이므로, `cats[1] + ', '` (이는 `Jeff,`와 같습니다)는 `info`에 연결될 것입니다.
    3. 계속 이와 같습니다. 반복문이 실행 된 후마다, `i`에 1이 더해질 것이고 (`i++`), 이 과정(process)은 다시 실행될 것입니다.
4. `i`가 `cats.length`와 같아질 때 (이 경우, 5), 반복문은 멈출 것이고, 브라우저는 반복문 아래에 있는 다음 코드로 이동할 것입니다.

**참고:** 우리는 조건을 `i <= cats.length`이 아니라 `i < cats.length`로 만들었는데, 이는 컴퓨터는 카운트를 1부터가 아니라 0부터 세기 때문입니다 — 우리는 `i`를 0에서 시작했고, `i = 4`까지 갔습니다 (마지막 배열 원소의 인덱스). 배열에 5개의 원소가 있으므로, `cats.length`는 5를 반환하지만, 우리는 `i = 5`까지 가고 싶지는 않습니다. 왜냐하면 이는 마지막 원소에 대해 `undefined`를 반환할 것이기 때문입니다 (5의 인덱스를 가진 배열 원소는 없습니다). 그래서, 그러므로, 우리는 `cats.length`과 같은 데까지가 아니라 (`i <=`), `cats.length`보다 1 작은 데까지 가기를 원합니다 (`i <`).

**참고:** 조건에 관련된 일반적인 실수는 "보다 작거나 같다(less than or equal to)" (`<=`)가 아니라 "동등(equal to)" (`===`)을 사용하는 것입니다. 만약 우리가 반복문을 `i = 5`까지 실행하기를 원했다면, 종료 조건은 `i <= cats.length`일 필요가 있었을 것입니다. 만약 우리가 그것을 `i === cats.length`에 설정했다면, 첫 반복문 반복에서 `i`는 `5`와 같지 않아서, 반복문은 즉시 멈췄을 것이기 때문에 반복문은 전혀 실행되지 않을 것입니다.

우리는 마지막으로 출력되는 문장이 잘 만들어지지 않았다는 작은 문제를 가지고 있습니다:

>
> My cats are called Bill, Jeff, Pete, Biggles, Jasmin,
>
>
>

이상적으로, 우리는 문장의 끝에 콤마를 가지지 않도록 마지막 반복문 반복에서 연결을 변경하기를 원합니다. 좋습니다, 문제 없어요 — 우리는 꽤 행복하게 반복문이 이 특별한 경우를 다루도록 조건문을 내부에 삽입할 수 있습니다:

```js
for (let i = 0; i < cats.length; i++) {
  if (i === cats.length - 1) {
    info += "and " + cats[i] + ".";
  } else {
    info += cats[i] + ", ";
  }
}
```

**참고:** 여러분은 이 예제 코드를 Github에서 또한 찾아볼 수 있습니다 (또한 실제로 작동하는 모습도 볼 수 있습니다).

**경고:** **중요**: 모든 반복문과 마찬가지로 — for 문에서, 초기화식(initializer)이 결국 조건이 true가 아닌 지점에 닿도록, 경우에 따라, 증가되거나 혹은 감소되게 해야만 합니다. 만약 그렇지 않다면, 반복문은 영원히 계속될 것이고, 브라우저가 강제로 멈추게 하거나, 브라우저가 멈출(crash) 것입니다. 이것은 **무한 루프**(infinite loop)라고 불립니다.

break로 반복문 종료하기
---------------

만약 여러분이 모든 반복이 완료되기 전에 반복문을 종료하고 싶다면, 여러분은 break문을 사용할 수 있습니다. 우리는 이미 이것을 지난 문서에서 switch문을 살펴볼 때 만났습니다 — 입력 표현식과 일치하는 switch문에서 case가 충족되었을 때, `break`문은 즉시 switch문을 종료하고 switch문 다음에 있는 코드로 이동합니다.

이것은 반복문과 같은 것입니다 — `break`문은 즉시 반복문을 종료하고 브라우저가 반복문 뒤에 있는 코드로 이동하게 합니다.

우리가 연락처와 핸드폰 번호의 배열을 탐색하고 우리가 원하는 바로 그 번호를 반환하고 싶다고 합시다. 첫째로, 간단한 HTML — 찾고자 하는 이름을 입력할 수 있게 해 주는 텍스트 `<input>` (en-US), 검색을 제출할 `<button>` 요소, 그리고 결과를 표시할 `<p>` 요소:

```html
<label for="search">Search by contact name: </label>
<input id="search" type="text" />
<button>Search</button>

<p></p>
```

이제 JavaScript를 봅시다:

```js
const contacts = [
  "Chris:2232322",
  "Sarah:3453456",
  "Bill:7654322",
  "Mary:9998769",
  "Dianne:9384975",
];
const para = document.querySelector("p");
const input = document.querySelector("input");
const btn = document.querySelector("button");

btn.addEventListener("click", function () {
  let searchName = input.value;
  input.value = "";
  input.focus();
  for (let i = 0; i < contacts.length; i++) {
    let splitContact = contacts[i].split(":");
    if (splitContact[0] === searchName) {
      para.textContent =
        splitContact[0] + "'s number is " + splitContact[1] + ".";
      break;
    } else {
      para.textContent = "Contact not found.";
    }
  }
});
```

```
<!doctype html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Simple contact search example</title>
    <style></style>
  </head>
  <body>
    <label for="search">Search by contact name: </label>
    <input id="search" type="text" />
    <button>Search</button>

    <p></p>

    <script>
 const contacts = [
 "Chris:2232322",
 "Sarah:3453456",
 "Bill:7654322",
 "Mary:9998769",
 "Dianne:9384975",
 ];
 const para = document.querySelector("p");
 const input = document.querySelector("input");
 const btn = document.querySelector("button");

 btn.addEventListener("click", function () {
 let searchName = input.value;
 input.value = "";
 input.focus();
 for (let i = 0; i < contacts.length; i++) {
 let splitContact = contacts[i].split(":");
 if (splitContact[0] === searchName) {
 para.textContent =
 splitContact[0] + "'s number is " + splitContact[1] + ".";
 break;
 } else if (i === contacts.length - 1)
 para.textContent = "Contact not found.";
 }
 });
 </script>
  </body>
</html>
```

1. 우선 우리는 몇 가지 변수 정의를 합니다 — 우리는 콜론으로 분리된 이름과 핸드폰 번호를 포함하고 있는 각각의 문자열 요소를 가지고 있는, 연락처 정보의 배열을 가지고 있습니다.
2. 다음으로, 버튼이 눌렸을 때 검색을 수행하고 결과를 반환하기 위해 코드가 실행되도록 버튼(`btn`)에 이벤트 리스너를 붙입니다.
3. 다음 검색의 준비를 위해, 텍스트 인풋을 비우고 그것을 다시 포커싱하기 전에, 우리는 `searchName` 변수에 텍스트 인풋에 입력된 값을 저장합니다. 검색이 대소문자 구분이 없도록(case-insensitive) 우리가 또한 `toLowerCase()`메서드를 문자열에 실행했다는 것에 주목하세요.
4. 이제 for 반복문의 흥미로운 점을 봅시다:
    1. 우리는 `0`에서 카운터를 시작하고, 카운터가 `contacts.length`보다 더 이상 작지 않을 때까지 반복문을 실행시키고, 그리고 `i`를 반복문의 각 반복 후마다 1씩 증가시킵니다.
    2. 반복문 내부에서, 우리는 첫째로 현재 연락처 (`contacts[i]`)를 콜론 문자에서 나누고(split), 결과인 두 값을 `splitContact` 배열에 저장했습니다.
    3. 그리고서 우리는 `splitContact[0]` (연락처의 이름, 다시 얘기하자면 `toLowerCase()`로 소문자화(lower-cased)된)이, 입력된 `searchName`과 같은지를 검사하는 조건문을 사용했습니다. 만약 그렇다면, 우리는 연락처의 번호가 무엇인지를 알리는 문자열을 문단에 입력하고, 반복문을 끝내기 위해 `break`을 사용합니다.
5. `(contacts.length-1)` 반복 후에, 만약 연락처 이름이 입력된 검색과 일치하지 않으면 문단 텍스트는 "Contact not found."로 설정되고, 반복문은 조건이 더 이상 true가 아닐 때까지 반복을 계속합니다.

**참고:** 참고: 여러분은 전체 소스 코드를 GitHub에서 또한 볼 수 있습니다 (또한 실제로 작동하는 모습도 볼 수 있습니다).

Continue로 반복 건너뛰기
-----------------

continue문은 `break`와 유사한 방식으로 작동하지만, 반복문을 완전히 탈출하는 대신, 이것은 반복문의 다음 반복으로 건너뜁니다. 숫자를 입력으로 취하고, 오직 정수의 제곱인 수만을 반환하는 다른 예제를 봅시다.

HTML은 기본적으로 지난 예제와 같습니다 — 간단한 텍스트 입력, 그리고 출력을 위한 문단. JavaScript는 대부분 또한 같지만, 반복문 자체는 약간 다릅니다:

```js
let num = input.value;

for (let i = 1; i <= num; i++) {
  let sqRoot = Math.sqrt(i);
  if (Math.floor(sqRoot) !== sqRoot) {
    continue;
  }

  para.textContent += i + " ";
}
```

여기 출력이 있습니다:
```

<!doctype html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Integer squares generator</title>
    <style></style>
  </head>
  <body>
    <label for="number">Enter number: </label>
    <input id="number" type="text" />
    <button>Generate integer squares</button>

    <p>Output:</p>

    <script>
 const para = document.querySelector("p");
 const input = document.querySelector("input");
 const btn = document.querySelector("button");

 btn.addEventListener("click", function () {
 para.textContent = "Output: ";
 let num = input.value;
 input.value = "";
 input.focus();
 for (let i = 1; i <= num; i++) {
 let sqRoot = Math.sqrt(i);
 if (Math.floor(sqRoot) !== sqRoot) {
 continue;
 }

 para.textContent += i + " ";
 }
 });
 </script>
  </body>
</html>
```

1. 이 경우에, 입력은 반드시 숫자 (`num`)여야 합니다. `for` 반복문은 1에서 시작하는 카운터 (우리는 이 경우에서 0에 관심이 없으니까요), 카운터가 입력 `num`보다 더 크게 되었을 때 반복문이 멈춘다고 말하는 종료 조건, 그리고 매번 카운터에 1을 더하는 반복자가 주어져 있습니다.
2. 반복문 안에서, 우리는 Math.sqrt(i)를 사용하여 각 숫자의 제곱근을 찾고, 이 제곱근이 가장 가까운 정수로 내림되었을 때 (이것이 Math.floor()가 전달된 숫자에게 하는 일입니다) 그 자신과 같은지를 검사함으로써 정수인지 확인합니다.
3. 만약 제곱근과 내림된 제곱근이 서로 같지 않다면 (`!==`), 이것은 제곱근이 정수가 아니라는 것을 의미하므로, 우리는 이것에 관심이 없습니다. 그러한 경우에, 우리는 숫자를 어디에도 기록하는 일 없이 다음 반복문 반복으로 건너뛰기 위해 `continue`문을 사용합니다.
4. 만약 제곱근이 정수라면, 우리는 `continue`문이 실행되지 않도록 지난 `if`블록을 완전히 건너뜁니다; 대신, 우리는 현재 `i`값 + 공백을 단락 콘텐츠의 끝에 연결합니다.

**참고:** 여러분은 전체 소스 코드를 GitHub에서 또한 볼 수 있습니다 (또한 실제로 작동하는 모습도 볼 수 있습니다).

while 그리고 do ... while
----------------------

`for` 는 JavaScript에서 사용할 수 있는 유일한 유형의 반복문이 아닙니다. 실제로 많은 다른 것들이 있고, 지금 이 모든 것을 이해할 필요는 없는 반면 여러분이 약간 다른 방식으로 작업에서 같은 기능을 인식할 수 있도록 다른 두 개의 구조를 살펴 볼 가치가 있습니다.

먼저 while 반복문을 살펴봅시다. 이 반복문의 구문은 다음과 같습니다:
```

초기화식
while (종료 조건) {
  // 실행할 코드

  증감식
}
```

초기화식 변수와 증감식이 괄호 안에 포함되어 있는 것이 아니라, 초기화식 변수가 반복문 전에 설정되어 있다는 것과, 증감식이 반복문 안에 실행할 코드 후에 포함되어 있다는 것을 제외하고, 이것은 `for` 반복문과 아주 비슷한 방식으로 작동합니다. 조건은 괄호 안에 포함되어 있고, `for` 대신 `while` 키워드가 앞에 옵니다.

같은 세 가지 요소가 여전히 존재하고, 이것들은 for 반복문에서처럼 여전히 같은 순서로 정의되어 있습니다. 여전히 카운터 변수가 조건이 더 이상 true가 아닌 지점에 도달했는지를 확인하기 전에 정의된 초기화식을 가지고 있어야만 하므로 이것은 말이 됩니다. 반복문 안의 코드가 실행된 이후에 증감식은 그리고서 실행되는데 (반복은 완료되었습니다), 이는 오직 조건이 여전히 참인 경우에만 일어납니다.

고양이 목록 예제를 다시 봐 봅시다. 하지만 while 반복문을 사용하기 위해 재작성되었습니다:

```js
let i = 0;

while (i < cats.length) {
  if (i === cats.length - 1) {
    info += "and " + cats[i] + ".";
  } else {
    info += cats[i] + ", ";
  }

  i++;
}
```

**참고:** 예상한 대로 이것은 여전히 똑같이 동작합니다 — 여기서 한 번 봐 보세요 running live on GitHub (또한 전체 소스 코드도 보세요).

do...while 반복문은 많이 비슷하지만 while 구조에 변형을 제공합니다:
```

초기화식
do {
  // 실행할 코드

  증감식
} while (종료 조건)
```

이 경우, 반복문이 시작하기 전에, 초기화식은 다시 첫번째로 옵니다. 키워드는 곧장 실행할 코드와 증감식을 포함하는 중괄호의 앞에 있습니다.

여기서 차별화 요소는 조건이 모든 것 뒤에 오는데, 괄호에 감싸져 있고 `while` 키워드가 앞에 있다는 점입니다. `do...while` 반복문에서, 중괄호 안의 코드는 이것이 다시 실행되어야 하는지를 보기 위해 확인이 만들어지기 전에 항상 한 번은 실행됩니다 (while과 for에서는, 확인이 먼저 와서, 코드는 혹시라도 절대로 실행될 일이 없습니다).

`do...while`을 사용하기 위해 고양이 목록 예제를 다시 작성해 봅시다:

```js
let i = 0;

do {
  if (i === cats.length - 1) {
    info += "and " + cats[i] + ".";
  } else {
    info += cats[i] + ", ";
  }

  i++;
} while (i < cats.length);
```

**참고:** 다시 말하지만, 이것은 예상한 바와 같이 똑같이 동작합니다 — 한 번 봐 보세요 running live on GitHub (또한 전체 소스 코드도 보세요).

**경고:** **중요**: 모든 반복문과 마찬가지로 — while과 do...while문에서, 조건이 결국 false가 되도록, 경우에 따라, 초기화식이 증가되거나 감소되게 해야만 합니다.만약 그렇지 않다면, 반복문은 영원히 계속될 것이고, 브라우저가 강제로 멈추게 하거나, 브라우저가 멈출(crash) 것입니다. 이것은 **무한 루프**(infinite loop)라고 불립니다.

직접 해보기: 카운트 다운 시작!
------------------

이 연습에서, 우리는 여러분이 간단한 발사 카운트다운을, 10에서 발사까지, 출력 박스에 출력하기를 원합니다. 구체적으로 말하면, 우리는 여러분이 다음을 하기를 원합니다:

* 10에서 0까지 반복하세요. 우리는 여러분에게 초기화식을 제공합니다 — `let i = 10;`.
* 각 반복마다, 새로운 단락을 만들고, 우리가 `const output = document.querySelector('.output');`를 사용해 선택한, 출력 `<div>`에 추가하세요. 주석에, 우리는 여러분에게 반복문 내부 어딘가에서 사용될 필요가 있는 세 줄의 코드를 제공합니다.
    + `const para = document.createElement('p');` — 새로운 단락을 만듭니다.
    + `output.appendChild(para);` — 단락을 출력 `<div>`에 추가합니다.
    + `para.textContent =` — 등호 기호 이후에, 우항(right-hand side)에 여러분이 입력한 것과 같은 텍스트를 단락 내부에 만듭니다.
* 다른 반복 숫자는 그 반복에 대한 단락에 입력될 다른 텍스트를 요구합니다 (여러분은 조건문과 다수의 `para.textContent =` 줄이 필요할 것입니다):
    + 만약 숫자가 10이면, 단락에 "Countdown 10"을 출력하세요.
    + 만약 숫자가 0이면, "Blast off!"를 단락에 출력하세요.
    + 다른 숫자에 대해서는, 단지 단락에 그 숫자를 출력하세요.
* 반복자를 포함하는 것을 잊지 마세요! 그러나, 이 예제에서는 우리는 각 반복마다 카운트를 위가 아니라 아래로 셉니다. 그러니 여러분은 `i++`를 원하지 **않을** 것입니다 — 어떻게 아래로 반복하실 건가요?

**참고:** 만약 여러분이 반복문을 타이핑하기 시작했다면 (예를 들어 (while(i>=0)), 아직 종료 조건을 입력하지 않았기 때문에 브라우저는 멈출(stuck) 지도 모릅니다. 그러니 조심하세요. 이 문제에 대처하기 위해 코드를 주석에 작성하고, 완성한 이후에 주석을 제거할 수 있습니다.

만약 실수했다면, 언제나 예제를 "Reset" 버튼으로 리셋할 수 있습니다. 만약 정말로 막혔다면, 답을 보기 위해 "Show solution"을 누르세요.

###### Active learning
```

<h2>Live output</h2>
<div class="output" style="height: 410px;overflow: auto;"></div>

<h2>Editable code</h2>
<p class="a11y-label">
  Press Esc to move focus away from the code area (Tab inserts a tab character).
</p>
<textarea id="code" class="playable-code" style="height: 300px;width: 95%">
var output = document.querySelector('.output');
output.innerHTML = '';

// var i = 10;

// var para = document.createElement('p');
// para.textContent = ;
// output.appendChild(para);
</textarea>

<div class="playable-buttons">
  <input id="reset" type="button" value="Reset" />
  <input id="solution" type="button" value="Show solution" />
</div>
```

```
html {
  font-family: sans-serif;
}

h2 {
  font-size: 16px;
}

.a11y-label {
  margin: 0;
  text-align: right;
  font-size: 0.7rem;
  width: 98%;
}

body {
  margin: 10px;
  background: #f5f9fa;
}
```

```
var textarea = document.getElementById("code");
var reset = document.getElementById("reset");
var solution = document.getElementById("solution");
var code = textarea.value;
var userEntry = textarea.value;

function updateCode() {
  eval(textarea.value);
}

reset.addEventListener("click", function () {
  textarea.value = code;
  userEntry = textarea.value;
  solutionEntry = jsSolution;
  solution.value = "Show solution";
  updateCode();
});

solution.addEventListener("click", function () {
  if (solution.value === "Show solution") {
    textarea.value = solutionEntry;
    solution.value = "Hide solution";
  } else {
    textarea.value = userEntry;
    solution.value = "Show solution";
  }
  updateCode();
});

var jsSolution =
  "var output = document.querySelector('.output');\noutput.innerHTML = '';\n\nvar i = 10;\n\nwhile(i >= 0) {\n var para = document.createElement('p');\n if(i === 10) {\n para.textContent = 'Countdown ' + i;\n } else if(i === 0) {\n para.textContent = 'Blast off!';\n } else {\n para.textContent = i;\n }\n\n output.appendChild(para);\n\n i--;\n}";
var solutionEntry = jsSolution;

textarea.addEventListener("input", updateCode);
window.addEventListener("load", updateCode);

// stop tab key tabbing out of textarea and
// make it write a tab at the caret position instead

textarea.onkeydown = function (e) {
  if (e.keyCode === 9) {
    e.preventDefault();
    insertAtCaret("\t");
  }

  if (e.keyCode === 27) {
    textarea.blur();
  }
};

function insertAtCaret(text) {
  var scrollPos = textarea.scrollTop;
  var caretPos = textarea.selectionStart;

  var front = textarea.value.substring(0, caretPos);
  var back = textarea.value.substring(
    textarea.selectionEnd,
    textarea.value.length,
  );
  textarea.value = front + text + back;
  caretPos = caretPos + text.length;
  textarea.selectionStart = caretPos;
  textarea.selectionEnd = caretPos;
  textarea.focus();
  textarea.scrollTop = scrollPos;
}

// Update the saved userCode every time the user updates the text area code

textarea.onkeyup = function () {
  // We only want to save the state when the user code is being shown,
  // not the solution, so that solution is not saved over the user code
  if (solution.value === "Show solution") {
    userEntry = textarea.value;
  } else {
    solutionEntry = textarea.value;
  }

  updateCode();
};
```

직접 해보기: 손님 목록 작성
----------------

이 연습에서, 우리는 여러분이 배열에 저장된 이름 목록을 취하고 그것을 손님 명단에 넣기를 원합니다. 하지만 이것은 쉽지 않습니다 — Phil과 Lola는 탐욕스럽고 무례하고, 항상 모든 음식을 먹기 때문에 우리는 Phil과 Lola를 목록에 넣고 싶지 않습니다. 우리는 두 목록을 가지고 있는데, 하나는 승인할 손님들을 위한 것이고 하나는 거절할 손님들을 위한 것입니다.

구체적으로, 우리는 여러분이 다음을 하기를 원합니다:

* 0부터 `people` 배열의 길이까지 반복하는 반복문을 작성하세요. 여러분은 초기화식 `let i = 0;`에서부터 시작할 필요가 있을 것이지만, 여러분은 무슨 조건을 필요로 하나요?
* 각 반복문 반복 동안에, 조건문을 사용하여 현재 배열 원소가 "Phil" 또는 "Lola"와 동일한지 검사하세요:
    + 만약 그렇다면, 배열 원소를 `refused` 단락의 `textContent`의 끝에 콤마와 공백을 붙여 연결하세요.
    + 만약 그렇지 않다면, 배열 원소를 `admitted` 단락의 `textContent`의 끝에 콤마와 공백을 붙여 연결하세요.

우리는 이미 여러분에게 다음을 제공했습니다:

* `let i = 0;` — 초기화식.
* `refused.textContent +=` — 무언가를 `refused.textContent`의 끝에 연결할 줄의 시작.
* `admitted.textContent +=` — 무언가를 `admitted.textContent`의 끝에 연결할 줄의 시작.

추가 보너스 질문 — 위의 일을 성공적으로 완료한 이후에, 여러분은 콤마로 나눠진 두 이름 목록을 가지고 있을 것이지만, 그것들은 단정치 못합니다 — 각 목록의 끝에 콤마가 있을 것입니다. 각 경우에 어떻게 마지막 콤마를 잘라낸 줄을 작성하고, 끝에 마침표를 추가할 지 알아내실 수 있으신가요? 도움을 위해 유용한 문자열 메서드 문서를 한 번 봐 보세요.

만약 실수했다면, 언제나 예제를 "Reset" 버튼으로 리셋할 수 있습니다. 만약 정말로 막혔다면, 답을 보기 위해 "Show solution"을 누르세요.
```

<h2>Live output</h2>
<div class="output" style="height: 100px;overflow: auto;">
  <p class="admitted">Admit:</p>
  <p class="refused">Refuse:</p>
</div>

<h2>Editable code</h2>
<p class="a11y-label">
  Press Esc to move focus away from the code area (Tab inserts a tab character).
</p>
<textarea id="code" class="playable-code" style="height: 400px;width: 95%">
const people = ['Chris', 'Anne', 'Colin', 'Terri', 'Phil', 'Lola', 'Sam', 'Kay', 'Bruce'];

const admitted = document.querySelector('.admitted');
const refused = document.querySelector('.refused');
admitted.textContent = 'Admit: ';
refused.textContent = 'Refuse: '

// let i = 0;

// refused.textContent += ;
// admitted.textContent += ;

</textarea>

<div class="playable-buttons">
  <input id="reset" type="button" value="Reset" />
  <input id="solution" type="button" value="Show solution" />
</div>
```

```
html {
  font-family: sans-serif;
}

h2 {
  font-size: 16px;
}

.a11y-label {
  margin: 0;
  text-align: right;
  font-size: 0.7rem;
  width: 98%;
}

body {
  margin: 10px;
  background: #f5f9fa;
}
```

```
const textarea = document.getElementById("code");
const reset = document.getElementById("reset");
const solution = document.getElementById("solution");
let code = textarea.value;
let userEntry = textarea.value;

function updateCode() {
  eval(textarea.value);
}

reset.addEventListener("click", function () {
  textarea.value = code;
  userEntry = textarea.value;
  solutionEntry = jsSolution;
  solution.value = "Show solution";
  updateCode();
});

solution.addEventListener("click", function () {
  if (solution.value === "Show solution") {
    textarea.value = solutionEntry;
    solution.value = "Hide solution";
  } else {
    textarea.value = userEntry;
    solution.value = "Show solution";
  }
  updateCode();
});

let jsSolution =
  "const people = ['Chris', 'Anne', 'Colin', 'Terri', 'Phil', 'Lola', 'Sam', 'Kay', 'Bruce'];\n\nconst admitted = document.querySelector('.admitted');\nconst refused = document.querySelector('.refused');\n\nadmitted.textContent = 'Admit: ';\nrefused.textContent = 'Refuse: '\nlet i = 0;\n\ndo {\n if(people[i] === 'Phil' || people[i] === 'Lola') {\n refused.textContent += people[i] + ', ';\n } else {\n admitted.textContent += people[i] + ', ';\n }\n i++;\n} while(i < people.length);\n\nrefused.textContent = refused.textContent.slice(0,refused.textContent.length-2) + '.';\nadmitted.textContent = admitted.textContent.slice(0,admitted.textContent.length-2) + '.';";
let solutionEntry = jsSolution;

textarea.addEventListener("input", updateCode);
window.addEventListener("load", updateCode);

// stop tab key tabbing out of textarea and
// make it write a tab at the caret position instead

textarea.onkeydown = function (e) {
  if (e.keyCode === 9) {
    e.preventDefault();
    insertAtCaret("\t");
  }

  if (e.keyCode === 27) {
    textarea.blur();
  }
};

function insertAtCaret(text) {
  let scrollPos = textarea.scrollTop;
  let caretPos = textarea.selectionStart;

  let front = textarea.value.substring(0, caretPos);
  let back = textarea.value.substring(
    textarea.selectionEnd,
    textarea.value.length,
  );
  textarea.value = front + text + back;
  caretPos = caretPos + text.length;
  textarea.selectionStart = caretPos;
  textarea.selectionEnd = caretPos;
  textarea.focus();
  textarea.scrollTop = scrollPos;
}

// Update the saved userCode every time the user updates the text area code

textarea.onkeyup = function () {
  // We only want to save the state when the user code is being shown,
  // not the solution, so that solution is not saved over the user code
  if (solution.value === "Show solution") {
    userEntry = textarea.value;
  } else {
    solutionEntry = textarea.value;
  }

  updateCode();
};
```

어떤 반복문을 써야 할까?
--------------

기본적 사용에 대해, `for`, `while`, 그리고 `do...while` 반복문들은 대체로 교체할 수 있습니다. 이것들은 같은 문제를 풀기 위해 모두 쓰여질 수 있고, 어떤 것을 사용할지는 주로 여러분의 개인적인 선호에 달려 있습니다 — 어떤 것이 가장 기억하기 쉽거나 직관적이라고 생각하시나요. 이것들을 다시 살펴봅시다.

첫째로 `for`:
```

for (초기화식; 종료 조건; 증감식) {
  // 실행할 코드
}
```

`while`:
```

초기화식
while (종료 조건) {
  // 실행할 코드

  증감식
}
```

그리고 마지막으로 `do...while`:
```

초기화식
do {
  실행할 코드

  증감식
} while (종료 조건)
```

우리는, 적어도 시작하는 데, `for`를 추천합니다. 왜냐하면 이것은 아마도 모든 것을 기억하기 가장 쉽기 때문입니다 — 초기화식, 조건, 증감식 모두가 괄호 안에 깔끔하게 들어가야만 하므로, 이것들이 어디 있는지 보고 여러분이 이것들을 놓치지 않았다는 것을 확인하기 쉽습니다.

**참고:** 다른 반복문 형태/기능 또한 있는데, 이는 고급/특수한 상황에서 유용하고 이 글의 범위 너머에 있습니다. 만약 반복문을 더 많이 배우고 싶다면, 고급 반복문과 반복 가이드를 읽어 보세요.

실력을 평가해 보세요!
------------

이 문서를 끝까지 읽으셨지만, 중요한 것들을 여전히 기억하고 계신가요? 다음 문서를 읽기 전에 이 문서의 내용을 잘 학습하고 이해하셨는지 확인하실 수 있습니다 — 실력을 평가해 보세요: 반복문.

결론
--

이 문서는 여러분에게 JavaScript에서의 반복문에 대한 기본 개념과 이용 가능한 다른 옵션들을 드러내 보였습니다. 여러분은 이제 왜 반복문이 반복적인 코드를 다루는 데 좋은 메커니즘인지 확실히 이해하고, 여러분만의 예제에서 그것들을 사용하고 싶어서 몸이 근질거리실 것입니다!

만약 뭐든지 이해하지 못한 게 있다면, 자유롭게 이 문서를 다시 읽거나, 문의하기에서 도움을 요청해 보세요.

같이 보기
-----

* 반복문과 반복 자세히 알아보기
* for 문 참고서
* while 과 do...while 레퍼런스
* break 과 continue 레퍼런스
* JavaScript For 반복문을 작성하는 가장 좋은 방법이 무엇인가? — 몇몇 고급 반복문 습관
* 이전
* Overview: Building blocks
* 다음


실력을 평가해 보세요: 조건문 - Web 개발 학습하기

실력을 평가해 보세요: 조건문
================

이 실력 평가의 목적은 여러분이 판단을 만드세요 — 조건문 문서를 잘 이해했는지 평가하기 위함입니다.

.

**참고:** 여러분은 정답을 아래의 인터랙티브 에디터에서 시도해 볼 수 있지만, 과제를 수행하기 위해 코드를 다운로드해서 다음과 같은 온라인 툴을 이용하는 것 또한 도움이 될 지도 모릅니다: CodePen, jsFiddle, or Glitch

정말로 막히면, 도움을 요청해 보세요 — 이 페이지 아래의 Assessment or further help 섹션을 확인해 보세요.

**참고:** 아래의 예제들에서, 만약 여러분의 코드에 오류가 있다면, 답을 알아내려고 시도하는 것을 돕기 위해 페이지의 결과 패널에 (혹은 다운로드 버전의 경우, 브라우저의 JavaScript 콘솔에) 오류가 출력될 것입니다.

조건문 1
-----

이 과제에서는 여러분에게 두 변수가 주어집니다:

* `season` — 현재 계절이 무엇인지를 말하는 문자열을 포함합니다.
* `response` — 초기화되지 않은 상태지만, 나중에 결과 패널에 출력될 대답을 저장하기 위해 쓰입니다.

우리는 여러분이 `season`이 문자열 "summer"를 포함하는지를 확인하는 조건문을 작성하고, 만약 그렇다면 `response`에 계절에 대한 알맞은 메시지를 유저에게 주는 문자열을 할당하기를 원합니다. 만약 아니라면, `response`에 유저에게 우리는 무슨 계절인지 모른다고 말하는 일반적인 문자열을 할당해야만 합니다.

마치기 위해서, 여러분은 그리고서 `season`가 문자열 "winter"를 포함하는지를 확인하는 다른 테스트를 추가하고, 다시 `response`에 적절한 문자열을 할당해야만 합니다.

완성된 예제를 만들기 위해 아래의 라이브 코드를 업데이트해 보세요:

**참고:** 다른 (온라인) 에디터에서 작업하기 위해 이 과제에 대한 시작점을 다운로드하세요.

조건문 2
-----

이 과제에 대해서 여러분에게는 3개의 변수가 주어집니다:

* `machineActive` — 대답 기계가 켜졌는지 꺼졌는지에 대한 지표를 포함합니다 (`true`/`false`)
* `score` — 가상 게임에서의 여러분의 점수를 포함합니다. 이 점수는 대답 기계에 넣어지는데, 이는 여러분이 얼마나 잘 했는지를 나타내는 대답을 제공합니다.
* `response` — 초기화되지 않은 상태지만, 나중에 결과 패널에 출력될 대답을 저장하기 위해 쓰입니다./li>

여러분은 기계가 켜졌는지 확인하고 `response` 변수에 메시지를 넣는 `if...else` 구조를 만들 필요가 있습니다. 만약 기계가 켜지지 않았다면, 유저에게 기계를 작동시키라고 말하세요.

만약 기계가 켜져 있다면 — 첫번째 (`if...else`문) 내부에, 여러분은 점수 값이 무엇인지에 따라 `response`에 적절한 메시지를 넣는 `if...else if...else`를 중첩할 필요가 있습니다. 다른 조건 테스트 (그리고 결과 대답)은 다음과 같습니다:

* 0보다 작거나 100보다 큰 점수 — "이것은 가능하지 않습니다, 오류가 발생했습니다."
* 0에서 19의 점수 — "끔찍한 점수입니다 — 완전한 실패입니다!"
* 20에서 39의 점수 — "조금 알긴 하지만 꽤 나쁜 점수입니다. 발전이 필요합니다."
* 40에서 69의 점수 — "그런대로 잘 하셨네요, 나쁘지 않습니다!"
* 70에서 89의 점수 — "훌륭한 점수입니다, 정말로 잘 아시는군요."
* 90에서 100의 점수 — "놀라운 점수입니다! 커닝하셨나요? 진짜인가요?"

완성된 예제를 만들기 위해 아래의 라이브 코드를 업데이트해 보세요. 코드를 입력한 이후에, 작동하는지 보기 위해서, `machineActive`을 `true`로 바꿔 보세요.

**참고:** 다른 (온라인) 에디터에서 작업하기 위해 이 과제에 대한 시작점을 다운로드하세요.

조건문 3
-----

이 과제에서 여러분은 두번째 과제에서 작성했던 코드를 가져와서, 안쪽의 `if...else if...else`를 `switch` 문으로 대신 재작성할 필요가 있습니다.

완성된 예제를 만들기 위해 아래의 라이브 코드를 업데이트해 보세요:

**참고:** 다른 (온라인) 에디터에서 작업하기 위해 이 과제에 대한 시작점을 다운로드하세요.

조건문 4
-----

마지막 과제에 대해서 여러분에게는 4개의 변수가 주어집니다:

* `machineActive` — 로그인 기계가 켜졌는지 꺼졌는지에 대한 지표를 포함합니다 (`true`/`false`).
* `pwd` — 유저의 로그인 비밀번호를 포함합니다.
* `machineResult` — 초기화되지 않은 상태지만, 유저에게 기계가 켜졌는지를 알게 하는, 나중에 결과 패널에 출력될 대답을 저장하기 위해 쓰입니다.
* `pwdResult` — 초기화되지 않은 상태지만, 유저에게 로그인 시도가 성공적이였는지를 알게 하는, 나중에 결과 패널에 출력될 대답을 저장하기 위해 쓰입니다.

우리는 여러분이 기계가 켜졌는지를 확인하고, 유저에게 기계가 켜졌는지 꺼졌는지를 말하는 `machineResult` 변수에 메시지를 넣는 `if...else` 구조를 만들기를 원합니다.

만약 기계가 켜져 있으면, 우리는 또한 `pwd`이 `cheese`와 동일한지 확인하는 두번째 조건문을 원합니다. 만약 그렇다면, 그것은 `pwdResult`에 유저에게 성공적으로 로그인되었다고 말하는 문자열을 할당해야만 합니다. 만약 그렇지 않다면, `pwdResult`에 유저에게 로그인 시도가 성공적이지 않았다고 말하는 다른 문자열을 할당해야만 합니다. `if ... else` 구조가 아닌 무언가를 사용해서, 우리는 여러분이 이것을 한 줄에서 하기를 원합니다.

완성된 예제를 만들기 위해 아래의 라이브 코드를 업데이트해 보세요:

**참고:** 다른 (온라인) 에디터에서 작업하기 위해 이 과제에 대한 시작점을 다운로드하세요.

평가 혹은 추가적인 도움
-------------

여러분은 이 예제들을 위의 인터랙티브 에디터에서 실습할 수 있습니다.

만약 여러분의 작업을 평가받고 싶으시거나 막혀서 도움을 요청하기를 원하신다면:

1. 여러분의 작업을 CodePen, jsFiddle, 또는 Glitch 같은 온라인에서 공유 가능한 에디터에 올리세요. 여러분은 직접 코드를 작성하거나, 위 섹션들에 링크된 시작점 파일을 사용할 수 있습니다.
2. MDN Discourse forum Learning category 에 평가 및/또는 도움을 요청하는 글을 작성하세요. 여러분의 글은 다음을 포함해야만 합니다:
    * "조건문 1 실력 평가에 대한 평가 원함"과 같은 서술적인 제목.
    * 여러분이 이미 무엇을 시도해 봤는지, 그리고 우리가 무엇을 하기를 원하는지에 대한 설명. 예를 들자면, 막혀서 도움이 필요하다거나, 평가를 원한다거나 하는 설명을 포함해야 합니다.
    * (위의 단계 1에서 언급된) 온라인에서 공유 가능한 에디터에 있는, 여러분이 평가를 원하거나 도움이 필요한 예제의 링크. 이것은 익숙해지기에 좋은 습관입니다. 코딩 문제가 있는 누군가를 도울 때, 그들의 코드를 보지 못한다면 그들을 돕는 것은 몹시 힘듭니다.
    * 우리가 여러분이 도움을 원하는 문제를 찾을 수 있도록, 실제 과제나 평가 페이지의 링크.


이미지 갤러리 - Web 개발 학습하기

이미지 갤러리
=======

* 이전
* Overview: Building blocks

이제 우리는 JavaScript의 핵심적인 구성 요소를 살펴보았으므로, 우리는 반복문, 함수, 조건문, 그리고 이벤트에 대한 여러분의 이해를 시험할 것입니다. 많은 웹사이트들에서 보게 될 꽤 흔한 아이템인 — JavaScript를 이용하는 이미지 갤러리를 만듦으로써 말이죠.

|  |  |
| --- | --- |
| 필요한 사전 지식: |
 이 평가를 시도하기 전에 여러분은 이 모듈의 모든 문서를 독파해야만
 합니다.
  |
| 목표: | JavaScript 반복문, 함수, 조건문, 그리고 이벤트에 대한 이해 시험하기. |

시작점
---

이 평가를 시작하기 위해, 다음의 링크로 가서 예제에 대한 ZIP 파일을 다운로드하고, 압축을 해제한 후 진행하세요.

그 대신에, JSBin 나 Glitch 같은 사이트를 이용할 수 있습니다. HTML, CSS 그리고 JavaScript를 이 온라인 에디터 중 하나에 붙여넣기할 수 있습니다. 만약 온라인 에디터가 분리된 JavaScript/CSS 패널을 가지고 있지 않다면, 자유롭게 HTML 페이지 내부의 인라인 `<script>`/`<style>` 요소에 넣으세요.

**참고:** 만약 막히면, 도움을 요청하세요 — 이 페이지 아래의 Assessment or further help 섹션을 보세요.

프로젝트 개요
-------

여러분에게 몇몇 HTML, CSS 그리고 이미지 에셋(asset) 그리고 몇 줄의 JavaScript 코드가 제공되었습니다; 여러분은 이것을 작동하는 프로그램으로 만들기 위해 필수적인 JavaScript를 작성할 필요가 있습니다. HTML body는 다음과 같습니다:

```html
<h1>Image gallery example</h1>

<div class="full-img">
  <img class="displayed-img" src="images/pic1.jpg" />
  <div class="overlay"></div>
  <button class="dark">Darken</button>
</div>

<div class="thumb-bar"></div>
```

예제는 다음과 같습니다:

![](/ko/docs/Learn/JavaScript/Building_blocks/Image_gallery/gallery.png)

이 예제의 가장 흥미로운 부분은 CSS 파일입니다:

* 이것은 `full-img <div>` 내부의 세 요소를 절대적으로 위치시킵니다 — 전체 크기의 이미지가 표시되는 `<img>`, `<img>`와 같은 크기이고 이것 바로 위에 놓여지는 비어있는 `<div>` (반투명한 배경색을 통해 이미지에 어두워지는 효과를 적용하기 위해 쓰입니다), 그리고 어두워지는 효과를 제어하기 위해 쓰이는 `<button>`.
* 이것은 `thumb-bar <div>` (소위 "섬네일" 이미지) 내부의 이미지들의 폭을 20%로 설정하고, 사진들이 한 줄에서 서로의 다음에 오도록 왼쪽으로 부유시킵니다.

여러분의 JavaScript는 다음을 하기를 필요로 합니다:

* 모든 이미지를 순회하고, 각각에 대해 `<img>` 요소를 페이지에 그 이미지를 끼워 넣는 `thumb-bar <div>` 내부에 삽입하기.
* `onclick` 핸들러를 `thumb-bar <div>` 내부의 각 `<img>`에 부착해 그것들이 클릭되었을 때, 해당하는 이미지가 `displayed-img <img>` 요소에 표시되도록 하기.
* `onclick` 핸들러를 `<button>`에 부착해 이것이 클릭되었을 때, 어두워지는 효과가 전체 크기 이미지에 적용되도록 하기. 이 버튼이 다시 클릭되었을 때, 어두워지는 효과는 다시 사라집니다.

더 많은 생각을 제공 받으려면, 완성된 예제를 살펴보세요. (소스 코드 훔쳐보기 없기!)

완료해야할 단계
--------

다음의 섹션들은 무엇을 할 필요가 있는지 설명합니다.

### 이미지 순회하기

우리는 이미 `thumbBar` 상수 내부에 `thumb-bar <div>`에 대한 참조를 저장하고, 새로운 `<img>` 요소를 생성하고, 그것의 `src` 어트리뷰트를 플레이스홀더 값 `xxx`로 설정하고, 그리고 `thumbBar` 내부에 이 새로운 `<img>` 요소를 추가하는 코드를 제공했습니다.

여러분은 다음을 할 필요가 있습니다:

1. 5개의 모든 이미지를 순회하는 반복문 내부의 "Looping through images" 주석 아래에 코드 섹션 추가하기 — 여러분은 그저 5개의 숫자를 순회할 필요가 있는데, 각 숫자는 각각의 이미지를 나타냅니다.
2. 각각의 반복에서, `xxx` 플레이스홀더 값을 각 경우의 이미지 경로와 동일한 문자열으로 대체하세요. 우리는 `src` 어트리뷰트의 값을 각 경우에서 이 값으로 설정하고 있습니다. 각 경우에서, 이미지는 이미지 디렉토리 내부에 있고 그것의 이름은 `pic1.jpg`, `pic2.jpg` 등등이라는 것을 기억해 두세요.
### onclick 핸들러를 각 섬네일 이미지에 추가하기

각각의 반복에서, 여러분은 `onclick` 핸들러를 현재의 `newImage`에 추가할 필요가 있습니다 — 이 핸들러는 현재 이미지의 `src` 어트리뷰트의 값을 찾아야만 합니다. `displayed-img <img>`의 `src` 어트리뷰트 값을 매개변수로서 전달된 `src` 값으로 설정하세요.

그 대신에, 여러분은 섬네일 바에 하나의 이벤트 리스너를 추가할 수 있습니다.

### 어두워지게/밝게 하는 버튼을 실행하는 핸들러 작성하기

우리의 어두워지게/밝게 하는 `<button>`은 가만히 있습니다 — 우리는 이미 `btn` 상수에 `<button>`에 대한 참조를 저장하는 코드 라인을 제공했습니다. 여러분은 다음을 수행하는 `onclick`을 추가할 필요가 있습니다:

1. `<button>`에 설정된 현재 클래스명을 확인 — 여러분은 다시 이것을 `getAttribute()`를 사용함으로써 달성할 수 있습니다.
2. 만약 클래스명이 `"dark"`라면, `<button>` 클래스를 `"light"`로 (`setAttribute()`를 사용하여), 이것의 텍스트 콘텐츠를 "Lighten"으로, 그리고 덮어씌운 `<div>`의 `background-color`를 `"rgba(0,0,0,0.5)"`로 변경.
3. 만약 클래스명이 `"dark"`가 아니라면, `<button>` 클래스를 `"dark"`로, 이것의 텍스트 콘텐츠를 다시 "Darken"으로, 덮어씌운 `<div>`의 `background-color`를 `"rgba(0,0,0,0)"`로 변경.

다음의 코드 라인은 위의 2와 3에서 규정된 변화 달성에 대한 기초를 제공합니다.

```js
btn.setAttribute("class", xxx);
btn.textContent = xxx;
overlay.style.backgroundColor = xxx;
```

힌트와 팁
-----

* 여러분은 어떤 방법으로도 HTML 또는 CSS를 수정할 필요가 없습니다.
평가 혹은 추가적인 도움
-------------

만약 여러분의 작업을 평가받고 싶으시거나 막혀서 도움을 요청하기를 원하신다면:

1. 여러분의 작업을 CodePen, jsFiddle, 또는 Glitch 같은 온라인에서 공유 가능한 에디터에 올리세요.
2. MDN Discourse forum Learning category 에 평가 및/또는 도움을 요청하는 글을 작성하세요. 여러분의 글은 다음을 포함해야만 합니다:
    * "이미지 갤러리에 대한 평가 원함"과 같은 서술적인 제목.
    * 여러분이 이미 무엇을 시도해 봤는지, 그리고 우리가 무엇을 하기를 원하는지에 대한 설명. 예를 들자면, 막혀서 도움이 필요하다거나, 평가를 원한다거나 하는 설명을 포함해야 합니다.
    * (위의 단계 1에서 언급된) 온라인에서 공유 가능한 에디터에 있는, 여러분이 평가를 원하거나 도움이 필요한 예제의 링크. 이것은 익숙해지기에 좋은 습관입니다. 코딩 문제가 있는 누군가를 도울 때, 그들의 코드를 보지 못한다면 그들을 돕는 것은 몹시 힘듭니다.
    * 우리가 여러분이 도움을 원하는 문제를 찾을 수 있도록, 실제 과제나 평가 페이지의 링크.
* 이전
* Overview: Building blocks


실력을 평가해 보세요: 이벤트 - Web 개발 학습하기

실력을 평가해 보세요: 이벤트
================

이 실력 테스트의 목적은 여러분이 우리의 이벤트 입문 문서를 이해했는지 평가하기 위함입니다.

**참고:** 아래의 인터랙티브 에디터에서 해답을 시도해 볼 수도 있지만, 과제를 하기 위해 코드를 다운로드하고 CodePen, jsFiddle, 또는 Glitch와 같은 온라인 툴(tool)을 사용하는 것이 도움이 될 지도 모릅니다.

만약 막히면, 도움을 요청하세요 — 이 페이지 아래의 Assessment or further help 섹션을 보세요.

**참고:** 아래의 예제들에서, 만약 코드에 오류가 있다면, 답을 찾는 걸 돕기 위해 페이지의 결과 패널에 (또는 다운로드한 경우, 브라우저의 JavaScript 콘솔에) 오류가 출력될 것입니다.

DOM 조작: 유용하다고 생각됨
-----------------

아래의 몇몇 문제들은 여러분에게 문제 해결을 위해서 몇몇 DOM 조작 코드를 작성하기를 요구합니다 — 새로운 HTML 요소 생성하기, 특정한 문자열 값과 동일한 텍스트 콘텐츠 설정하기, 그리고 페이지에 존재하는 요소 내부에 중첩하기와 같은 — 모두 JavaScript를 통해서.

우리는 이것을 아직 이 코스에서 분명하게 가르치지 않았지만, 여러분은 이것을 사용하는 몇몇 예제를 보았고, 우리는 여러분이 문제에 성공적으로 답하기 위해 어떤 DOM API들이 필요한지에 대해 검색하기를 원합니다. 좋은 시작점은 우리의 문서 조작하기 (en-US)(Manipulating documents) 튜토리얼입니다.

이벤트 1
-----

우리의 첫 번째 이벤트에 관계된 과제에서, 여러분은 버튼 (`btn`) 내부의 텍스트가 버튼이 클릭되었을 때 바뀌고, 다시 클릭되었을 때 원상복귀되게 하는 간단한 이벤트 핸들러를 생성할 필요가 있습니다.

HTML은 변경되어서는 안 됩니다; JavaScript만 변경되어야 합니다.

완성된 예제를 다시 만들기 위해 아래의 코드를 업데이트해 보세요:

**참고:** 여러분의 에디터나 온라인 에디터에서 작업하기 위해서 이 과제의 시작점을 다운로드하세요.

이벤트 2
-----

이제 우리는 키보드 이벤트를 살펴볼 것입니다. 이 평가를 통과하기 위해서 여러분은 WASD 키가 키보드에서 눌렸을 때 원을 제공된 캔버스 주위에서 움직이는 이벤트 핸들러를 만들 필요가 있습니다. 원은 `drawCircle()` 함수로 그려지는데, 이는 다음의 입력을 매개변수로 취합니다.

* `x` — 원의 x 좌표.
* `y` — 원의 y 좌표.
* `size` — 원의 반지름.

완성된 예제를 다시 만들기 위해 아래의 코드를 업데이트해 보세요:

**참고:** 여러분의 에디터나 온라인 에디터에서 작업하기 위해서 이 과제의 시작점을 다운로드하세요.

이벤트 3
-----

우리의 마지막 이벤트에 관련된 과제에서, 여러분은 `<button>`들의 부모 요소 (`<div class="button-bar"> ... </div>`)에 이벤트 핸들러를 설정할 필요가 있는데, 이는 버튼을 클릭해서 호출했을 때 `button-bar`의 배경색을 버튼의 `data-color` 어트리뷰트 안에 포함된 색으로 설정합니다.

우리는 여러분이 모든 버튼을 순회하고 각 버튼에 이벤트 리스너를 주지 않고 이것을 해결하기를 원합니다.

완성된 예제를 다시 만들기 위해 아래의 코드를 업데이트해 보세요:

**참고:** 여러분의 에디터나 온라인 에디터에서 작업하기 위해서 이 과제의 시작점을 다운로드하세요.

평가 혹은 추가적인 도움
-------------

여러분은 이 예제들을 위의 인터랙티브 에디터에서 연습할 수 있습니다.

만약 여러분의 작업을 평가받고 싶으시거나 막혀서 도움을 요청하기를 원하신다면:

1. 여러분의 작업을 CodePen, jsFiddle, 또는 Glitch와 같은 온라인에서 공유 가능한 에디터에 올리세요. 여러분은 코드를 직접 작성할 수도 있고, 혹은 위 섹션에 링크된 시작 파일을 사용할 수도 있습니다.
2. MDN Discourse forum Learning category 에 평가 및/또는 도움을 요청하는 글을 작성하세요. 여러분의 글은 다음을 포함해야만 합니다:
    * "이벤트 1 실력 테스트에 대한 평가 원함"과 같은 서술적인 제목.
    * 여러분이 이미 무엇을 시도해 봤는지, 그리고 우리가 무엇을 하기를 원하는지에 대한 설명. 예를 들자면, 막혀서 도움이 필요하다거나, 평가를 원한다거나 하는 설명을 포함해야 합니다.
    * (위의 단계 1에서 언급된) 온라인에서 공유 가능한 에디터에 있는, 여러분이 평가를 원하거나 도움이 필요한 예제의 링크. 이것은 익숙해지기에 좋은 습관입니다. 코딩 문제가 있는 누군가를 도울 때, 그들의 코드를 보지 못한다면 그들을 돕는 것은 몹시 힘듭니다.
    * 우리가 여러분이 도움을 원하는 문제를 찾을 수 있도록, 실제 과제나 평가 페이지의 링크.


실력을 평가해 보세요: 함수 - Web 개발 학습하기

실력을 평가해 보세요: 함수
===============

이 실력 테스트의 목적은 여러분이 우리의 함수 — 코드 재사용, 함수 만들기, 그리고 함수 반환 값 문서를 이해했는지 평가하기 위함입니다.

**참고:** 아래의 인터랙티브 에디터에서 해답을 시도해 볼 수도 있지만, 과제를 하기 위해 코드를 다운로드하고 CodePen, jsFiddle, 또는 Glitch와 같은 온라인 툴(tool)을 사용하는 것이 도움이 될 지도 모릅니다.

만약 막히면, 도움을 요청하세요 — 이 페이지 아래의 Assessment or further help 섹션을 보세요.

**참고:** 아래의 예제에서, 만약 코드에 오류가 있다면, 답을 찾는 걸 돕기 위해 페이지의 결과 패널에 (또는 다운로드한 경우, 브라우저의 JavaScript 콘솔에) 오류가 출력될 것입니다.

DOM 조작: 유용하다고 생각됨
-----------------

아래의 몇몇 문제들은 여러분에게 문제 해결을 위해서 몇몇 DOM 조작 코드를 작성하기를 요구합니다 — 새로운 HTML 요소 생성하기, 특정한 문자열 값과 동일한 텍스트 콘텐츠 설정하기, 그리고 페이지에 존재하는 요소 내부에 중첩하기와 같은 — 모두 JavaScript를 통해서.

우리는 이것을 아직 이 코스에서 분명하게 가르치지 않았지만, 여러분은 이것을 사용하는 몇몇 예제를 보았고, 우리는 여러분이 문제에 성공적으로 답하기 위해 어떤 DOM API들이 필요한지에 대해 검색하기를 원합니다. 좋은 시작점은 우리의 문서 조작하기 (en-US)(Manipulating documents) 튜토리얼입니다.

함수 1
----

첫 번째 과제에서, 여러분은 제공된 배열 (`names`)에서 무작위 이름을 제공된 단락(`para`)에 출력하고, 그리고서 한 번만 실행되는 간단한 함수 — `chooseName()` — 를 만들어야 합니다.

완성된 예제를 다시 만들기 위해 아래의 코드를 업데이트해 보세요:

**참고:** 여러분의 에디터나 온라인 에디터에서 작업하기 위해서 이 과제의 시작점을 다운로드하세요.

함수 2
----

우리의 두 번째 함수에 관계된 과제에서, 여러분은 제공된 `<canvas>`에 (참조 변수 `canvas`, context는 `ctx`에서 이용가능), 다섯 개의 제공된 입력 변수를 기반으로 하여, 직사각형을 그리는 함수를 만들 필요가 있습니다.

* `x` — 직사각형의 x 좌표.
* `y` — 직사각형의 y 좌표.
* `width` — 직사각형의 너비.
* `height` — 직사각형의 높이.
* `color` — 직사각형의 색깔.

인터랙티브 에디터의 경우 코드가 업데이트될 때, 많은 직사각형들이 다른 직사각형 위에 그려지지 않도록, 여러분은 그리기 전에 캔버스를 지우기를 원할 것입니다.

완성된 예제를 다시 만들기 위해서 아래의 코드를 업데이트해 보세요:

**참고:** 여러분의 에디터나 온라인 에디터에서 작업하기 위해서 이 과제의 시작점을 다운로드하세요.

함수 3
----

이 과제에서는, 여러분은 과제 1에서 제기된 문제를 개선시킬 목적으로 이 과제에 다시 돌아왔습니다. 우리가 여러분이 만들기를 원하는 세 가지 개선점은:

1. 무작위 숫자를 생성하는 코드를 별도의 함수 `random()`으로 리팩토링하는데, 이 함수는 매개변수로서 무작위 숫자가 사이에 위치할 두 기준점을 취하고, 결과를 반환합니다.
2. `chooseName()` 함수가 무작위 숫자 함수를 사용하고, 매개변수로서 선택할 배열을 취하고 (함수를 더 적응성 있게 만듭니다), 결과를 반환하도록 함수를 업데이트하세요.
3. 반환된 결과를 단락 (`para`)의 `textContent`에 출력하세요.

완성된 예제를 다시 만들기 위해 아래의 코드를 업데이트해 보세요:

**참고:** 여러분의 에디터나 온라인 에디터에서 작업하기 위해서 이 과제의 시작점을 다운로드하세요.

평가 혹은 추가적인 도움
-------------

여러분은 이 예제들을 위의 인터랙티브 에디터에서 연습할 수 있습니다.

만약 여러분의 작업을 평가받고 싶으시거나 막혀서 도움을 요청하기를 원하신다면:

1. 여러분의 작업을 CodePen, jsFiddle, 또는 Glitch와 같은 온라인에서 공유 가능한 에디터에 올리세요. 여러분은 코드를 직접 작성할 수도 있고, 혹은 위 섹션에 링크된 시작 파일을 사용할 수도 있습니다.
2. MDN Discourse forum Learning category 에 평가 및/또는 도움을 요청하는 글을 작성하세요. 여러분의 글은 다음을 포함해야만 합니다:
    * "함수 1 실력 테스트에 대한 평가 원함"과 같은 서술적인 제목.
    * 여러분이 이미 무엇을 시도해 봤는지, 그리고 우리가 무엇을 하기를 원하는지에 대한 설명. 예를 들자면, 막혀서 도움이 필요하다거나, 평가를 원한다거나 하는 설명을 포함해야 합니다.
    * (위의 단계 1에서 언급된) 온라인에서 공유 가능한 에디터에 있는, 여러분이 평가를 원하거나 도움이 필요한 예제의 링크. 이것은 익숙해지기에 좋은 습관입니다. 코딩 문제가 있는 누군가를 도울 때, 그들의 코드를 보지 못한다면 그들을 돕는 것은 몹시 힘듭니다.
    * 우리가 여러분이 도움을 원하는 문제를 찾을 수 있도록, 실제 과제나 평가 페이지의 링크.


멀티미디어: 비디오 - Web 개발 학습하기

멀티미디어: 비디오
==========

* 이전
* Overview: Performance
* 다음  (en-US)

이전 섹션에서 살펴본 것처럼 미디어, 즉 이미지 및 비디오는 평균 웹사이트 다운로드 바이트의 70%를 차지합니다. 이미지를 최적화하는 방법은 이미 살펴봤습니다. 이 기사는 웹 성능 향상을 위한 동영상 최적화에 대해 살펴보겠습니다.

|  |  |
| --- | --- |
| 사전 지식: |
 기본 컴퓨터 활용능력,
 기본 소프트웨어 설치,
 클라이언트 사이드 웹 기술들의 기본적인 지식.
  |
| 목표: | 성능에 영향을 미치는 다양한 비디오 형식, 그리고 각 브라우저의 파일 형식 지원에 따라 가장 작은 동영상 파일 크기를 제공하면서 전체 페이지 로드 시간에 비디오가 미치는 영향을 줄이는 방법에 대해 학습합니다. |

왜 멀티미디어를 최적화 해야할까요?
-------------------

평균적인 웹사이트는 비디오에서 25%의 대역폭을 사용합니다. 비디오를 최적화하는 것은 대역폭을 크게 아낄 수 있고, 더 나은 웹 성능으로 이어질 수 있습니다.

비디오 전송 최적화하기
------------

아래 섹션에서는 다음과 같은 최적화 기법에 대해 설명합니다.

* 모든 비디오를 압축하기
* `<source>` 순서 최적화
* 비디오 자동 재생
* 음 소거된 영웅 비디오에서 소리 제거하기
* 비디오 미리 불러오기
* 스트리밍 고려하기
### 모든 비디오를 압축하기

대부분의 비디오 압축은 비디오 내의 인접한 프레임을 비교하여 두 프레임에서 동일한 부분을 의도적으로 제거하는 것입니다. 동영상을 압축하고 WebM, MPEG-4/H.264, Ogg/Theora등 여러 비디오 포맷으로 내보낼 수 있습니다.

비디오 편집 소프트웨어는 파일 크기를 줄일 수 있는 기능이 있을 것입니다. 만약 그렇지 않다면, FFmpeg같은 (아래 섹션에서 설명됩니다) 인코드, 디코드, 변환 및 다른 최적화 기능들을 수행하는 온라인 도구가 있습니다.

### `<source>` 순서 최적화

비디오 소스의 순서를 작은 것부터 큰 것으로 정렬하세요. 예를 들어, 10MB, 12MB, 13MB의 세 가지 다른 형식의 동영상 압축이 주어지면 가장 작은 것을 먼저 선언하고 가장 큰 것을 마지막으로 선언합니다.

```html
<video width="400" height="300" controls="controls">
  <!-- WebM: 10 MB -->
  <source src="video.webm" type="video/webm" />
  <!-- MPEG-4/H.264: 12 MB -->
  <source src="video.mp4" type="video/mp4" />
  <!-- Ogg/Theora: 13 MB -->
  <source src="video.ogv" type="video/ogv" />
</video>
```

브라우저는 이해할 수 있는 첫 번째 형식을 먼저 다운로드 합니다. 목표는 큰 버전보다 작은 버전을 먼저 제공하는 것입니다. 가장 작은 버전을 사용하면, 압축된 비디오가 여전히 잘 보이는지 확인합니다. 일부 압축 알고리즘은 동영상을 animated GIF처럼 (좋지 않게) 보이게 만들 수 있습니다. 128Kb 비디오는 10MB 다운로드보다 더 나은 사용자 경험을 제공하는 것처럼 보일 수 있지만, 거친 GIF 같은 비디오는 브랜드 또는 프로젝트에 악영향을 끼칠 것입니다.

CanIUse.com에서 현재 브라우저의 비디오 및 다른 미디어 타입들의 지원을 확인하세요.

### 비디오 자동 재생

반복되는 배경 동영상이 자동 재생되도록 하려면 비디오에 반드시 `autoplay`, `muted` 및 `playsinline` 같은 몇몇 속성들을 추가해야 합니다.

```html
<video
 autoplay=""
 loop=""
 muted="true"
 playsinline=""
 src="backgroundvideo.mp4"></video>
```

`loop` 및 `autoplay`는 비디오를 반복하고 자동재생 하는것에 적합하지만, `muted` 속성은 모바일 브라우저에서 자동재생에 필요한 속성입니다.

`Playsinline`은 모바일 Safari에 필요합니다. 전체화면 모드를 강제하지 않고 비디오를 실행시킬 수 있습니다.

### 음 소거된 영웅 비디오에서 소리 제거하기

영웅 동영상이나 오디오가 없는 동영상의 경우, 오디오를 제거하는것이 현명합니다.

```html
<video autoplay="" loop="" muted="true" playsinline="" id="hero-video">
  <source src="banner\_video.webm" type='video/webm; codecs="vp8, vorbis"' />
  <source src="web\_banner.mp4" type="video/mp4" />
</video>
```

위에 있는 영웅 비디오 코드는 컨퍼런스 웹사이트와 기업 홈페이지에서 일반적으로 사용됩니다. 자동 재생, 반복 및 음 소거를 포함하는 비디오 입니다. 제어할 수 있는 인터페이스가 없어서 오디오를 들을 수 있는 방법이 없습니다. 오디오는 종종 비어있지만 여전히 존재합니다. 그리고 대역폭을 사용합니다. 항상 음 소거가 되어있는 비디오에 오디오를 제공할 이유가 없습니다. **오디오를 제거하는것은 20%의 대역폭을 절약할 수 있습니다**

선택한 소프트웨어에 따라, 내보내기 및 압축 중에 오디오를 제거할 수도 있습니다. 그렇지 않다면 무료 유틸리티 FFmpeg 을 사용할 수 있습니다. 아래 예시는 오디오를 제거하기 위한 일반적인 FFmpeg 명령어입니다.

```bash
ffmpeg -i original.mp4 -an -c:v copy audioFreeVersion.mp4
```

### 비디오 미리 불러오기

preload 속성에는 `auto`|`metadata`|`none`라는 3개의 가능한 옵션이 있습니다. 기본 설정은 `metadata`입니다. 이러한 설정들은 페이지를 불러올 때 얼마나 많은 비디오 파일을 다운로드 할지 제어합니다. 인기가 낮은 비디오들의 다운로드를 연기하여 데이터를 절약할 수 있습니다.

`preload="none"`으로 설정하는 것은 재생하기 전까지 비디오를 다운로드 하지 않는 속성입니다. 시작이 지연되기는 하지만, 실행 확률이 낮은 비디오의 경우 상당한 양의 데이터를 절약할 수 있습니다.

대역폭을 조금 더 절약할 수 있는 `preload="metadata"`로 설정하는것은 페이지를 불러올 때 비디오의 3%까지만 다운로드 할 수 있습니다. 이 옵션은 작거나 일반 크기의 일부 파일들에 유용합니다.

설정을 `auto`로 바꾸는 것은 브라우저가 자동으로 전체 비디오를 다운로드하게 합니다. 재생이 매우 자주 일어날 것 같을 때 사용하세요. 그렇지 않으면 대역폭을 많이 낭비하게 됩니다.

### 스트리밍 고려하기

비디오 스트리밍을 사용하면 적절한 비디오 크기와 대역폭을 (네트워크 속도에 기반해서) 최종 사용자에게 전달할 수 있습니다. 반응형 이미지와 비슷하게, 올바른 크기의 비디오가 브라우저에 전달되고 빠른 시작, 낮은 버퍼링 및 최적화된 재생을 보장해 줍니다.

결론
--

비디오를 최적화하는 것은 웹 성능을 상당히 개선할 수 있는 잠재력을 가지고 있습니다. 비디오 파일들은 상대적으로 다른 웹사이트 파일에 비해 용량이 커서 항상 주의가 필요합니다. 이 기사는 파일 크기를 줄이고, (HTML) 다운로드 설정 및 스트리밍을 통해서 어떻게 웹사이트 비디오를 최적화할 수 있는지 설명합니다.

* 이전
* Overview: Performance
* 다음  (en-US)


멀티미디어: 이미지 - Web 개발 학습하기

멀티미디어: 이미지
==========

* 이전
* Overview: Performance
* 다음

미디어 파일(이미지 + 비디오)은 평균적으로 웹사이트에서 다운로드되는 용량의 약 70% 이상을 차지합니다. 다운로드 성능 측면에서 미디어를 없애거나 파일 크기를 줄이는 것은 어렵지 않습니다. 이 글에서는 웹 성능을 개선하기 위해 이미지와 비디오를 최적화하는 방법을 살펴봅니다.

|  |  |
| --- | --- |
| 필요한 사전 지식: |
 컴퓨터에 대한 기본적인 이해도,
 기본적인 소프트웨어 설치,
 클라이언트 사이드 웹 기술에 대한 기초 지식
  |
| 목표: | 다양한 이미지 형식과 각 형식이 성능에 미치는 영향, 전체 페이지 로드 시간에 대한 이미지의 영향을 줄이는 법을 배웁니다. |

**참고:** 이 글은 일반적인 원칙과 기술을 포함하여 웹에서의 멀티미디어 전송 최적화를 개략적으로 소개합니다. 더 깊은 내용을 다루는 가이드를 찾으신다면, https://images.guide를 참조하세요.

멀티미디어를 최적화해야 하는 이유
------------------

일반적인 웹사이트의 데이터 전송량 중 51%는 이미지가, 25%는 비디오가 차지하기 때문에, 멀티미디어를 능숙하게 다루고 최적화하는 것은 중요하다고 할 수 있습니다.

데이터 사용량은 필수적으로 고려해야 하는 문제입니다. 많은 사람들이 데이터 한도가 있거나 1MB 단위로 요금이 계산되는 종량제 방식의 통신 요금제를 사용하기 때문입니다. 이는 선진국들도 해당되는 문제입니다. 2018년 기준, 영국 인구의 24%가 종량제 요금제를 사용합니다.

메모리 사용량도 중요한 문제입니다. 많은 모바일 기기의 RAM 용량이 크지 않기 때문이죠. 이미지가 다운로드될 때 메모리에 저장되어야 한다는 것을 잊지 마세요.

이미지 전송 최적화
----------

이미지는 데이터 전송량 중 가장 큰 부분을 차지하지만, 이미지 다운로드가 사용자가 인지하는 성능 (en-US)에 영향을 끼치는 정도는 많은 사람들의 생각보다 훨씬 적습니다. 가장 큰 이유는 페이지 내 텍스트가 즉시 다운로드되어 표시되고 사용자들이 이미지가 도착하면서 렌더링되는 것을 볼 수 있기 때문입니다. 하지만 좋은 사용자 경험을 위해선 방문자들이 이미지를 가능한 한 빨리 볼 수 있어야 합니다.

### 로딩 전략

대부분의 웹사이트에서 가장 큰 개선 사항 중 하나는 방문자의 스크롤 여부와 무관하게 초기 페이지 로드 시 이미지를 모두 다운로드하는 대신, 스크롤을 해야 볼 수 있는 이미지를 지연 로딩하는 것입니다. lazysizes와 같은 많은 JavaScript 라이브러리가 지연된 로딩을 구현하고 있으며, 웹 브라우저 제조사들도 내장 `lazyload` 속성을 실험적 기능으로 제공하고 있습니다.

이미지를 로딩된 이후에는 이미지 형식 자체를 들여다봐야 합니다.

* 최적의 파일 형식으로 로딩하고 있나요?
* 이미지는 잘 압축되었나요?
* 올바른 크기의 이미지를 로딩하고 있나요?

#### 최적의 파일 형식

어떤 파일 형식이 가장 적합한지는 이미지의 특성에 따라 다릅니다.

**참고:** 이미지 파일 유형과 형식 가이드 (en-US)에서 이미지 유형에 대한 일반적인 정보를 찾을 수 있습니다.

SVG (en-US) 형식은 색상이 적고 사실적이지 않은 이미지에 더 적합합니다. SVG 형식을 사용하려면 원본 이미지를 벡터 그래픽 형식으로 쓸 수 있어야 합니다. 만약 원본 이미지가 비트맵 형식으로만 존재한다면 PNG (en-US) 형식이 대안이 될 수 있습니다. 이런 주제의 유형으로는 로고, 일러스트, 차트, 아이콘 등이 있습니다. (참고: SVG는 아이콘 폰트보다 훨씬 낫습니다!) SVG와 PNG 모두 투명도를 지원합니다.

PNG는 세 가지의 출력 조합을 지정해 저장할 수 있습니다.

* 24-bit 색상 + 8-bit 투명도 - 가장 정확한 색상과 부드러운 투명도를 제공하는 대신 파일의 크기가 큽니다. 만약 WebP를 선호하는 분이라면 이 조합은 피하고 싶을 것입니다. (아래를 참고하세요.)
* 8-bit 색상 + 8-bit 투명도 - 255개 이하의 색상과 부드러운 투명도를 제공합니다. 용량은 그렇게 크지 않습니다. 많은 사람이 원할 만한 PNG입니다.
* 8-bit 색상 + 1-bit 투명도 - 255개 이하의 색상과 단 픽셀당 투명하거나 투명하지 않거나의 단 두 가지 투명도 설정을 제공합니다. 그렇기 때문에 투명한 영역의 테두리가 부드럽지 않고 울퉁불퉁해 보입니다. 용량은 작지만 시각적 정확도가 떨어집니다.

온라인으로 SVGOMG라는 괜찮은 SVG 최적화 서비스를 이용하실 수 있습니다. PNG의 경우 ImageOptim online나 Squoosh가 괜찮습니다.

투명도가 필요하지 않은 '사진 같은' 이미지는 더 넓은 범위의 파일 형식을 선택할 수 있습니다. 안전한 방식을 선호한다면, 잘 압축된 **점진적 JPEG**이 적합할 것입니다. 점진적 JPEG은 일반적인 JPEG과 다르게 점진적으로 렌더링됩니다 (이름 그대로 말이죠). 사용자는 완전한 해상도의 이미지가 상단에서 하단으로 로딩되거나 모두 다운로드된 이후 렌더링되는 대신 이미지 다운로드가 진행되면서 낮은 해상도에서 높은 해상도로 점점 더 명확해지는 것을 보게 됩니다. 점진적 JPEG 압축방식 중 괜찮은 것으로 MozJPEG이 있는데요, 온라인 이미지 최적화 도구인 Squoosh에서 사용할 수 있습니다. 75% 품질 설정 정도면 괜찮은 결과를 얻을 수 있을 것입니다.

JPEG 대비 압축 성능을 개선한 다른 파일 형식들이 더 있지만, 모든 브라우저에서 쓸 수 있는 것은 아닙니다.

* WebP (en-US) - 이미지와 애니메이션 이미지 두 경우 모두 훌륭한 선택입니다. WebP는 PNG, JPEG보다 훨씬 더 높은 압축률과 표현 색상 수, 애니메이션의 프레임 수, 투명도 등을 제공합니다. (단, 점진적 표시 기능은 없습니다). macOS 컴퓨터의 Safari 14 외 모든 주요 브라우저가 지원합니다.

>
> **Note:** Safari 14에서의 WebP 지원이 공표되었지만, 여전히 macOS 데스크탑에서는 .webp 이미지가 표시되지 않습니다. 반면 iOS 14에서는 정상적으로 표시됩니다.
>
>
>
* AVIF (en-US) - 이미지와 애니메이션 이미지 두 경우 모두 훌륭한 선택으로, 높은 성능의 무료 이미지 형식입니다. (WebP보다 더 효율적이지만, 지원 범위는 넓지 않습니다.) Chrome, Opera, Firefox가 지원합니다. 이전 이미지 형식들을 변환해주는 온라인 AVIF 변환도구를 참고하세요.
* **JPEG2000** - 한때 JPEG의 계승자였으나 지금은 Safari만 지원하고 있습니다. 점진적 표시 기능도 없죠.

JPEG-XR과 JPEG2000의 좁은 지원 범위와 높은 복호화 비용을 고려하면 JPEG의 유일한 경쟁자는 WebP입니다. 그러므로 이미지를 WebP 형식으로도 제공할 수 있습니다. 이를 위해선 `<picture>` 요소에 `<source>` 요소를 넣고 type 속성 (en-US)을 적용하면 됩니다.

이 모두가 다소 복잡하거나 소속 팀에게 너무 과한 작업처럼 느껴진다면 이미지 CDN처럼 사용할 수 있는 온라인 서비스들이 있습니다. 이미지를 요청하는 기기 유형과 브라우저에 따라 적절한 이미지 형식을 제공하는 과정을 자동화해주죠. 가장 많이 사용되는 것으로는 Cloudinary와 Image Engine이 있습니다.

마지막으로, 페이지에 애니메이션 이미지를 넣고 싶을 경우 Safari는 `<img>`와 `<picture>` 요소 안에 비디오 파일을 사용할 수 있다는 것을 알아두세요. 다른 모든 최신 브라우저들에서는 이 요소들을 사용해 **애니메이션 WebP**를 추가할 수 있습니다.

```html
<picture>
  <source type="video/mp4" src="giphy.mp4" />
  <source type="image/webp" src="giphy.webp" />
  <img src="giphy.gif" alt="A GIF animation" />
</picture>
```

#### 최적의 해상도 제공하기

이미지 전송에 있어 "모두에게 적합한" 방식의 접근법은 최상의 결과를 내지 못합니다. 작은 화면에서는 이미지를 낮은 해상도로, 큰 화면에서는 반대로 높은 해상도로 제공하고 싶을 것이기 때문이죠. 그 외에 높은 해상도를 갖는 화면 (예: "레티나") 기기에도 높은 해상도로 제공하고 싶을 것입니다. 그러므로 중간 해상도의 이미지 변형을 여럿 만드는 것 외에 적절한 파일을 알맞은 브라우저에 제공하는 방법이 필요합니다. 여기가 `<picture>`, `<source>` 요소를 media (en-US)나 sizes (en-US) 속성을 활용해 업그레이드할 필요가 있는 지점입니다. 이 모든 속성들을 결합하는 방법에 대한 자세한 글은 여기에서 확인할 수 있습니다.

높은 해상도를 갖는 화면들을 다룰 땐 다음의 두 가지 흥미로운 효과들을 염두에 두세요.

* 높은 해상도를 가진 화면에서 사람들은 이미지 압축손실을 더 늦게 발견합니다. 그러므로 높은 DPI를 가진 화면에서 쓰일 이미지들은 평소보다 압축률을 더 높여도 됩니다.
* 아주 소수의 사람들만 2배 이상의 DPI에서 해상도 증가를 알아차립니다. 이는 2배 이상 해상도의 이미지를 제공할 필요가 없음을 의미합니다.

#### 다운로드되는 이미지의 우선순위 (그리고 순서) 제어하기

가장 중요한 이미지를 덜 중요한 것들보다 먼저 방문자들에게 보여주는 것은 사용자들이 인지하는 웹 성능을 높일 수 있습니다.

첫 번째 확인사항은 페이지 본문의 이미지들이 `<img>`나 `<picture>` 요소를 사용하고 있는지, 그리고 배경 이미지들이 CSS의 `background-image` 속성으로 정의되고 있는지입니다. `<img>` 요소를 통해 참조된 이미지들은 배경 이미지보다 더 높은 로딩 우선순위가 부여됩니다.

둘째로, 우선순위 힌트(Priority Hints)가 도입되면서, 이미지 태그에 `fetchPriority` 속성을 적용하여 우선순위를 추가로 조절할 수 있습니다. 적절한 사용 예시로 이미지 캐러셀의 첫 번째 이미지가 이어지는 이미지들보다 높은 우선순위를 갖도록 구현하는 것이 있습니다.

### 렌더링 전략: 이미지 로딩 시 버벅거림 방지하기

 이미지는 비동기적으로 로드되며, First Paint 이후에도 계속 로드되기 때문에, 만약 이미지의 크기가 로딩 전에 정의되지 않았다면 페이지 내용의 Reflow를 유발할 수 있습니다. 이미지가 로딩되면서 텍스트가 페이지 아래로 밀려 내려가는 예시가 이에 해당할 것입니다.
 그렇기 때문에, 브라우저가 이미지가 표시될 공간을 미리 준비하도록 `width`와 `height` 속성을 설정하는 것이 중요합니다.

HTML `<img>` 요소에 포함된 이미지의 `width`와 `height` 속성은 이미지 로딩 전 브라우저가 이미지의 가로 세로 비율을 미리 계산하는 데 쓰입니다. 이미지 다운로드 후 화면에 표시될 때 이미지가 표시될 공간을 준비하고 Layout Shift를 줄이거나 더 나아가 예방하는 데에도 활용되죠. Layout Shift를 줄이는 것은 좋은 사용자 경험과 웹 성능의 주요한 부분입니다.

브라우저는 이미지를 포함한 모든 자산이 다운로드되기 전, HTML이 구문 분석될 때 콘텐츠 렌더링을 시작합니다. 이미지 크기를 포함시키면 브라우저가 최초의 페이지 렌더링 시 각 이미지가 표시될 정확한 크기의 플레이스홀더를 준비할 수 있습니다.

![첫 번째는 이미지가 없지만 공간이 준비되어 있는 이미지, 두 번째는 이미지가 준비된 공간으로 로딩되는 이미지](/ko/docs/Learn/Performance/Multimedia/ar-guide.jpg)

`width`와 `height` 속성이 없다면 플레이스홀더 공간이 만들어지지 않기 때문에, 페이지 렌더링 후 이미지 로드 시점에 눈에 띄는 버벅거림(jank)나 Layout Shift가 생깁니다. 페이지 Reflow와 Repaint 모두 성능과 사용성 문제에 해당하죠.

반응형 디자인에서는 이미지를 담는 공간의 가로 길이가 이미지보다 작을 경우 이미지가 그 공간을 벗어나지 않도록 하기 위해 보통 다음의 CSS를 사용합니다.

```css
img {
  max-width: 100%;
  height: auto;
}
```

이 방법은 반응형 레이아웃에는 유용하지만 너비 및 높이 정보가 포함되어 있지 않을 경우 버벅거림을 유발합니다. `<img>` 요소가 파싱되었지만 이미지는 로드되기 전에 높이 정보가 없을 경우엔 높이를 0으로 설정한 것과 같은 효과를 주기 때문이죠. 페이지가 화면에 최초로 렌더링된 후 이미지 로드 시점에 페이지는 Reflow, Repaint되며 새로 설정된 높이를 위한 공간을 만들면서 Layout Shift가 생깁니다.

브라우저는 실제로 이미지가 로드되기 전 이미지의 크기를 정하는 메커니즘을 갖고 있습니다. `<img>`, `<video>`, `<input type="button">` 요소에 `width`와 `height` 속성이 설정되어 있으면 브라우저는 이를 통해 가로 세로 비율을 로드 시간 이전에 계산하고 활용할 수 있습니다.

가로 세로 비율은 그 다음으로 이미지의 높이를 계산하는 데 쓰이고, 그 결과 `<img>` 요소의 정확한 크기가 적용됩니다. 이렇게 되면 경우 이미지 로드 시 앞에서 얘기한 버벅거림이 아예 일어나지 않거나 최소화됩니다. 목록으로 주어진 이미지 크기들이 정확하지 않더라도 말이죠.

가로 세로 비율은 이미지 로드 시 공간을 준비하는 데에만 쓰입니다. 이미지가 로드된 후에는 속성들에서 계산된 값이 아닌 로드된 이미지 자체의 가로 세로 비율이 사용됩니다. 이는 크기 속성들이 정확하지 않은 경우에도 이미지가 정확한 가로 세로 비율로 표시될 수 있도록 해줍니다.

지난 10년 동안 HTML에 `<img>` 태그에 이미지를 쓸 때 `width`와 `height` 속성을 생략하는 것이 개발자 모범 사례로 추천되었었지만, 가로 세로 비율 매핑으로 인해 이제는 이 두 속성을 포함시키는 것이 모범 사례입니다.

배경 이미지의 경우, 이미지가 다운로드되기 전에도 그 위의 표시될 내용을 읽을 수 있도록 `background-color` 속성을 설정하는 것이 중요합니다.

결론
--

이 섹션에선 이미지 최적화에 대해 살펴보았습니다. 이제 평균 웹사이트 데이터 전송량의 절반에 달하는 부분을 최적화하는 방법에 대해 전체적으로 이해했을 것입니다. 이미지는 사용자들의 데이터 전송량을 소모하고 페이지 로딩을 느리게 하는 단 하나의 미디어 유형일 뿐입니다. 다음에는 데이터 전송량의 소모의 20%를 차지하는 비디오를 최적화하는 방법에 대해서 살펴보겠습니다.

* 이전
* Overview: Performance
* 다음


웹 성능이 중요한 "이유" - Web 개발 학습하기

웹 성능이 중요한 "이유"
==============

* Overview: Performance
* 다음  (en-US)

웹 성능은 느린 처리 속도를 빠르게 보이게 하는 것을 포함해 웹사이트를 빠르게 만드는 모든 것입니다. 이 기사에서는 왜 웹 성능이 사이트 방문자와 당신의 사업적 목표에 중요한지 소개합니다.

|  |  |
| --- | --- |
| 사전 지식: |
 기본 컴퓨터 활용능력,
 기본 소프트웨어 설치,
 클라이언트 사이드 웹 기술들의 기본적인 지식.
  |
| 목표: | 좋은 사용자 경험을 위해 왜 웹 성능이 중요한지 기본적으로 숙지할 수 있습니다. |

웹 성능은 웹 브라우저에서 얼마나 빠르게 사이트의 컨텐츠가 **불러와지고** **렌더링** 되는지 그리고 사용자 상호작용에 얼마나 잘 응답하는지를 나타냅니다. 나쁜 성능을 가진 사이트는 느리게 보여지고 입력에 느리게 응답합니다. 나쁜 성능의 사이트는 사이트 이탈을 증가시킵니다. 최악의 경우 나쁜 성능은 컨텐츠가 완전히 접근 불가능하게 될 수 있습니다. 웹 성능을 위한 좋은 목표는 사용자들이 성능에 대해 느끼지 못하는 것입니다. 사이트 성능의 개인적인 인식은 주관적이지만, 로딩 및 렌더링은 측정될 수 있습니다. 좋은 성능은 대부분 사이트 방문자들에게 명백하지 않을 수 있습니다. 하지만 느린 사이트는 대부분 즉시 알아챌 수 있을 것입니다. 이것이 바로 우리가 웹 성능에 대해 신경 쓰는 이유입니다.

성능에 신경 쓰는 이유는 무엇일까요?
--------------------

웹 성능과 관련된 모범 사례들은 웹사이트 방문자들이 좋은 경험을 갖게 하기 위해 필수적입니다. 어떤 의미에서 웹 성능은 웹 접근성의 하위 집합으로 간주될 수 있습니다. 웹 접근성과 마찬가지로, 성능도 사이트 방문자들이 사이트에 접근하기 위해 어떤 디바이스를 사용하는지와 디바이스 연결 속도를 고려합니다.

예를 들어, CNN.com의 로딩 경험을 생각해 보세요. 이 글을 작성할 당시 파일 크기가 22.6MB가 넘고 400번 이상의 HTTP 요청을 했습니다.

* 광섬유 네트워크에 연결된 데스크탑 컴퓨터에서 불러온다고 상상해 보세요. 이렇게 하면 파일 사이즈에 거의 관계없이 상대적으로 속도가 빠를 것입니다.
* 대중교통에서 출퇴근 하는동안 9년된 아이패드에서 테더링된 모바일 데이터를 사용해서 같은 사이트를 불러온다고 상상해 보세요. 그 사이트는 아마 불러오는 속도가 느려지고 셀 커버리지에 따라 사용할 수 없는 상태가 될 수도 있습니다. 불러오는 것이 끝나기도 전에 포기할 수도 있습니다.
* 같은 사이트를 커버리지가 제한적이거나 아예 없는 인도 시골의 35달러 화웨이 장비에서 불러온다고 상상해 보세요. 아마 사이트는 매우 느리게 불러와질 것이고, 로딩이 되더라도 차단된 스크립트로 인해 시간이 초과될 수 있고, 로딩이 되더라도 CPU에 나쁜 영향을 끼쳐 브라우저가 종료될 수 있습니다.

사이트의 크기가 22.6 MB인 경우 3G 네트워크에서 불러오는데 83초까지 걸릴 수 있습니다. `DOMContentLoaded` (사이트의 기본 HTML 구조를 의미) 의 경우 31.86초가 소요됩니다.

그리고 다운로드를 하는데 걸리는 시간만이 중요한 문제가 아닙니다. 많은 나라들은 여전히 인터넷 연결이 메가바이트 단위로 가격이 부과됩니다. 22.6 MB CNN.com 사이트를 예로들면, 다운로드 하는데 인도인 평균 하루 임금의 약 11%를 지출하게 됩니다. 북서 아프리카의 모바일 장치에서 이 사이트를 이용하려면 평균 임금의 이틀치 비용이 들 수 있습니다. 그리고 이 사이트를 미국의 국제 로밍 요금제로 이용한다면 어떨까요? 그 비용에 누구라도 울음을 터뜨릴 것입니다. (다운로드 하는데 얼마나 가격이 드는지 확인해보세요.)

### 전환율 향상시키기

사이트의 다운로드 및 렌더링 시간을 줄이면 사용자 유지율 및 전환율이 향상됩니다.

**전환율**은 사이트 방문자들이 측정된 행동 또는 원하는 행동을 수행하는 비율을 말합니다. 예를 들어 제품을 구매하거나 기사를 읽는 것 또는 뉴스레터를 구독하는 것일 수 있습니다. 전환율로 측정되어지는 이 행동은 웹사이트의 사업적 목표에 따라 달라집니다.

성능은 전환율에 영향을 줍니다. 웹 성능을 개선하면 전환율이 향상됩니다. 사이트 방문자들은 사이트를 불러오는데 2초 또는 그 이하를 기대합니다. 때때로 모바일(일반적으로 더 오래 걸리는)의 환경에서 더 빠르기를 기대하기도 합니다. 이러한 사이트 방문자들은 3초 정도에 느린 사이트를 떠나기 시작합니다.

사이트 로딩 속도도 한 가지 요소입니다. 만약 사이트가 사용자 상호작용에 느리게 반응하거나 불안정하게 표시되면, 사이트 방문자들의 흥미와 신뢰를 잃게 됩니다.

여기 성능 개선의 몇몇 실제 사례들이 있습니다.

* Tokopedia는 렌더링 시간을 3G 연결 시 14초에서 2초로 줄였습니다. 그리고 방문자의 19% 증가, 전체 세션의 35% 증가, 새로운 사용자의 7% 증가, 활성 사용자의 17% 증가 및 사용자당 세션들이 16% 증가했습니다.
* 성능을 위해 Pinterest 페이지들을 재구축한 결과 대기 시간의 40% 감소, SEO 트래픽의 15% 증가 및 회원가입 전환율이 15% 증가했습니다.

사람들이 사용하고 싶어 하는 웹사이트와 애플리케이션을 구축하고, 사이트 방문자들을 유치하고 유지하려면 사용자 경험이 좋은 접근성 있는 사이트를 만들어야 합니다. 웹사이트를 구축하려면 일반적으로 이미지나 비디오 같은 이진 파일 유형을 포함하여 HTML, CSS, Javascript 가 필요합니다. 당신이 사이트를 구축할 때 내리는 결정 및 도구 선택은 완성된 결과물의 성능에 큰 영향을 줄 수 있습니다.

좋은 성능은 자산입니다. 나쁜 성능에는 책임이 따릅니다. 사이트 속도는 이탈률, 전환율, 수익, 사용자 만족 및 검색 엔진 순위에 직접적인 영향을 줍니다. 성능이 우수한 사이트는 방문자 유지율과 사용자 만족도를 높이는것으로 나타났습니다. 느린 컨텐츠는 사이트 이탈로 이어지고 일부 사용자들은 다시는 돌아오지 않는 것으로 나타났습니다. 클라이언트와 서버 간의 전송되는 데이터의 양을 줄이면 모든 당사자들의 비용이 줄어듭니다. HTML/CSS/JavaScript 및 미디어 파일들의 사이즈를 줄이는 것은 사이트의 불러오는 시간과 전력 소비가 모두 줄어듭니다. (성능 예산 (en-US)을 확인해 주세요.)

성능을 추적하는것은 중요합니다. 네트워크 속도 및 디바이스 기능들을 포함하여 다양한 요인이 성능에 영향을 미칩니다. 단일 성능 지표는 없습니다. 그리고 비즈니스 목표가 다르면, 사이트가 지원하는 조직이나 사이트의 목표와 더 관련 있는 지표가 다를 수 있습니다. 사이트의 성능이 어떻게 인식되는지는 사용자 경험입니다!

결론
--

웹 성능은 접근성뿐만 아니라 조직 또는 비즈니스의 목표에 부합하는 다른 웹사이트 지표에도 중요합니다. 웹 사이트 성능의 좋고 나쁨은 유저 경험뿐만 아니라 대부분의 사이트의 전반적인 효율성과도 밀접하게 관련되어 있습니다. 이것이 당신이 웹 성능에 신경 써야 하는 이유입니다.

* Overview: Performance
* 다음  (en-US)


웹 성능 측정하기 - Web 개발 학습하기

웹 성능 측정하기
=========

* 이전  (en-US)
* Overview: Performance
* 다음

성능을 측정하는 것은 당신의 앱, 사이트 또는 웹 서비스의 성공을 평가하는 데 도움이 되는 중요한 지표를 제공합니다.

예를 들어, 성능 지표들을 사용해서 경쟁사 제품과 비교하여 앱의 성능을 확인하거나, 여러 릴리즈에 걸쳐 앱의 성능을 비교할 수 있습니다. 당신이 측정하려고 선택한 지표들은 사용자, 사이트 및 사업적 목표들과 관련이 있어야 합니다. 이러한 지표들은 기술적 이해관계자가 아닌 사용자도 사용하고 이해할 수 있는 형식으로 수집, 일관적으로 측정 및 분석되어야 합니다.

이 기사는 사이트 성능을 측정하고 최적화하는 데 사용할 수 있는 웹 성능 지표들에 접근하기 위해 사용할 수 있는 도구들을 소개합니다.

|  |  |
| --- | --- |
| 필요한 사전 지식: |
 기본 컴퓨터 활용능력,
 기본 소프트웨어 설치,
 클라이언트 사이드 웹 기술들의 기본적인 지식.
  |
| 목표: | 다양한 웹 성능 API 및 해당 데이터들을 시각화하는 데 사용할 수 있는 도구들을 사용해서 모을 수 있는 웹 성능 지표들에 대한 정보를 제공합니다. |

웹 성능 도구
-------

성능을 측정하고 개선하는 데 도움을 주는 다양한 도구들이 있습니다. 이러한 도구들은 일반적으로 2가지 범주로 분류될 수 있습니다.

* PageSpeed Insights 또는 Firefox 네트워크 모니터 및 성능 모니터 같은 성능을 표시하거나 측정하는 도구들이 있습니다. 이러한 도구들은 얼마나 빠르게 또는 느리게 웹사이트가 불러와지는지 보여줍니다. 또한 이 도구들은 당신의 웹 앱에서 최적화하기 위해 개선할 수 영역도 표시해 줍니다.
* Performance API (en-US) 를 사용해 사용자 지정 성능 도구를 만들 수 있습니다.
일반적인 성능 보고 도구
-------------

PageSpeed Insights같은 도구들은 빠른 성능 측정을 제공합니다. URL을 입력하면 몇 초안에 성능 보고서를 얻을 수 있습니다. 이 성능 보고서는 당신의 웹사이트가 모바일 및 데스크탑에서 어떻게 작동하는지 보여줍니다. 이 도구는 이미 잘하고 있는 부분과 개선할 수 있는 부분에 대한 아이디어를 얻는데 좋은 출발점입니다.

이 글을 작성하는 시점에, MDN의 성능 보고서 요약은 다음과 비슷합니다.

![A screenshot of PageSpeed Insights report for the Mozilla homepage.](/ko/docs/Learn/Performance/Measuring_performance/pagespeed-insight-mozilla-homepage.png)

성능 보고서에는 어떤 것이 페이지에 보이기 전에 얼마나 오래 사용자가 기다려야 하는지, 페이지를 보여주는 데 필요한 바이트의 수 등에 대한 정보들을 포함하고 있습니다. 또한 측정된 수치가 좋은지 나쁜지도 알려줍니다.

webpagetest.org는 자동으로 사이트를 테스트하고 유용한 지표를 반환하는 다른 도구의 예입니다.

당신이 좋아하는 웹 사이트를 이러한 도구들을 이용해서 사용해 보고 어떤 점수가 나오는지 확인해 보세요.

네트워크 모니터 도구
-----------

최신 브라우저에는 불러온 페이지에 대해 실행하고 페이지의 성능을 확인하는 데 사용할 수 있는 도구가 있습니다. 대부분 비슷하게 동작합니다. 예를 들어, Firefox의 네트워크 모니터는 네트워크에서 다운로드한 모든 애셋들의 자세한 정보를 보여줍니다. 그리고 각각 다운로드 받는데 얼마나 오래 걸렸는지 폭포수 시간 그래프를 통해서 보여줍니다.

![Firefox network monitor showing a list of assets that has loaded as well as load time per asset](/ko/docs/Learn/Performance/Measuring_performance/network-monitor.png)

Chrome 네트워크 모니터 문서 또한 확인할 수 있습니다.

성능 모니터 도구
---------

Firefox 성능 모니터같은 브라우저 성능 도구를 사용해서 다양한 작업을 수행할 때, 웹 앱 또는 웹 사이트의 사용자 인터페이스의 성능을 측정할 수 있습니다. 이는 웹 앱 또는 사이트를 느리게 할 수 있는 기능들을 나타냅니다.

![Developer tools performance panel showing the waterfall of recording #1.](/ko/docs/Learn/Performance/Measuring_performance/perf-monitor.png)

Chrome 성능 도구 문서 또한 확인할 수 있습니다.

Performance APIs
----------------

웹을 위한 코드를 작성할 때 자신만의 성능 측정 도구를 만들기 위해 사용할 수 있는 수많은 Web APIs가 있습니다.

당신은 Navigation Timing API를 사용해서 이전 페이지를 언로드 하는 데 걸리는 시간, 도메인 조회에 걸리는 시간, 윈도우의 로드 처리기 실행에 필요한 총시간 등 클라이언트 측 웹 성능을 측정하는 데 사용할 수 있습니다. 아래 다이어그램에 표시된 모든 내비게이션 이벤트와 관련된 지표들에 API를 사용할 수 있습니다.

![The various handlers that the navigation timing API can handle including Navigation timing API metrics Prompt for unload redirect unload App cache DNS TCP Request Response Processing onLoad navigationStart redirectStart redirectEnd fetchStart domainLookupEnd domainLookupStart connectStart (secureConnectionStart) connectEnd requestStart responseStart responseEnd unloadStart unloadEnd domLoading domInteractive domContentLoaded domComplete loadEventStart loadEventEnd](/ko/docs/Learn/Performance/Measuring_performance/navigationtimingapi.jpg)

현재 페이지의 성능 관련 정보에 대한 접근을 제공하는 Performance API (en-US)는 Performance Timeline API, Navigation Timing API, User Timing API (en-US) 그리고 Resource Timing API (en-US)를 포함합니다. 이러한 인터페이스들은 JavaScript 작업들을 완료하는 데 걸리는 시간을 정확하게 측정하게 해줍니다.

PerformanceEntry 객체는 '성능 타임라인'의 일부입니다.
 '성능 항목'은 애플리케이션의 명시적 지점에서 성능 `mark` (en-US) 또는 `measure` (en-US) (예를 들어 `mark()` 메서드를 호출하여)를 생성하여 직접적으로 만들 수 있습니다. 성능 항목들은 또한 이미지 같은 리소스를 불러오는 간접적인 방법으로도 생성할 수 있습니다.

PerformanceObserver API (en-US)는 성능 측정 이벤트들을 관찰하고 브라우저의 성능 타임라인에 기록되는 새로운 PerformanceEntry를 알려주는 데 사용할 수 있는 API입니다.

이 기사는 이러한 API들을 사용하는데 깊이 다루지는 않지만, 해당 API들이 존재하는 것을 아는 것만으로도 유용합니다. Navigation and timings (en-US)를 참고하여 performance Web APIs를 사용하는 추가적인 예시를 확인할 수 있습니다.

결론
--

이 글에서는 웹 앱 또는 사이트에서 성능을 측정하는 데 도움을 주는 웹 성능 도구들에 대해서 간략한 개요를 제공했습니다. 다음은 체감 성능과 피할 수 없는 성능 저하를 사용자에게 덜 심각하게 보이거나 완전히 위장하는 몇 가지 기법에 대해 살펴보겠습니다.

* 이전  (en-US)
* Overview: Performance
* 다음


웹 작동방식 - Web 개발 학습하기

웹 작동방식
======

이 섹션에서는 웹 생태계 및 작동 방식에 대한 일반적인 지식과 관련된 질문을 다루고 있습니다.

인터넷은 어떻게 작동합니까?

**인터넷**은 웹의 근간을 이루며, 웹을 가능하게 하는 기술 인프라입니다.
 기본적으로, 인터넷은 서로 통신하는 컴퓨터의 거대한 네트워크입니다. 이 문서에서는 인터넷이 어떻게 작동하는지에 대해 설명합니다.

웹페이지, 웹사이트, 웹서버, 검색엔진의 차이점은 무엇인가요?

 이 도움말에서는 웹페이지, 웹사이트, 웹서버, 검색엔진 등 다양한 웹 관련 개념에 대해 설명합니다.
 이러한 용어는 웹을 처음 접하는 사람들에게 종종 혼란을 주거나, 잘못 사용되는 경우가 많습니다. 이 용어들이 실제로 무엇을 의미하는지 알아봅시다!

하이퍼링크란 무엇인가요?

이 글에서는, 하이퍼링크의 정의와 하이퍼링크가 중요한 이유에 대해 살펴봅니다.

URL이란 무엇인가요?

Hypertext 및 HTTP에서, URL은 인터넷에 관한 핵심 개념입니다. URL은 브라우저가 웹에 게시된 리소스를 검색하는 데 사용하는 방식입니다.

도메인 네임이란 무엇인가요? (en-US)

도메인 네임은 인터넷 인프라의 핵심 구성 요소입니다. 도메인 네임은 인터넷에서 사용할 수 있는 모든 웹 서버에 사람이 읽을 수 있는 주소를 제공합니다.

웹 서버란 무엇인가요?

"웹 서버"라는 용어는 웹을 통해 클라이언트에 웹 사이트를 제공하는 하드웨어 또는 소프트웨어, 또는 이 두 가지를 모두 의미할 수 있습니다. 이 글에서는 웹 서버의 작동 방식과 웹 서버가 중요한 이유에 대해 살펴봅니다.


웹 서버란 무엇일까? - Web 개발 학습하기

웹 서버란 무엇일까?
===========

여기서 우리는 웹 서버가 무엇인지, 어떻게 동작하는지, 왜 중요한지를 알아볼 것입니다.

|  |  |
| --- | --- |
| 선수 지식 | 웹 페이지와 웹 사이트, 웹 서버, 그리고 검색 엔진의 차이점 (en-US)에 대해 이해하고
 인터넷이 어떻게 동작하는지 (en-US) 알고있으면 좋습니다.
  |
| 목표 |
 웹 서버가 무엇인지를 배우고, 어떻게 동작하는지에 대한 전반적인 이해를
 얻을 것입니다.
  |

요약
--

"웹 서버"는 하드웨어, 소프트웨어 혹은 두 개가 같이 동작하는 것을 의미할 수 있습니다.

1. 하드웨어 측면에서, 웹 서버는 웹 서버의 소프트웨어와 website의 컴포넌트 파일들을 저장하는 컴퓨터입니다. (컴포넌트 파일에는 HTML 문서, images, CSS stylesheets, 그리고 JavaScript files가 있습니다.) 웹 서버는 인터넷에 연결되어 웹에 연결된 다른 기기들이 웹 서버의 데이터(컴포넌트 파일들)를 주고받을 수 있도록 합니다.
2. 소프트웨어 측면에서, 웹 서버는 기본적으로 웹 사용자가 어떻게 호스트 파일들에 접근하는지를 관리합니다. 이 문서에서 웹 서버는 HTTP서버로 국한합니다. HTTP 서버는 URL(Web addresses)과 HTTP(당신의 브라우저가 웹 페이지를 보여주기 위해 사용하는 프로토콜)의 소프트웨어 일부입니다.

가장 기본적인 단계에서, 브라우저가 웹 서버에서 불려진 파일을 필요로 할때, 브라우저는 HTTP를 통해 파일을 요청합니다. 요청이 올바른 웹 서버(하드웨어)에 도달하였을 때, HTTP 서버(software)는 요청된 문서를 HTTP를 이용해 보내줍니다.

![Basic representation of a client/server connection through HTTP](/ko/docs/Learn/Common_questions/Web_mechanics/What_is_a_web_server/web-server.svg)

웹 사이트를 공개하기 위해서는, 당신은 정적 혹은 동적 웹 서버가 필요합니다.

정적 웹 서버 혹은 스택은 HTTP 서버 (소프트웨어)가 있는 컴퓨터(하드웨어)로 구성되어 있습니다. 서버가 그 불려진 파일을 당신의 브라우저에게 전송하기 때문에, 저희는 그것을 "정적"이라고 부릅니다.

동적 웹 서버는 정적 웹 서버와 추가적인 소프트웨어(대부분 일반적인 애플리케이션 서버와 데이터베이스)로 구성되어 있습니다. 애플리케이션 서버가 HTTP 서버를 통해 당신의 브라우저에게 불려진 파일들을 전송하기 전에, 애플리케이션 서버가 업데이트하기 때문에 우리는 이것을 동적이라고 부릅니다.

예를 들어, 당신이 브라우저에서 보는 최종 웹페이지들을 생성하기 위해, 애플리케이션 서버는 아마 데이터베이스로 온 컨텐츠들로 이루어진 HTML 템플릿을 채울지 모릅니다. MDN 혹은 Wikipedia와 같은 사이트들은 수 천개의 웹페이지들을 가지고 있지만, 그것들은 실제의 HTML 문서가 아니라 오직 약간의 HTML 템플릿과 엄청 큰 데이터베이스로 되어있습니다. 이 구성은 내용들을 전달하고 관리하기 쉽고 빠르게 만들어 줍니다.

더 깊은 부분
-------

웹 페이지를 가져오기 위해, 우리가 이미 말했듯이, 당신의 브라우저는 저장 공간에 있는 요청된 파일들을 찾는 웹 서버에게 요청을 보냅니다. 한번 좀더 자세히 알아봅시다.

### 호스팅 파일들

웹 서버는 처음에 HTML 문서라고 불리는 웹 사이트의 파일들과 이미지, CSS 스타일시트, JavaScript 파일, 폰트, 비디오를 포함한 관련된 것들을 저장해야합니다.

기술적으로, 당신은 컴퓨터에 있는 그 파일들을 불러올수 있지만, 그것들을 전담하는 웹 서버에 저장하는것이 훨씬 더 편리합니다. 전담하는 웹서버는:

* 항상 실행 중입니다
* 항상 인터넷과 연결되어 있습니다
* 항상 같은 IP주소를 가지고 있습니다(모든 ISPs가 홈 라인에 대해 고정된 IP주소를 제공하는 것은 아닙니다.)
* 제 3자에 의해 유지보수 됩니다

이러한 이유들로, 좋은 호스팅 제공자를 찾는 것은 당신의 웹 사이트를 구축하는 것의 핵심 부분입니다. 다양한 서비스 회사들의 조건을 살펴보고 당신의 필요와 예산을 충족하는 하나를 선택하세요 (서비스는 무료부터 매달 수 백만원까지 있습니다.) 더 많은 자세한 사항은 여기서 찾을 수 있습니다.

당신이 웹 호스팅 솔루션을 설정했다면, 그저 당신의 웹 서버에 파일들을 업로드 하시면 됩니다. (en-US)

### HTTP를 이용해 통신하기

두 번째로, 웹 서버는 HTTP (hypertext transfer protocol)을 위한 지원합니다. 이름이 의미하듯이, HTTP는 어떻게 두 컴퓨터간의 hypertext(예를 들어, 연결된 웹 문서)를 전송하는지를 서술합니다.

프로토콜은 두 컴퓨터간의 통신를 위한 규칙의 집합입니다. HTTP는 문자로 된, 독립적인 프로토콜입니다.

Textual(문자로 된)

모든 명령어들은 기본 문자이며 사람들이 읽을 수 있습니다.

Stateless(독립적인)

서버 혹은 클라이언트는 이전의 통신을 기억하지 않습니다. 예를 들어, HTTP에만 의존하면, 서버는 당신이 입력한 비밀번호 혹 당신이 처리한 단계를 기억하지 못합니다. 당신은 그러한 일들을 위한 애플리케이션 서버가 필요합니다. (우리는 그러한 기술을 뒤에 나올 기사에서 다룰 것입니다.)

HTTP는 어떻게 클라이언트와 서버가 통신을 하는지 명확한 규칙을 제공합니다. 우리는 HTTP 그 자체를 나중에 technical article 에서 다룰 것입니다. 현재는, 이러한 것들을 기억해주세요.

* 오직 클라이언트만이 HTTP 요청을 만들 수 있으며, 서버에게만 보낼 수 있습니다. 서버는 오직 클라이언트의 HTTP 요청에 응답할 수 있습니다.
* HTTP를 통해 파일을 요청할때, 클라이언트는 반드시 URL 파일들을 제공해야 합니다.
* 웹 서버는 반드시 최소한의 에러 메시지를 포함하여 모든 HTTP 요청에 응답해야합니다.

![The MDN 404 page as an example of such error page](/ko/docs/Learn/Common_questions/Web_mechanics/What_is_a_web_server/mdn-404.jpg)웹 서버에서, HTTP 서버는 들어오는 요청들에 대해 응답하고, 처리해야 합니다.

1. 요청을 받으면, HTTP 서버는 먼저 요청받은 URL이 존재하는 파일과 매칭이 되는지를 확인합니다.
2. 만약 매칭된다면, 웹 서버는 그 파일 내용을 브라우저에게 되돌려줍니다. 만약 그렇지 않다면, 애플리케이션 서버는 필요한 파일을 구축합니다.
3. 만약 위 둘의 과정이 불가능하다면, 웹 서버는 브라우저에게 에러 메시지를 반환합니다, 대부분의 에러 메시지는 "404 Not Found" 입니다.(이 에러는 너무 많이 발생하여 많은 웹 디자이너들은404 error pages를 디자인하는데 많은 시간을 할애합니다.
### 정적 vs. 동적 컨텐츠

대략적으로 말하자면, 서버는 정적 혹은 동적 컨텐츠 모두 제공할 수 있습니다. "정적"은 "있는 그대로 제공되는 것(served as-is)"를 의미합니다. 정적 웹 사이트들은 설치하기 가장 쉽기때문에 우리는 당신이 첫 사이트를 정적 사이트로 만들기를 제안합니다.

"동적"은 서버가 컨텐츠를 처리하는 것, 심지어는 컨텐츠를 데이터베이스로부터 생성하는 것을 의미합니다. 이 방법은 더 많은 유연성을 제공하지만, 기술적 스택이 더 다루기 힘들어지고, 웹사이트를 구축하는 것이 훨씬 더 복잡해집니다.

당신이 지금 읽고있는 페이지를 예시로 봅시다. 이 사이트를 호스팅하고 있는 웹 서버에는, 데이터베이스로부터 내용들을 받고, 구성하고, HTML 템플릿 안에 집어넣고, 당신에게 결과를 보내는 애플리케이션 서버가 있습니다. 이러한 경우, 애플리케이션 서버는 Kuma라고 불리고, Python(Django 프레임워크를 이용한)으로 구축됩니다. Mozilla 팀은 MDN의 특수한 목적으로 Kuma를 만들었지만, 많은 다른 기술들로 만들어진 비슷한 애플리케이션이 존재합니다.

애플리케이션 서버는 아주 많이 있어서 특정한 하나만 추천하기는 어렵습니다. 어떤 애플리케이션 서버는 블로그나 위키, 인터넷 쇼핑, CMSs라고 불리는 다른 것들(컨텐츠 관리 시스템) 같은 특수한 웹 사이트에 특화되어 있습니다. 만약 당신이 동적 웹 사이트를 구축한다면, 당신의 필요에 맞는 도구를 선택하는 시간을 가져보세요. 웹 서버 프로그래밍을 배우기를 원하는 경우가 아니라면(물론, 그 자체로도 흥미진진한 영역입니다!), 애플리케이션 서버를 새로 만들 필요가 없습니다. 그것은 휠을 다시 재발명 하는 것과 같은 일입니다.

다음 과정
-----

이제 당신은 웹 서버에 익숙해졌으니, 아래와 같은 것들을 할 수 있습니다:

* 웹에서 어떤 것을 하는 것이 얼마나 많은 비용이 들지 (en-US)를 읽어보기
* 당신이 웹 사이트를 생성하기 위해 필요한 다양한 소프트웨어를 배우기
* 웹 서버에 어떻게 파일을 업로드 하는 지 (en-US)와 같은 실용적인 것으로 넘어가기


URL이란? - Web 개발 학습하기

URL이란?
======

이 문서에서는 URL(Uniform Resource Locator)이 무엇이며 어떻게 구성되어 있는지 설명합니다.

|  |  |
| --- | --- |
| 사전 지식 |
 먼저
 인터넷은 어떻게 동작하는 방법,
 웹 서버
 그리고
 웹 링크 뒤에 있는 개념을 알아야 합니다.
  |
| 목표 | URL이 무엇이며 웹에서 어떻게 작동하는지 배웁니다. |

요약
--

하이퍼텍스트와 HTTP에서 ***URL***은 웹의 핵심 개념 중 하나입니다. URL은 웹에 게시된 리소스를 검색하기 위해 브라우저에서 사용하는 메커니즘입니다.

**URL**은 *Uniform Resource Locator*의 약자입니다. URL은 웹에서 주어진 고유 리소스 주소에 지나지 않습니다. 이론적으로 각각의 유효한 URL은 고유한 리소스를 가리킵니다. 이러한 리소스는 HTML 페이지, CSS 문서, 이미지 등이 될 수 있습니다. 실제로는 몇 가지 예외가 있으며 가장 일반적인 예외는 더 이상 존재하지 않거나 이동된 리소스를 가리키는 URL입니다. URL로 표시되는 리소스와 URL 자체는 웹 서버에서 처리되므로 해당 리소스와 관련 URL을 신중하게 관리하는 것은 웹 서버 소유자에게 달려 있습니다.

기본: URL 분석
----------

다음은 URL의 몇 가지 예시입니다.
```

https://developer.mozilla.org
https://developer.mozilla.org/ko/docs/Learn/
https://developer.mozilla.org/en-US/search?q=URL
```

해당 URL 중 하나를 브라우저의 주소창에 입력하면 연결된 페이지(리소스)를 로드할 수 있습니다.

URL은 여러 부분으로 구성되며 일부는 필수이고 일부는 선택 사항입니다. 가장 중요한 부분은 아래 URL에 강조표시되어 있습니다(자세한 내용은 다음 섹션에서 다룸).

![전체 URL](/ko/docs/Learn/Common_questions/Web_mechanics/What_is_a_URL/mdn-url-all.png)

**참고:** URL은 일반 우편 주소와 비슷하다고 생각할 수 있습니다. *scheme*(스키마)는 사용하려는 우편 서비스, *domain name*(도메인 이름)은 시 또는 마을, *port*(포트)는 우편 번호, *path*(경로)는 메일이 배달되어야 하는 건물, *parameters*(매개변수)는 건물의 아파트 번호와 같은 추가 정보, 마지막으로 *anchor*(앵커)는 메일을 보낸 실제 사람을 나타냅니다.

**참고:** URL과 관련하여 몇 가지 추가 부분과 추가 규칙이 있지만 일반 사용자 또는 웹 개발자와는 관련이 없습니다. 이건 걱정하지 않아도 괜찮습니다. 완전히 작동하는 URL을 구축하고 사용하기 위해 이것을 알 필요는 없습니다.

스키마
---

![스키마](/ko/docs/Learn/Common_questions/Web_mechanics/What_is_a_URL/mdn-url-protocol@x2_update.png)

URL의 첫 번째 부분은 브라우저가 리소스를 요청하는 데 사용해야 하는 프로토콜을 나타냅니다.(프로토콜은 컴퓨터 네트워크에서 데이터를 교환하거나 전송하기 위한 설정 방법입니다). 일반적으로 웹사이트의 경우 프로토콜은 HTTPS 또는 HTTP(보안되지 않은 버전)입니다. 웹 페이지의 주소를 지정하려면 이 두 가지 중 하나가 필요하지만 브라우저는 `mailto:` (메일 클라이언트를 열기 위해)와 같은 다른 체계를 처리하는 방법도 알고 있으므로 다른 프로토콜이 보이더라도 놀라지 마세요.

권한
--

![권한](/ko/docs/Learn/Common_questions/Web_mechanics/What_is_a_URL/mdn-url-authority.png)

그 다음에는 권한(authority)이 뒤따르며 문자 패턴 `://`에 의해 스키마와 구분됩니다. 만약 존재한다면 권한에는 콜론으로 구분된 도메인(예: `www.example.com`)과 포트(`80`)가 모두 포함됩니다.

* 도메인은 요청하는 웹 서버를 나타냅니다. 도메인은 일반적으로 도메인 이름 (en-US)이지만 IP 주소도 사용될 수 있습니다. (그러나 이것은 훨씬 불편하기 때문에 자주 사용하지 않습니다.)
* 포트는 웹 서버의 리소스에 접근하는 데 사용되는 기술적인 "게이트"를 나타냅니다. 웹 서버가 리소스에 대한 액세스 권한을 부여하기 위해 HTTP 프로토콜의 표준 포트(HTTP의 경우 80, HTTPS의 경우 443)를 사용하는 경우엔 일반적으로 생략합니다. 그렇지 않으면 필수입니다.

**참고:** 스키마와 권한 사이의 구분 기호는 `://`입니다. 콜론은 스키마를 URL의 다음 부분과 구분하고 `//`는 URL의 다음 부분이 권한임을 나타냅니다.

권한을 사용하지 않는 URL의 한 예시는 메일 클라이언트(`mailto:foobar`)입니다. 스키마는 포함하지만 권한 구성 요소는 사용하지 않습니다. 따라서 콜론 뒤에 두 개의 슬래시가 오지 않고 콜론은 스키마와 메일 주소 사이의 구분 기호 역할만 합니다.

리소스 경로
------

![파일 경로](/ko/docs/Learn/Common_questions/Web_mechanics/What_is_a_URL/mdn-url-path@x2.png)

`/path/to/myfile.html`은 웹 서버에 있는 리소스의 경로입니다. 웹 초기에는 이와 같은 경로가 웹 서버의 실제 파일 위치를 나타냈습니다. 요즘에는 대부분 물리적 실체가 없는 웹 서버가 추상적으로 처리합니다.

매개변수
----

![매개변수](/ko/docs/Learn/Common_questions/Web_mechanics/What_is_a_URL/mdn-url-parameters@x2.png)

`?key1=value1&key2=value2`는 웹 서버에 제공되는 추가 매개변수입니다. 이러한 매개변수는 `&` 기호로 구분된 키/값 쌍 목록입니다. 웹 서버는 리소스를 반환하기 전에 이러한 매개변수를 사용하여 추가 작업을 수행할 수 있습니다. 각 웹 서버에는 매개변수에 관한 고유한 규칙이 있으며 특정 웹 서버가 매개변수를 처리하는지 알 수 있는 신뢰할 수 있는 유일한 방법은 웹 서버 소유자에게 물어보는 것입니다.

앵커
--

![앵커](/ko/docs/Learn/Common_questions/Web_mechanics/What_is_a_URL/mdn-url-anchor@x2.png)

`#SomewhereInTheDocument`는 리소스 자체의 어떤 부분에 대한 앵커입니다. 앵커는 리소스 내부에서 일종의 "책갈피" 역할을 하며, 브라우저에 해당 "책갈피" 지점의 콘텐츠를 표시하도록 지시합니다. 예를 들어 HTML 문서에서는 브라우저가 앵커가 정의된 지점으로 스크롤합니다. 비디오 또는 오디오 문서에서 브라우저는 앵커가 나타내는 시간으로 이동하려고 시도합니다. **프래그먼트 식별자**라고도 하는 `#` 뒤의 부분은 요청과 함께 서버로 전송되지 않는다는 점은 주목할 가치가 있습니다.

URL을 사용하는 법
-----------

어떤 URL이든 브라우저의 주소 표시줄에 직접 입력면 리소스에 액세스할 수 있습니다. 그러나 이것은 빙산의 일각에 불과합니다!

다음에 설명할 HTML 언어는 URL을 광범위하게 사용합니다.

* `<a>` 요소를 사용하여 다른 문서에 대한 링크를 생성합니다.
* `<link>` 또는 `<script>`와 같은 다양한 요소를 통해 문서와 관련 리소스를 연결합니다.
* 이미지(`<img>` 요소), 비디오(`<video>` 요소), 사운드 및 음악(`<audio>` (en-US) 요소) 등과 같은 미디어를 표시합니다.
* `<iframe>` (en-US) 요소로 다른 HTML 문서를 표시합니다.

**참고:** 페이지의 일부로 로드할 리소스의 URL을 지정할 땐(예: `<script>`, `<audio>`, `<img>`, `<video>`등을 사용할 때) 몇 가지 예외가 있지만(주목할 만한 것 중 하나는 `data:`입니다. 데이터 URL 참조) 일반적으로 HTTP와 HTTPS URL만 사용해야 합니다. 예를 들어 FTP 사용은 안전하지 않으며 최신 브라우저에서 더 이상 지원되지 않습니다.

CSS 또는 JavaScript와 같은 다른 기술은 URL을 광범위하게 사용하며 이것은 실제로 웹의 핵심입니다.

절대 URL vs 상대 URL
----------------

앞서 본 URL을 절대 URL이라고 하지만 상대 URL이라는 것도 있습니다. URL 표준은 URL 객체(URL의 메모리 내 표현)와 구별하기 위해 절대 URL 문자열과 상대 URL 문자열이라는 용어를 사용하지만 둘 다 정의합니다.

URL의 맥락에서 절대와 상대의 차이가 무엇을 의미하는지 살펴보겠습니다.

URL의 필수 부분은 URL이 사용되는 컨텍스트에 따라 크게 달라집니다. 브라우저의 주소 표시줄에서 URL에는 아무 맥락이 없으므로 위에서 본 것과 같은 전체(또는 절대) URL을 제공해야 합니다. 프로토콜(브라우저는 기본적으로 HTTP를 사용함)이나 포트(대상 웹 서버가 비정상적인 포트를 사용하는 경우에만 필요함)를 포함할 필요는 없지만 URL의 다른 모든 부분은 필요합니다.

URL이 HTML 페이지와 같은 문서 내에서 사용되는 경우, 상황이 약간 다릅니다. 브라우저에는 이미 문서 고유의 URL이 있기 때문에 이 정보를 사용하여 해당 문서 내에서 사용할 수 있는 URL의 누락된 부분을 채울 수 있습니다. URL의 경로 부분만 보면 절대 URL과 상대 URL을 구별할 수 있습니다. URL의 경로 부분이 "`/`" 문자로 시작하는 경우 브라우저는 현재 문서에서 제공하는 맥락을 참조하지 않고 서버의 최상위 루트에서 해당 리소스를 가져옵니다.

명확히 이해하기 위해 몇 가지 예를 살펴보겠습니다.

### 절대 URL의 예

|  |  |
| --- | --- |
| 전체 URL(앞서 사용한 것과 동일) |
```
https://developer.mozilla.org/ko/docs/Learn
```
 |
| 암시적 프로토콜 |
```
//developer.mozilla.org/ko/docs/Learn
```

이 경우 브라우저는 해당 URL을 호스팅하는 문서를 로드하는 데 사용된 것과 동일한 프로토콜로 해당 URL을 호출합니다. |
| 암시적 도메인 이름 |
```
/ko/docs/Learn
```

HTML 문서 내 절대 URL의 가장 일반적인 사용 사례입니다. 브라우저는 해당 URL을 호스팅하는 문서를 로드하는 데 사용된 것과 동일한 프로토콜과 동일한 도메인 이름을 사용합니다. **참고:** 프로토콜도 생략하지 않고 도메인 이름만 생략할 수 없습니다. |

### 상대 URL의 예

다음 예제를 더 잘 이해하기 위해 다음 URL에 있는 문서 내에서 URL이 호출된다고 가정해 보겠습니다. `https://developer.mozilla.org/ko/docs/Learn`

|  |  |
| --- | --- |
| 하위 리소스 |
```
Skills/Infrastructure/Understanding_URLs
```

URL이 `/`로 시작하지 않기 때문에 브라우저는 현재 리소스가 포함된 하위 디렉터리에서 문서를 찾으려고 시도합니다. 따라서 이 예시에서는 https://developer.mozilla.org/ko/docs/Learn/Skills/Infrastructure/Understanding\_URLs URL에 도달하려고 합니다. |
| 디렉터리 트리로 돌아가기 |
```
../CSS/display
```

이 경우 UNIX 파일 시스템 세계에서 가져온 `../` 작성 규칙을 사용하여 브라우저에 한 디렉토리에서 위로 이동하고 싶다고 알립니다. 여기서는 https://developer.mozilla.org/ko/docs/Learn/../CSS/display URL에 도달하려고 합고, https://developer.mozilla.org/ko/docs/CSS/display으로 단순화될 수 있습니다. |

시맨틱 URL
-------

매우 기술적인 특징에도 불구하고 URL은 사람이 읽을 수 있는 웹 사이트 진입점을 나타냅니다. 기억할 수 있으며 누구나 브라우저의 주소 표시줄에 입력할 수 있습니다. 사람은 웹의 핵심이므로 시맨틱 URL이라고 하는 것을 구축하는 것이 모범 사례로 간주됩니다. 시맨틱 URL은 기술적 노하우와 상관없이 누구나 이해할 수 있는 고유의 의미를 가진 단어를 사용합니다.

언어 의미론은 물론 컴퓨터와 관련이 없습니다. 임의 문자로 이루어진 URL을 자주 보셨을 것입니다. 그러나 사람이 읽을 수 있는 URL을 만들면 많은 이점이 있습니다.

* URL을 쉽게 조작할 수 있습니다.
* 사용자가 어디에 있는지, 무엇을 하고 있는지, 웹에서 무엇을 읽거나 상호 작용하는지에 대해 사용자에게 명확하게 설명합니다.
* 일부 검색 엔진은 이러한 의미 체계를 사용하여 관련 페이지의 분류를 개선할 수 있습니다.
같이 보기
-----

데이터 URL: `data:` 스키마가 접두사로 붙은 URL은 콘텐츠 작성자가 문서에 작은 파일을 인라인으로 포함할 수 있도록 합니다.


What are hyperlinks? - Web 개발 학습하기

What are hyperlinks?
====================

이 글에서, 우리는 하이퍼링크가 무엇이고 왜 중요한지를 살필 것이다.

|  |  |
| --- | --- |
| 선수지식: | 인터넷이 작동하는 법을
 알아야 하고
 웹 페이지, 웹사이트, 웹 서버 그리고 검색엔진의 차이 (en-US)에 익숙해야 한다.
  |
| 목적: | 하이퍼링크가 무엇이고 왜 중요한지를 배울 것이다. |

요약
--

보통 링크라고 불리는 하이퍼링크는 웹에서 기본적인 개념이다. 링크가 무엇인 지 설명하기 위해, 웹의 매우 기본적인 구조로 돌아볼 필요가 있다.

1989년으로 돌아가, 웹의 발명가인 Tim Berners-Lee는 웹을 대표하는 3가지 축에 대해 말하였다. :

1. URL, 웹 문서를 추적하는 주소 시스템
2. HTTP, URL들이 주어졌을 때, 문서들을 찾는 전송 프로토콜
3. HTML, 내장된 *hyperlinks* 를 허용하는 문서 형식

3가지 축에서 본 것처럼, 웹에 대한 모든 것들은 문서들과 어떻게 문서에 접근할 것인 지에 관련되어 있다. 웹의 기본 목적은 텍스트 문서를 통해서 도달하고, 읽고, 찾기쉬운 방식을 제공하는 것이다. 그리고 나서, 웹은 이미지와 동영상, 이진 데이터에 접근하는 것을 제공하도록 진화했다. 그러나, 이런 발전은 3가지 축은 거의 바꾸지 못 하였다.

웹 이전에는, 문서에 접근하고 문서끼리 이동하는 것은 꽤 어려웠다. 인간이 읽을 수 있는 URL은 이런 것들을 훨씬 쉽게 만들었다. 하지만, 문서에 접근할 때마다 긴 URL을 타이핑하는 것은 어려웠다. 이것이 하이퍼링크가 개혁한 모든 것이다. 링크는 URL을 가진 텍스트와 연결될 수 있다. 그렇게 된 링크를 활성화함으로써, 타겟 문서에 즉시 도달할 수 있다.

기본적으로 파란색으로 밑줄이 된 링크는 주위 텍스트에서 보여진다. 활성화하기 위해 링크를 클릭하거나 Tab키로 링크를 선택하고 Enter키나 Space바를 누르면 된다.

![Example of a basic display and effect of a link in a web page](/ko/docs/Learn/Common_questions/Web_mechanics/What_are_hyperlinks/link-1.png)

링크는 웹을 유용하고 성공적으로 만든 돌파구이다. 이 글의 나머지엔, 다양한 유형의 링크와 현대 웹 디자인의 중요성을 얘기할 것이다.

깊게 들어가기
-------

다시 말하면, 링크는 URL이 연결된 텍스트이다. 그리고, 링크를 사용하면, 하나의 문서에서 다른 문서로 쉽게 이동할 수 있다. 이런 내용들을 말하다보면, 몇몇의 생각해볼 뉘앙스차이가 있다.

### 링크의 유형들

Internal link(내부 링크)

당신의 웹사이트에 속하는 두 개의 웹사이트 사이의 링크는 내부 링크라고 불린다. 내부 링크가 없다면, 웹 사이트와 같은 것은 없을 것이다. (물론, 한 페이지의 웹 사이트 빼고).

External link(외부 링크)

당신의 웹사이트에서 다른 사람의 웹사이트로 가는 링크이다. 외부 링크가 없다면, 웹이 존재하지 않는다. 왜냐하면 웹은 웹페이지들의 네트워크이기 때문이다. 당신이 유지하는 내용 외의 정보를 제공하기위해 외부 링크를 사용해라.

Incoming links(들어오는 링크)

다른 사람의 웹 사이트에서 당신의 사이트로 가는 링크이다. 단지 외부링크의 반대이다. 누군가 당신의 사이트로 링크를 걸 때 당신이 역으로 링크를 걸 필요하는 없다는 것을 기록해라.

당신이 웹사이트를 구축할 때, 내부링크에 집중해야 한다. 왜냐하면 내부링크가 당신의 사이트를 사용가능하게 해주기 때문이다. 링크가 너무 많거나 너무 적지 않게 좋은 밸런스를 찾아야 한다. 우리는 다른 글에서 웹 사이트 네비게이션을 디자인하는 것에 대해 이야기 할 것이다. 그러나 룰로써, 당신이 새 웹페이지를 추가할 때마다, 적어도 당신의 1개 이상의 페이지에는 새 페이지에 대한 링크를 걸어야 한다. 반면에, 만약 당신의 사이트가 10페이지 이상이라면, 모든 페이지에 링크를 거는 것은 역효과이다.

당신이 처음 시작할 때, 외부와 들어오는 링크를 많이 걱정할 필요가 없다. 그러나, 그것들은 검색 엔진에서 당신의 사이트를 찾을 때, 매우 중요하다. (자세한 사항은 밑에 있다.)

### Anchors(앵커)

대부분의 링크는 두 개의 웹사이트를 연결한다. **앵커**는한 문서에서 다른 부분들을 연결한다. 앵커가 가리키는 링크를 따라가면, 브라우저는 새 문서를 불러오는 것 대신에 현재 문서의 다른 부분으로 이동한다. 그러나 다른 링크과 같은 방식으로 만들고 사용한다.

![Example of a basic display and effect of an anchor in a web page](/ko/docs/Learn/Common_questions/Web_mechanics/What_are_hyperlinks/link-2.png)

### 링크와 검색엔진

링크는 유저와 검색엔진 모두에게 중요하다. 검색 엔진이 웹페이지를 크롤링할 때마다, 검색엔진은 웹 페이지에서 이용가능한 링크를 따라가면서 웹 사이트를 인덱싱한다. 검색 엔진이 웹 사이트의 다양한 페이지를 발견하기 위해 링크를 따라가는 것뿐만 아니라 타켓 웹페이지에 도달하기 위해 어떤 검색 쿼리가 적절한 지를 결정하기 위해 링크의 텍스트를 사용한다.

그래서 링크는 얼마나 쉽게 검색 엔진이 너의 사이트를 찾는 지에 영향을 미친다. 문제는 검색 엔진의 활동을 측정하는 것은 어렵다. 회사들은 그들의 사이트가 검색 결과에 높은 랭크가 되기를 자연스럽게 원한다. 그리고, 모든 연구 결과는 적어도 몇몇은 분명하게 해준다.

* 링크의 *텍스트*는 어떤 컴색 쿼리들이 주어진 URL을 찾는 지에 영향을 미친다.
* 웹 페이지가 더 많은 *들어오는 링크*를 자랑할 수 있다면, 검색 결과 랭킹은 더 높이진다.
* *외부 링크*는 소스 웹페이와 타겟 웹페이지의 검색 랭킹에 영향을 미친다. 그러나 얼마나 많은 지는 분명치 않다.

SEO (search engine optimization, 검색 엔진 최적화)는 검색 결과에 웹페이지 랭크를 높게 만드는 법에 대한 연구이다. 웹페이지의 링크 사용을 증가시키는 것이 유용한 SEO 기법이다.

다음 단계
-----

그래서 이젠, 당신은 링크가 있는 웹페이지들을 설정하고 싶을 것이다!

* 더 많은 이론적인 배경을 배우기 위해, URLs 과 구조를 배울 것이다. 왜냐하면 모든 링크는 URL을 가리키기 때문이다.
* 좀 더 실용적인 것을 원하나요? HTML 도입 중 하이퍼 링크 만들기 모듈은 링크를 구현하는 법에 대한 상세한 내용을 설명한다.


인터넷은 어떻게 동작하는가? - Web 개발 학습하기

인터넷은 어떻게 동작하는가?
===============

이 글에서는 인터넷의 개념과 작동 원리에 대해 설명합니다.

|  |  |
| --- | --- |
| 선행지식: | 선행지식은 필요없습니다. 하지만 '프로젝트의 목표 설정에 대한 글(Article on setting project goals (en-US))에 대한 글을 먼저 읽어보세요. |
| 목적: | 웹 기술 인프라의 기초와 인터넷과 웹의 차이점을 배우게 됩니다. |

요약
--

**인터넷**은 웹의 핵심적인 기술입니다. 인터넷의 가장 기본적인 것은, 컴퓨터들이 서로 통신 가능한 거대한 네트워크라는 것입니다.

인터넷의 역사는 잘 알려지지 않았습니다. 인터넷은 1960년 대 미육군에서 기금한 연구 프로젝트에서 시작되었습니다. 그리고 1980년 대에 많은 국립 대학과 비공개 기업의 지원으로 공공의 기반으로 변화되었습니다. 인터넷을 지원하는 다양한 기술은 시간이 지남에 따라 진화 해 왔지만 작동 방식은 그다지 변하지 않았습니다. 인터넷은 모든 컴퓨터를 연결하고 어떤 일이 있어도 연결 상태를 유지할 수있는 방법을 찾는 방법입니다.

활동적으로 배우기
---------

* How the internet Works in 5 minutes: Aaron Titus의 인터넷에 대한 기초를 이해하기 위한 5분짜리 동영상
깊게 들어가기
-------

### 단순한 네트워크

두 개의 컴퓨터가 통신이 필요할 때, 우리는 다른 컴퓨터와 물리적으로 (보통 이더넷 케이블) 또는 무선으로 (예를 들어, WiFi 나 Bluetooth 시스템) 연결되어야 합니다. 모든 현대 컴퓨터들은 이러한 연결 중 하나를 이용하여 연결을 지속할 수 있습니다.

**참고:** 이 글의 나머지 부분에서는 유선 케이블에 대해서만 이야기 하지만 무선 네트워크도 동일한 방식입니다.

![Two computers linked together](/ko/docs/Learn/Common_questions/Web_mechanics/How_does_the_Internet_work/internet-schema-1.png)

이러한 네트워크는 두 대의 컴퓨터로 제한되지 않습니다. 원하는 만큼의 컴퓨터를 연결할 수 있습니다. 그러나 이렇게 연결할 수록 매우 복잡해집니다. 예를 들어 10대의 컴퓨터를 연결하려는 경우 컴퓨터 당 9개의 플러그가 달린 45개의 케이블이 필요합니다!

![Ten computers all together](/ko/docs/Learn/Common_questions/Web_mechanics/How_does_the_Internet_work/internet-schema-2.png)

이 문제를 해결하기 위해 네트워크의 각 컴퓨터는 라우터라고하는 특수한 소형 컴퓨터에 연결됩니다. 이 라우터에는 단 하나의 작업만 있습니다. 철도역의 신호원처럼 주어진 컴퓨터에서 보낸 메시지가 올바른 대상 컴퓨터에 도착하는지 확인합니다. 컴퓨터 B에게 메시지를 보내려면 컴퓨터 A가 메시지를 라우터로 보내야하며, 라우터는 메시지를 컴퓨터 B로 전달하고 메시지가 컴퓨터 C로 배달되지 않도록해야합니다.

이 라우터를 시스템에 추가하면 10대의 컴퓨터 네트워크에는 10개의 케이블만 필요합니다. 각 컴퓨터마다 단일 플러그와 10개의 플러그가 있는 하나의 라우터가 필요합니다.

![Ten computers with a router](/ko/docs/Learn/Common_questions/Web_mechanics/How_does_the_Internet_work/internet-schema-3.png)

### 네트워크 속의 네트워크

지금까지는 그런대로 잘되었습니다. 수백, 수천, 수십억 대의 컴퓨터를 연결하는 것은 어떨까요? 물론 단일 라우터는 그 정도까지 확장 할 수는 없지만 신중하게 읽으면 라우터는 다른 컴퓨터와 마찬가지로 컴퓨터라고 말했습니다. 그럼, 두 대의 라우터를 연결하지 못하게 하는 것이 있을까요? 없죠!

![Two routers linked together](/ko/docs/Learn/Common_questions/Web_mechanics/How_does_the_Internet_work/internet-schema-4.png)

컴퓨터를 라우터에 연결하고, 라우터에서 라우터로, 우리는 무한히 확장할 수 있습니다.

![Routers linked to routers](/ko/docs/Learn/Common_questions/Web_mechanics/How_does_the_Internet_work/internet-schema-5.png)

이러한 네트워크는 우리가 인터넷이라고 부르는 것에 매우 가깝지만, 우리는 뭔가를 놓치고 있습니다. 우리는 우리의 목적을 가지고 네트워크를 구축했습니다. 하지만 그밖에 다른 네트워크들 : 친구, 이웃, 누구든지 컴퓨터로 이루어진 그들만의 네트워크를 가질 수 있습니다. 하지만 집과 다른 지역 사이에, 아주 먼 곳에 케이블을 연결할 수는 없습니다. 이 문제를 어떻게 처리 할 수 있을까요? 예를 들어 전력 및 전화와 같이 이미 집에 연결된 케이블이 있습니다. 전화기 기반의 시설은 이미 세계 어느 곳과도 연결되어 있으므로 우리가 필요로 하는 완벽한 배선이라고 할 수 있습니다. 따라서 우리의 네트워크를 전화 시설과 연결하기 위해선, 모뎀이라는 특수 장비가 필요합니다. 이 모뎀은 우리 네트워크의 정보를 전화 시설에서 처리 할 수있는 정보로 바꾸며, 그 반대의 경우도 마찬가지입니다.

![A router linked to a modem](/ko/docs/Learn/Common_questions/Web_mechanics/How_does_the_Internet_work/internet-schema-6.png)

그래서 우리의 네트워크는 전화 시설에 연결됩니다. 다음 단계는 우리의 네트워크에서 도달하려는 네트워크로 메시지를 보내는 것입니다. 그렇게하기 위해 네트워크를 인터넷 서비스 제공 업체 (Internet Service Provider, ISP)에 연결합니다. ISP는 모두 함께 연결되는 몇몇 특수한 라우터를 관리하고 다른 ISP의 라우터에도 액세스 할 수 있는 회사입니다. 따라서 우리 네트워크의 메시지는 ISP 네트워크의 네트워크를 통해 대상 네트워크로 전달됩니다. 인터넷은 이러한 전체 네트워크 인프라로 구성됩니다.

![Full Internet stack](/ko/docs/Learn/Common_questions/Web_mechanics/How_does_the_Internet_work/internet-schema-7.png)

### 컴퓨터 찾기

컴퓨터에 메시지를 보내려면 메시지를 받을 특정 컴퓨터를 지정해야합니다. 따라서 네트워크에 연결된 모든 컴퓨터에는 IP 주소 (IP는 인터넷 프로토콜을 나타냄)라는 고유한 주소가 있습니다. 주소는 점으로 구분 된 네 개의 숫자로 구성된 주소입니다 . 예: `192.168.2.10`.

컴퓨터는 이러한 주소로 다른 컴퓨터를 찾아가는데 문제가 없습니다. 그러나 우리들은 IP주소를 기억하기 어렵죠. 그래서 우리는 '도메인 이름' 이라고하는 사람이 읽을 수 있는 IP 주소의 이름을 지정할 수 있습니다. 예를 들어 `'google.com'`은 IP 주소로 `'173.194.121.32'` 입니다. 따라서 '도메인 이름'은 'IP주소'보다 인터넷을 사용하기에 쉽습니다.

![Show how a domain name can alias an IP address](/ko/docs/Learn/Common_questions/Web_mechanics/How_does_the_Internet_work/dns-ip.png)

### 인터넷과 웹

웹 브라우저를 사용하여 웹을 탐색 할 때 일반적으로 도메인 이름을 사용하여 웹 사이트에 접속합니다. 그것은 인터넷과 웹이 같은 것을 의미할까요? 그렇게 간단하지 않습니다. 앞에서 보았 듯이 인터넷은 수십억 대의 컴퓨터를 모두 연결하는 기술 인프라입니다. 이러한 컴퓨터들 중에 일부는 '웹 서버'로서 웹 브라우저가 이해할 수 있는 서비스를 제공합니다. 인터넷은 인프라이며, 웹은 그 인프라 기반 위에 구축된 서비스입니다. 웹 뿐만 아니라 인터넷 위에 구축된 다른 서비스들(이메일, IRC 등)도 있음을 알아야합니다.

다음 단계
-----

* How the Web works(웹이 작동하는 방법)
* Understanding the difference between a web page, a web site, a web server and a search engine(웹 페이지, 웹 사이트, 웹 서버, 검색 엔진의 차이점 이해하기) (en-US)
* Understanding domain names(도메인 이름 이해하기) (en-US)


웹페이지, 웹사이트, 웹서버 그리고 검색엔진의 차이는 무엇일까요? - Web 개발 학습하기

웹페이지, 웹사이트, 웹서버 그리고 검색엔진의 차이는 무엇일까요?
====================================

이번 글에서는 다양한 웹 관련 개념들을 이야기합니다: 웹, 페이지, 웹사이트, 웹서버, 검색엔진. 이런 용어들은 흔히 웹을 처음 배우는 사람이나 잘못 배운 사람들에게 혼란스럽습니다. 이것들이 무엇을 의미하는 지 배워봅시다!

|  |  |
| --- | --- |
| 요구지식: | how the Internet works(인터넷이 작동하는 법)을 배워야 한다. |
| 목적: | 웹페이지, 웹사이트, 웹서버, 검색엔진의 차이점을 논할 수 있다. |

요약
--

지식의 범위에 따라, 웹은 많은 용어가 있습니다. 걱정마세요, 우리는 그런 모든 것들로 여러분을 억누르지 않을 것입니다. (궁금하시다면, glossary(용어사전) 이 있습니다.) 하지만 여러분이 처음에 이해할 필요가 있는 기본적인 용어들이 있습니다. 왜냐하면, 읽는 내내, 이런 표현들을 보게될 것이기 때문이다. 때때로 이런 용어들은 혼동하기 쉽습니다. 왜냐하면 다른 기능을 가지고 있지만 관련있는 것으로 언급되기 때문이죠. 사실, 뉴스 기사 등에서 이따금 잘못 사용된 이런 용어들을 볼 수 있을 것입니다. 그래서 그것들이 혼동되는 것은 당연합니다!

나아가서 더 자세한 용어와 기술들을 다룰 것입니다. 하지만, 앞서 정의해보는 것은 시작하는 데 도움이 될 것입니다:

웹 페이지

Firefox, 구글 크롬, 오페라, MS 익스플로러나 엣지, 애플의 Safari 같은 웹 브라우저에서 보여지는 문서이다. 이런 것들을 단순히 "페이지"라고 하기도 한다.

웹사이트

다양한 방식으로 그룹으로 묶이거나 연결된 웹 페이지들의 모음이다. 보통 "웹사이트"나 단순히 "사이트"라고 한다.

웹 서버

인터넷에 웹사이트를 호스팅하는 컴퓨터이다.

검색 엔진

구글, 빙, 야후 같은 다른 웹 페이지들을 찾게 도와주는 웹사이트이다.

도서관과 간단한 유사점을 보자. 아래는 도서관에 방문했을 때, 일반적으로 하는 일이다:

1. 검색 색인을 발견하고 원하는 책의 제목을 찾는다.
2. 책의 분류번호를 기록한다.
3. 그 책이 있는 구역으로 간 뒤, 올바른 분류번호를 찾고, 책을 얻는다.

웹 서버와 도서관을 비교해보자.

* 도서관은 웹 서버와 같다. 도서관은 여러 구역이 있는데, 이것은 다양한 웹사이트들을 호스팅하는 서버와 비슷합니다.
* 도서관에 있는 과학, 수학, 역사와 같은 각기 다른 구역들은 웹사이트와 같습니다. 각각의 구역은 유일한 웹사이트입니다. (두 개의 구역이 같은 책을 포함하지 않는다.)
* 구역에 있는 책들은 웹페이지와 같다. 한 웹사이트는 여러 웹페이지들을 가지고 있을 수 있습니다. 예를 들어, 과학 섹션(웹사이트)는 열, 소리, 열역학, 정역학 등의 책(웹페이지)를 가지고 있을 것이다.
* 검색 색인은 검색 엔진과 같다. 각각의 책은 도서관에서 자신만의 위치를 가지고 있다. (두 개의 책이 같은 위치에 놓일 수 없다.) 이 위치는 분류번호로 정해진다.
* 비슷하게, 웹페이지는 유일한 주소를 갖습니다. 이런 주소들은 파이폭스, 크롬, Safari같은 웹 브라우저의 주소창에 주소를 적으면 웹 서버에서 웹페이지를 검색하기 위해 사용됩니다.
Active learning
---------------

*There is no active learning available yet. Please, consider contributing.*

깊게 들어가기
-------

4개의 용어가 얼마나 관련됐는지, 서로 헷갈리는 이유가 무엇인지를 더 깊게 알아봅시다.

### 웹 페이지

웹 페이지는 browser(브라우저)를 통해 보여지는 단순한 문서입니다. 이런 문서는 HTML 언어로 쓰여집니다. (다른 글에서 더 자세히 알 수 있다) 웹 페이지는 다양한 다른 종류의 자원을 포함할 수 있습니다:

* *style information(스타일 정보)* — 페이지의 외관과 느낌을 관리
* *scripts(스크립트)* — 페이지에 interactivity(대화식 이용)을 첨가
* *media*(미디어) — 사진, 소리, 동영상

>
> \*\*참고:\*\*브라우저는 또한 PDF 파일이나 이미지를 보여줄 수 있다. 그러나 **웹 페이지**는 HTML 문서를 의미하는 용어이다. 아니라면 우리는 **문서**(**document**)라는 용어를 사용한다.
>
>
>

웹에서 이용하는 모든 웹 페이지는 유일한 주소를 통해 접근할 수 있습니다. 한 페이지에 접근하기 위해서는, 브라우저의 주소창에 주소를 적으면 됩니다.

![Example of a web page address in the browser address bar](/ko/docs/Learn/Common_questions/Web_mechanics/Pages_sites_servers_and_search_engines/web-page.jpg)

*웹사이트* 는 유일한 도메인 이름을 같이 사용하는 연결된 웹 페이지들의 모음입니다. (관련된 자원도 포함된다.) 각각의 웹사이트에서 분명한 링크가 주어진 웹 페이지들은 유저가 그 웹사이트의 한 페이지에서 다른 페이지로 이동하게 합니다. 보통 클릭할 수 있는 형태로 되어있습니다.

웹사이트에 접근하기 위해서, 브라우저 주소 창에 도메인 이름을 적으면, 브라우저는 웹사이트의 메인 페이지나 *홈페이지* (보통 "홈"이라 하는)를 보여줄 것이다:

![Example of a web site domain name in the browser address bar](/ko/docs/Learn/Common_questions/Web_mechanics/Pages_sites_servers_and_search_engines/web-site.jpg)

*웹 페이지* 와 *웹사이트 에 대한 생각은* 특히 하나의*웹 페이지*만 포함하는 *웹사이트*에서 혼동하기 쉽습니다. 이런 웹사이트를 보통 a \*single-page website(싱글 페이지 웹사이트)\*라고 합니다.

### 웹 서버

##### *웹 서버*는 한 개 이상의 *웹사이트*를 호스팅하는 컴퓨터입니다. "호스팅"은 모든 *웹 페이지* 및 웹 페이지가 지원하는 파일들을 컴퓨터에서 이용할 수 있다는 것을 의미한다. *웹 서버*는 유저의 request(요청)마다 호스팅하는 *웹사이트*에서 유저의 브라우저로 *웹 페이지*를 보낼 것이다

*웹 사이트*와 *웹 서버*를 혼동하지 마라. 예를 들어, 당신이 누군가 "내 웹사이트가 반응하지 않는다." 라고 말하는 것을 들었다면, 그것은 사실 *웹 서버*가 반응하지 않는다는 의미이다. 그러므로 *웹사이트*를 이용하지 못 한다. 더 중요하게, *웹 서버*는 여러 웹사이트에 호스팅될 수 있기 때문에, 웹 서버라는 용어는 절대 웹사이트를 지정하기 위해 사용하지 않는다. 그것이 큰 혼란을 일으킬 수 있기 때문이다. 아까의 예처럼, 만약 우리가 "내 웹 서버가 반응하지 않는다." 라고 하면, 그것은 웹 서버가 이용할 수 있는 웹 사이트가 없다는 것을 의미한다.

### 검색 엔진

검색 엔진은 웹에서 흔한 혼란의 근원입니다. 검색 엔진은 웹 페이지를 *다른* 웹사이트에서 찾을 수 있게 도와주는 특별한 종류의 웹사이트입니다.

검색 엔진은 다음과 같습니다: Google, Bing, Yandex, DuckDuckGo, 그리고 더 많은 검색 엔진들이 있습니다. 일부는 일반적인 것을 위한 것이고, 일부는 특정한 주제에 특화되어 있습니다. 선호하는 것을 사용하면 됩니다.

많은 웹 초보자들은 검색 엔진과 브라우저를 혼돈합니다. 분명히 합시다: ***브라우저***는 소프트웨어의 한 조각으로, 웹 페이지를 검색하고 보여줍니다; ***검색 엔진***은 사람들이 다른 웹사이트에서 웹 페이지를 찾도록 도와주는 웹 사이트입니다. 혼란이 생기는 이유는, 처음 브라우저를 실행하면, 브라우저는 검색 엔진의 홈페이지를 보여주기 때문입니다. 이것이 의미있는 이유는 브라우저로 가장 하고 싶은 일이 보여줄 웹 페이지를 찾는 것이기 때문이다. 브라우저같은 기반 시설을 검색엔진 같은 서비스와 혼동하지마세요. 이것을 구별하는 것이 상당히 도움이 될 것입니다. 그러나 몇몇의 전문가들도 느슨하게 말하므로, 염려하지 않아도 됩니다.

기본 시작 페이지로 구글 검색 상자를 보여주는 파이어폭스의 한 예입니다.

![Example of Firefox nightly displaying a custom Google page as default](/ko/docs/Learn/Common_questions/Web_mechanics/Pages_sites_servers_and_search_engines/search-engine.jpg)

다음 단계
-----

* 더 깊게 들어가기: What is a web server(웹 서버란 무엇인가) (en-US)
* 웹 페이지들이 웹 사이트로 연결되는 방법 보기: Understanding links on the web(웹에서의 연결 이해하기) (en-US)


어떤 HTML 기능이 접근성을 촉진할까? - Web 개발 학습하기

어떤 HTML 기능이 접근성을 촉진할까?
======================

이번 내용은 웹 페이지를 좀 더 서로 다른 장애를 가진 사람들에게 좀 더 접근하기 쉽게 만들 수 있는 HTML의 특정한 기능을 서술합니다.

탭(Tabbing)
----------

pointing devices를 사용 하지 않거나 사용 할 수 없는 유저들은 `Tab` 을 links를 통해 할 수 있습니다.(links는 논리적 순서로 이루어져 있어야 합니다.) tabindex 속성은 당신이 이러한 순서를 정의 할 수 있도록 허락합니다. 만약 HTML이 선형이라면, 논리적 탭 순서는 자동적으로 맞춰집니다.

```html
<ul>
  <li><a href="here.html" tabindex="1">Here</a></li>
  <li><a href="there.html" tabindex="3">There</a></li>
  <li><a href="anywhere.html" tabindex="2">Anywhere</a></li>
</ul>
```

이번 예시는(순수히 데모를 위해 사용되었으니 따라하지 마세요), 탭이 여기서부터 여기저기를 점프합니다.

링크 제목(Link Titles)
------------------

만약 당신이 자신을 설명하지 않는 링크를 가지고 있거나, 링크 목적지가 더 자세하게 설명되지 않으면, 그 링크에 제목 속성을 추가 할 수 있습니다.

```html
<p>
  I'm really bad at writing link text.
  <a
 href="inept.html"
 title="Why I'm rubbish at writing link text: An explanation and an apology."
 >Click here</a
 >
  to find out more.
</p>
```

접근 키(Access Keys)
-----------------

*접근 키는* 링크에 사용자가 `Alt` or `Ctrl` + 접근 키를 입력하여 얻을 수 있는 키보드 단축키를 할당하여 쉬운 네비게이션을 제공합니다. 정확한 키 조합은 플래폼에 따라 다릅니다.

```html
<a href="somepage.html" accesskey="s">Some page</a>
```

링크 넘어가기(Skip Links)
-------------------

탭을 지원하기 위하여, 당신은 유저가 당신의 웹 페이지 모음으로 넘어갈 수 있는 링크를 제공할 수 있습니다. 당신은 아마도 다른 사람이 네비게이션 링크를 따라 점프하기를 원할 것입니다. 그렇게 함으로써, 페이지의 메인 내용을 읽을 수 있습니다.

```html
<header>
  <h1>The Heading</h1>
  <a href="#content">Skip to content</a>
</header>

<nav>
  <!-- navigation stuff -->
</nav>

<section id="content">
  <!--your content -->
</section>
```


나의 웹사이트를 설계하기 위해서는? - Web 개발 학습하기

나의 웹사이트를 설계하기 위해서는?
===================

이 글은 모든 프로젝트에서 중요한 첫 단계 - 프로젝트를 통해 달성하고 싶은 것을 정의하기 - 를 다룬다.

|  |  |
| --- | --- |
| 선이수: | 없음 |
| 목표: | 웹 프로젝트 방향 설정을 위해 목적을 정하는 법을 배운다. |

요약
--

웹 프로젝트를 시작할 때, 많은 사람들은 기술적인 면에 집중한다. 물론 자기 분야의 기술에 익숙해야한다. 그러나 정말 중요한건 무엇을 달성하고 싶은가이다. 당연한 이야기같지만, 생각보다 많은 프로젝트들이 기술적 방법의 부족이 아닌, 목적과 전망의 부족으로 실패한다.

따라서 아이디어를 얻고, 그것을 웹 사이트로 만들고 싶을 때, 다른 것보다 먼저 대답해야할 질문이 있다.

* 내가 달성하고 싶은 것은 정확히 무엇인가?
* 내 목적 달성을 웹사이트가 어떻게 돕는가?
* 목적 달성을 위해 무엇을, 어떤 순서로 해야할까?

이러한 것들을 프로젝트 관념(ideation)이라 한다. 당신이 초보자든 숙련된 개발자든 목표에 도달하기 위해 반드시 거쳐야 할 첫 단계이다.

능동 학습
-----

*아직 가능한 능동 학습이 없다. 기여를 고민해보라.*

깊게 들어가기
-------

프로젝트는 절대 기술에서 시작하지 않는다. 음악가는 무엇을 연주할 지 정하기 전엔 어떤 음악도 만들지 않는다. 화가, 작가, 그리고 웹 개발자도 마찬가지다. 기술은 다음이다.

기술은 분명히 중요하다. 음악가는 기악을 완성해야 한다. 그러나 좋은 음악가는 절대 생각없이 좋은 음악을 만들수 없다. 그러므로 코드와 툴같은 기술로 뛰어들기 전에, 한 걸음 물러서서 하고 싶은 것을 상세히 결정해야 한다.

친구와 함께하는 한 시간의 토론은 좋은 시작이지만 부족하다. 생각을 현실로 만들 길의 탁 트인 전망을 얻으려면 앉아서 생각을 구조화해야한다. 이것을 하기 위해서, 오직 펜과 종이 그리고 적어도 다음 질문에 대한 답할 시간이 필요하다.

**참고:** **메모:** 프로젝트 관념화를 수행하기 위한 셀 수 없는 방법들이 있다. 우리는 여기에 그것들을 모두 제시할 수는 없다. (책 전체로는 충분하지 않을 것이다). 이 곳에 주는 것은 전문가들이 Project Ideation(관념화), Project Planning(계획) 그리고 Project Management(관리) 라고 부르는 것을 다루는 단순한 방법이다.

### 내가 정확히 달성하고 싶은 것은 무엇인가?

이것은 대답해야 하는 가장 중요한 질문이다. 왜냐하면, 이것이 다른 모든 것을 만들기 때문이다. 도달하고 싶은 모든 목표를 목록화해라. 그것은 무엇일 수도 있다: 돈을 벌기 위해 물건 팔기, 정치적인 의견 표현하기, 새로운 친구 만들기, 음악가들과 공연하기, 고양이 사진 모으기, 또는 원하는 무엇이든.

당신이 음악가라고 생각해보자. 이런걸 원할 수 있다.

* 다른 사람들이 내 음악을 듣게 하기
* 관련 상품 팔기
* 다른 음악가들과 만나기
* 내 음악에 대해 이야기하기
* 동영상으로 음악 가르치기
* 내 고양이 사진 출판하기
* 새로운 애인 찾기

일단 이런 리스트를 만들고 나면, 우선순위를 정하는 것이 필요하다. 가장 중요한 것부터 덜 중요한 것까지 목표를 정렬해라.

1. 새로운 애인 찾기
2. 다른 사람들이 내 음악을 듣게 하기
3. 내 음악에 대해 이야기하기
4. 다른 음악가들과 만나기
5. 관련 상품 팔기
6. 동영상으로 음악 가르치기
7. 내 고양이 사진 출판하기

단순한 목표 쓰기와 순위 정하기가 만들고 싶은 것을 결정할 때, 도움이 될 것이다. (내가 이런 특징을 구현해야할까, 이런 서비스를 사용해야할까, 이런 디자인을 만들어야할까?)

우선순위가 정리된 목적 기록부가 생겼으니, 다음 질문으로 이동하자.

### 어떻게 웹사이트가 나를 목적지로 데려다 줄 수 있을까?

그래서 당신은 목표 리스트를 가지고 있고, 그 목표들을 이루기위해 웹사이트가 필요하다고 느낍니다. 확실합니까?

우리의 예를 다시 봅시다. 우리는 음악에 관련된 5개의 목표, 개인 삶(소중한 사람 찾기)에 관련된 하나의 목표 그리고, 완전히 상관없는 고양이 사진을 가지고 있습니다. 이 모든 목표들을 다루기 위한 하나의 웹사이트를 만드는 것이 합리적입니까? 그것이 필요할까요? 결국에, 많은 기존의 웹 서비스는 새로운 웹사이트를 만들지 않고 당신의 목표를 가져다 줄 지 모릅니다.

애인을 찾는 것은 새로운 웹사이트를 구축하는 것보다 기존의 자원을 사용하는 것이 더 알맞다는 점에서 중요한 케이스입니다. 왜? 왜냐하면 우리가 실제로 애인을 찾는 것보다 웹사이트를 구축하고 유지하는 데 더 많은 시간을 소비하기 때문입니다. 우리의 목표가 가장 중요하기 때문에, 우리는 처음부터 시작하는 것보다는 기존의 툴을 레버리징(leveraging )하는 것에 에너지를 써야합니다. 다시, 사진을 보여주기 위해 이용할 수 있는 이미 너무 많은 웹서비스가 있습니다 그래서 우리의 고양이가 얼마나 귀여운 지에 대한 것을 퍼뜨리기 위해 새로운 사이트를 구축하는 데 노력할 가치가 없습니다.

음악과 연관된 다른 5개의 목표가 있습니다. 물론, 이런 목표들을 다룰 수 있는 많은 웹서비스가 있습니다. 그러나, 우리만을 위한 웹사이트를 구축하는 경우에는 이해가 됩니다. 그런 웹사이트는 하나의 공간에 퍼블리싱하고 싶은 모든 항목을 합치는 것과 (목표 3, 5, 6에 적합) 그리고 우리와 대중 사이에 상호작용을 장려하는 것에 (목표 2, 4) 가장 좋은 방법입니다. 다시 말해서, 이런 목표들이 같은 주제를 중심으로 돌기 때문에, 한 곳에 모든 것을 가지는 것이 우리의 목표를 충족하고, 팔로어들과 연결하는 데 도움이 될 것입니다.

어떻게 웹사이트가 나의 목표를 달성하는 데 도움이 될까요? 그것에 답함으로써, 우리는 우리의 목표를 달성하는 데 가장 좋은 방법을 찾을 것이고, 노력이 낭비되지 않도록 할 것입니다.

### 내 목표를 달성하기 위해, 무엇을, 어떤 순서로 해야할까?

이제 우리가 달성하고 싶은 것을 알고 있으므로, 그 목표들을 실행가능한 단계로 바꿀 시간입니다.

긴 설명을 하기 보다는 이 표로 우리의 예제를 돌아봅시다:

| 목표 | 해야할 것 |
| --- | --- |
| 사람들이 당신의 음악을 듣게 하기 | 1. 음악을 녹음한다.
2. 온라인에서 사용할 수 있는 몇몇의 오디오 파일을 준비힌다. (기존의
 웹서비스로 이것을 할 수 있을까?)
3. 사람들에게 당신의 웹사이트의 일부에서 당신의 음악에 접근하게 한다.
 |
| 음악에 대해 이야기하기 | 1. 토의를 시작하기 위한 몇몇의 글을 쓴다.
2. 어떻게 글이 보여야 하는 지 정해라.
3. 웹사이트에 이 글을 게시해라 (어떻게 이것을 할까?)
 |
| 다른 음악가들 만나기 | 1. 사람들이 너와 연락할 방법을 제공해라.
2. 너의 웹사이트에서 어떻게 사람들이 연락 채널을 찾을 지 정해라.
 |
| goodies 팔기 | 1. goodies 만든다.
2. goodies 저장한다.
3. 쇼핑을 하는 방식 찾는다.
4. 결제 방식 찾는다.
5. 사이트에서 사람들의 주문 메카니즘 만든다.
 |
| 동영상을 통해 음악 가르치기 | 1. 동영상 강의 녹화한다.
2. 온라인에서 볼 수 있는 동영상 파일 준비한다. (다시, 기존의
 웹사이트에서 할 수 있을까?)
3. 웹사이트의 한 부분에서 비디오 접근 가능하게 한다.
 |

공지할 것이 두 개가 있다. 첫째, 이런 아이템 중 몇몇은 웹과 상관이 없다. (예를 들어, 음악 녹음, 글 쓰기) 종종 그런 오프라인 활동이 프로젝트의 웹 부분보다 훨씬 더 중요하다. 예를 들어, 판매의 경우에, 공급, 결제, 배달에 시간을 쓰는 것이 사람들이 주문할 수 있는 웹사이트를 만드는 것보다 훨씬 더 중요하다.

둘째, 실행가능한 단계를 설정하는 것은 우리가 답할 필요가 있는 새로운 질문을 이끌어 낸다. 종종 우리가 본래 생각했던 것보다 더 많은 질문으로 변한다. (예를 들어, 내가 혼자서 어떻게 이것을 배워야할까? 누군가에게 이것을 부탁할까? 서드파티(제 3의) 서비스를 사용해야할까?)

결론
--

당신이 본 것 처럼, "나는 웹사이트를 만들고 싶다" 라는 단순한 생각이 긴 해야할 목록을 만들었다. 그리고 그것은 생각하면 할 수록 더 길어진다. 금방 그것은 압도적으로 보일 것이다. 그러나 겁먹지 마라. 당신은 모든 질문에 대답할 필요는 없다. 그리고 당신은 리스트에 모든 것을 할 필요는 없다. 중요한 것은 원하는 것과 도달하는 법에 대한 비전을 가지고 있어야하는 것이다. 일단 분명한 비전이 있다면, 당신은 해야할 때와 하는 방법을 결정할 필요가 있다. 큰 일을 작은 실행할 수 있는 단계로 부숴라. 그리고 그 작은 단계를 거대한 성과로 합쳐라.

이 글에서, 당신은 웹사이트를 만들기 위한 개략적인 계획을 지금 세울 수 있어야 한다. 다음 단계는 how the Internet works(인터넷이 작동하는 법) 을 읽어야 할 것이다.


What software do I need to build a website? - Web 개발 학습하기

What software do I need to build a website?
===========================================

이 글에서, 우리는 당신이 편집하고, 업로드하고, 웹사이트를 볼 때 어떤 소프트웨어 구성품이 필요한 지 제시한다.

|  |  |
| --- | --- |
| 요구사항: | 웹페이지, 웹사이트, 웹서버, 검색엔진의 차이 (en-US)를 알아야 한다. |
| 목적: |
 만약 당신이 웹사이트를 편집하거나 업로드하거나 볼 때, 필요한 소프트웨어
 구성품이 무엇인지 배웁니다.
  |

요약
--

당신은 웹 개발에 필요한 대부분의 프로그램들을 무료로 다운 받을 수 있습니다. 우리는 이 글에서 몇 개의 링크를 제공할 것입니다. 당신은 1) 웹페이지를 생성하고 편집하기, 2) 웹 서버에 파일을 업로드하기, 3) 웹 페이지 보기 를 위한 툴들이 필요할 것입니다.

거의 모든 운영체제는 기본적으로 텍스트 에디터와 웹 뷰어(브라우저)를 포함하고 있습니다. 그래서 보통 웹 서버로 파일을 전송할 소프트웨어 필요합니다.

Active Learning
---------------

*There is no active learning available yet. Please, consider contributing.*

깊게 들어가기
-------

### 웹 페이지를 생성하고 편집하기

웹사이트를 생성하고 편집하기 위해, 텍스트 에디터가 필요합니다. 텍스트 에디터는 무서식의 텍스트 파일을 생성하고 수정합니다. (**RTF** 같은 다른 형식(format)들은, 볼드체와 밑줄같은 포멧을 추가하게 합니다. 이런 포맷들은 웹 페이지를 쓰는 데 적합하지 않습니다.) 당신은 현명하게 텍스트 에디터를 선택해야 합니다. 왜냐하면, 웹사이트를 구축하는 동안에, 광범위하게 사용해야하기 때문입니다.

모든 데스크탑 운영체제는 기본적인 텍스트 에디터가 딸려 있습니다. 이런 에디터들은 모두 간단하지만, 웹페이지 코딩에 특별한 기능들이 부족합니다. 만약 당신이 더 복잡한 것을 원한다면, 많은 이용가능한 다른(third-party) 툴들이 있습니다. 서드-파티 에디터들은 구문 색표시, 자동완성, 섹션접기, 코드검색을 포함하는 추가 기능이 딸려 있습니다. 에디터들의 간략한 리스트입니다:

| 운영 체제 | 내장 에디터 | Third-party 에디터 |
| --- | --- | --- |
| Windows | Notepad | Notepad++Visual Studio CodeWeb StormBracketsShiftEdit |
| Mac OS | TextEdit | TextWranglerVisual Studio CodeBracketsShiftEdit |
| Linux | Vi (All UNIX) GEdit (Gnome) Kate (KDE) LeafPad (Xfce) | Emacs VimVisual Studio CodeBracketsShiftEdit |
| ChromeOS |  | ShiftEdit |

이것은 하나의 고급 텍스트 에디터의 스크린샷입니다:

![Screenshot of Notepad++.](/ko/docs/Learn/Common_questions/Tools_and_setup/What_software_do_I_need/notepadplusplus.png)

이것은 온라인 텍스트 에디터의 스크린샷입니다:

![Screenshot of ShiftEdit](/ko/docs/Learn/Common_questions/Tools_and_setup/What_software_do_I_need/shiftedit.png)

### 웹에 파일 업로드하기

당신의 웹사이트가 대중들에게 보여지기 전에, 웹 서버에 웹페이지를 업로드 해야할 것입니다. 당신은 다양한 제공자로부터 서버의 공간을 살 수 있습니다. (How much does it cost to do something on the web? (en-US)를 보십시오). 일단, 당신이 어떤 제공자를 사용할 지 정했다면, 제공자는 당신에게 FTP(파일 전송 프로토콜) 접근 정보를 이메일로 보낼 것입니다.웹 사이트를 만들 때, 웹 서버에 파일을 업로드 하는 것은 매우 중요한 단계입니다, 그래서 우리는 상세한 부분은 a separate article(따로 분리한 글) (en-US)에서 다루겠습니다. 아래는 무료 기본 FTP 클라이언트의 목록입니다:

| 운영체제 | FTP 소프트웨어 |
| --- | --- |
| Windows | WinSCP
Moba Xterm | FileZilla (All OS)
 |
| Linux | Nautilus
 (Gnome)Dolphin
 (KDE)
  |
| Mac OS | Cyberduck |
| ChromeOS | ShiftEdit (All OS) |  |

### 웹사이트 보기

알다시피, 웹사이트를 보기 위해 웹 브라우저가 필요합니다. 개인적인 사용을 위한 수 십개의 브라우저 선택권이 있습니다. 그러나, 웹 사이트를 개발할 때, 대부분의 사람들이 당신의 사이트를 잘 이용하기 위해서는 다음의 주요 브라우저에서 테스트해야합니다.

* Mozilla Firefox(Firefox)
* Google Chrome(크롬)
* Microsoft Internet Explorer(인터넷 익스플로러)
* Apple Safari(사파리)

만약 당신이 기술적인 플랫폼이나 국가 등 특정한 그룹을 목적으로 한다면, Opera, Konqueror, UC Browser 같은 추가적인 브라우저도 테스트해야할 지도 모릅니다.

그러나 몇몇의 브라우저는 특정한 운영체제에서만 동작하기 때문에 테스트하는 것이 복잡합니다. 애플의 Safari는 iOS와 Max OS 에서만 동작하는 반면에, 인터넷 익스플로러는 윈도우에서만 동작합니다. Browsershots나 Browserstack 같은 서비스를 이용하는 것이 좋습니다. Browsershots은 다양한 브라우저에서 볼 때, 웹사이트의 스크린샷을 제공합니다. Browserstack은 사실 당신에게 가상머신에서 완전한 원거리 접근을 가능하게 해줍니다. 그래서 당신은 대부분의 공통 환경에서 사이트를 테스트할 수 있습니다. 그렇지 않으면, 당신 자신의 가상 머신을 설치하면 됩니다. 하지만 이것은 약간의 전문지식이 필요한 작업입니다. (만약 당신이 이런 길을 가고자 한다면, 마이크로소프트에서는 modern.ie.에서 사용 준비가 완료된 가상 머신이 포함된 개발자를 위한 툴들을 가지고 있습니다.)

물론, 실제 장치에서 몇 번의 테스트를 해봐야한다. 특히, 실제 모바일 장치에서는. 모바일 장치 시뮬레이션은 새롭고, 진화하고 있는 기술이고 데스트탑 시뮬레이션보다 신뢰가 떨어진다. 물론, 모바일 장치는 돈이 든다. 그래서 우리는Open Device Lab initiative에서 보는 것을 제안한다. 당신이 너무 많은 소비없이 많은 플랫폼을 테스트하고 싶다면, 장치를 공유할 수 있다.

다음 단계
-----

* 몇몇의 소프트웨어는 무료이나, 모두 무료는 아니다. 웹에서 무언가를 하기 위해 얼마나 비용이 드는 지 알아보기 (en-US). (en-US)
* 당신이 더 많은 텍스트 에디터에 대해 배우고 싶다면, 텍스트 에디터를 선택하고 설치하는 법 (en-US)에 대한 글을 읽으세요.
* 당신이 웹에서 웹사이트를 퍼블리싱하는 법에 대해 궁금하다면, "웹 서버에 파일을 업로드하는 법" (en-US)을 보십시오.


로컬 테스트 서버 설치하기 - Web 개발 학습하기

로컬 테스트 서버 설치하기
==============

이 글에서는 간단한 로컬 테스트 서버를 여러분의 장비에 설치하는 법과 기본적인 사용법을 설명합니다.

|  |  |
| --- | --- |
| 사전 준비: | 인터넷의 작동 방법 (en-US)과 웹서버 (en-US)에 대해
 알고 있어야 합니다.
  |
| 목표: | 로컬 테스트 서버를 설치하는 법을 배울 것입니다. |

로컬 파일과 원격 파일
------------

대부분의 학습 분야에 걸쳐서 여러분은 그냥 웹브라우저로 예제들을 직접 열어보기만 하면 됩니다. — 브라우저를 통해 예제들을 직접 열어보는 것은 HTML 파일을 더블 클릭하거나 브라우저 창으로 예제들을 드래그 앤 드롭하거나 또는 *File* > *Open...* 메뉴에서 해당하는 HTML 파일을 선택하면 됩니다. 이를 수행하는 방법은 많습니다.

웹 주소 경로가 `file://`로 시작하고 뒤에 오는 경로가 여러분의 로컬 하드 드라이브에 있는 파일의 경로인 경우, 로컬 파일이 사용되는 것입니다. 이와는 달리, GitHub (또는 다른 원격 서버에 있는) 예제를 보는 경우에는 웹 주소가 `http://`나 `https://`로 시작하며, 이는 그 파일이 HTTP를 통해 수신된 파일이라는 것을 나타냅니다.

로컬 파일로 테스트할 때의 문제점
------------------

일부 예제는 로컬 파일과 같은 방식으로 열면 동작하지 않습니다. 여기에는 여러 가지 원인이 있을 수 있으며, 대부분은 다음과 같습니다:

* **비동기 요청인 경우**. 일부 브라우저(크롬을 포함하는)에서는 로컬 파일의 예제를 실행할 경우에 비동기 요청(서버로부터 데이터 가져오기 - Fetching data from the server (en-US)를 참고)이 작동하지 않을 것입니다. 이는 보안 제한(웹 보안과 관련된 자세한 내용은 웹사이트 보안- Website security (en-US)을 참고하세요) 때문입니다.
* **서버측 언어인 경우**. 서버측 언어(PHP나 Python과 같은)는 코드를 해석하고 결과를 내보낼 수 있는 특별한 서버가 필요합니다.
간단한 로컬 HTTP 서버 실행하기
-------------------

비동기 요청 문제를 해결하려면 로컬 웹 서버에서 예제를 실행하여 테스트해야 합니다. 이를 위한 가장 쉬운 방법은 파이썬(Python)의 `SimpleHTTPServer` 모듈을 사용하는 것입니다. (설치된 파이썬 버전에 따라 `http.server` 모듈을 사용해야 할 수도 있습니다.)

이를 위해:

1. 파이썬을 설치합니다. 리눅스나 맥OS 사용자라면 이미 시스템에 설치되어 있을 것입니다. 윈도우 사용자일 경우, 다음과 같이 파이썬 홈페이지로부터 설치 프로그램을 다운 받고 설치합니다:
    * 파이썬 홈페이지(python.org)로 이동합니다.
    * 다운로드(download) 영역에서 Python "3.xxx" 링크를 클릭합니다.
    * 페이지의 아래쪽에 있는 *Windows x86 executable installer*를 선택하고 다운로드 받습니다.
    * 다운로드가 완료되면 실행합니다.
    * 설치 프로그램의 첫 번째 페이지에서 "Add Python 3.xxx to PATH" 체크박스를 체크해야 합니다.
    * *Install*을 클릭하고 설치가 완료되면 *Close*를 클릭합니다.
2. 명령 실행창(윈도우의 경우는 command prompt, OS/X나 리눅스인 경우에는 터미널창)을 엽니다. 파이썬이 설치되었는지 확인하기 위해 다음 명령을 입력합니다.:

```bash
python -V
```

3. 이 명령은 버전 번호를 반환합니다. 정상적으로 작동하면, `cd` 명령을 이용해 여러분의 예제가 존재하는 디렉토리로 이동합니다.

```bash
# 들어가고자 하는 디렉토리 명을 입력합니다. 예를 들어,
cd Desktop
# 한 단계 상위 디렉토리로 이동하려면 점 두 개를 사용합니다.
cd ..
```

4. 그 경로에 있는 서버를 구동하기 위한 명령을 입력합니다:

```bash
# 위에서 반환된 파이썬 버전이 3.X인 경우
python -m http.server
# 위에서 반환된 파이썬 버전이 2.X인 경우
python -m SimpleHTTPServer
```

5. 이 명령은 기본적으로 로컬 웹 서버의 8000번 포트를 이용해 해당 경로의 컨텐츠를 실행시킵니다. 웹 브라우저에서 주소줄에 `localhost:8000`를 입력하면 이 서버로 이동할 수 있습니다. 그러면 그 디렉토리의 컨텐츠 목록을 볼 수 있는데 실행하고자 하는 HTML 파일을 클릭합니다.

**참고:** 8000번 포트에 이미 실행 중인 무언가가 있다면 서버 실행 명령에 다음과 같이 대체 포트 번호를 명시함으로써 다른 포트로 서버를 구동할 수 있습니다.

예: `python -m http.server 7800` (Python 3.x일 경우) 또는 `python -m SimpleHTTPServer 7800` (Python 2.x일 경우). 이 경우, `localhost:7800`를 통해 서버로 이동할 수 있습니다.

서버측 언어를 로컬에서 실행하기
-----------------

파이썬의 `SimpleHTTPServer (python 2.0) http.server (python 3.0)` 모듈은 유용하기는 하나 파이썬이나 PHP 또는 JavaScript와 같은 언어로 작성된 코드를 실행하지 못합니다. 이런 코드를 처리하기 위해서는 뭔가가 더 필요합니다 — 정확하게 무엇이 필요한지는 실행하고자 하는 서버측 언어가 무엇인지에 따라 다릅니다. 다음에 몇 가지 사례를 소개합니다:

* 파이썬으로된 서버측 코드를 실행하기 위해서는 파이썬 웹 프레임워크(Python web framework)를 사용할 필요가 있습니다. Django Web Framework (Python)를 읽어보면 Django framework를 이용하는 법을 알 수 있습니다. Flask는 Djang를 대신할 좋은(조금 더 가벼운) 대안이될 수 있습니다. Flask를 실행하기 위해서는 Python/PIP(install Python/PIP)를 설치하고, `pip3 install flask` 명령으로 Flask를 설치해야 합니다. 이 때부터 파이썬 Flask 예제를 실행할 수 있는데, 예를 들어, `python3 python-example.py`명령을 실행하고 브라우저에서 `localhost:5000`으로 이동하면 됩니다.
* Node.js (JavaScript)라는 서버측 코드를 실행하기 위해서는 기본 node(raw node)나 그 위에 설치되는 프레임워크를 이용해야 합니다. Express가 좋은 선택이될 수 있습니다 — Express Web Framework (Node.js/JavaScript)를 살펴보시기 바랍니다.
* PHP로된 서버측 코드를 실행하려면 PHP에 내장된 개발서버(PHP's built-in development server)를 실행시킵니다:

```bash
cd path/to/your/php/code
php -S localhost:8000
```