원문 : https://morioh.com/p/6d422fc49bd2

웹 언어인 HTML은 가장 잘 알려진 웹 기술 중 하나입니다. HTML은 도입된 이후로 인터넷을 구축하기 위해 지속적으로 사용되고 있습니다.

많은 새로운 기술들이 웹사이트 생성 프로세스를 보다 간단하고 효율적으로 만들었지만, HTML은 그 중에 항상 핵심이었습니다.

HTML5는 2014년에 나왔습니다. 하이퍼텍스트 마크업 언어의 표준화를 향한 또 다른 단계였습니다. 2014년 10월에 개정된 HTML 사양은 합리적이었습니다.

사람들은 이제 또 다른 업그레이드를 기다리고 있는데, 무엇일까요? 바로 HTML6가 오고 있습니다.

WHATWG - HTML 사양을 규제하는 기관은 HTML 사양을 한 번에 광범위하게 변경하지 않고, 천천히 시간이 지남에 따라 지속적으로 변경하고 있습니다. (출처에서 알 수 있듯이)

이 아티클에서는 HTML6의 새로운 점과 가장 많이 바뀔 사항들을 살펴보겠습니다.

 

목차

  • 익스프레스 태그 (Express Tags)

  • 기본 모달 지원 (Native Modals Support)

  • 자유로운 이미지 크기 조정 (Freedom to Resize Image)

  • HTML6 전용 라이브러리 (HTML6 Dedicated Libraries)

  • 이미지 및 비디오에 대한 주석 (Annotations for Images and Videos)

  • 인증 향상 (Authentication Enhancement)

  • HTML6의 사용자 메뉴 (Customized Menus in HTML6)

  • HTML6 통합 카메라 (HTML6 Integrated Camera)

  • 유용한 마이크로포맷 (Good Microformats)

  • 자바스크립트 없는 단일 페이지 애플리케이션 (Single-Page Apps without JavaScript)

  • 결론

익스프레스 태그 (Express Tags)

이름에서 유추할 수 있듯이, 이 태그는 표현식으로 쓰입니다. 웹 페이지의 로고와 같은 태그를 사용할 수 있습니다.

또한 , , 와 같은 태그를 사용할 수 있습니다.

기본 모달 지원 (Native Modals Support)

dialog 요소는 HTML6에서 사용합니다. 이 요소는 자바스크립트 기반의 모달 창과 동등한 것으로 간주됩니다.

dialog 요소는 이미 표준화 되었지만, 크롬과 삼성 인터넷 브라우저와 같은 일부 브라우저에서만 완벽히 지원합니다. 그렇더라도 곧 모든 브라우저에서 작동할 것입니다.

기본 포맷으로 된 해당 요소는 배치된 위치 위로 띄어서 노출될 것입니다.

보다 일반적인 모달과 같은 인터페이스를 사용하려면, 자바스크립트를 통해 모달 메서드를 열 수 있습니다.

<dialog>
  <form method="dialog">
    <input type="submit" value="Ok" />
    <input type="submit" value="Cancel" />
  </form>
</dialog>

기본 양식에서 요소는 비대화형인 컨텐츠가 포함된 회색 배경을 만듭니다.

dialog 요소 내의 양식에서 메소드 속성을 사용할 수 있습니다. 이것은 값을 제출하고 값을 다시 대화 상자 객체로 전달합니다.

전반적으로, 이 dialog 요소는 사용자와의 상호작용 및 UI 향상에 유리합니다.

표준 HTML 형식으로 open 속성을 토글시켜 dialog 요소를 열고 닫을 수 있습니다.

<dialog open>
  <p>Dialog Box Built with HTML 6</p>
</dialog>

자유로운 이미지 크기 조정 (Freedom to Resize Image)

전문가들은 브라우저가 최상의 뷰 환경을 위해 이미지 크기를 조정할 수 있는 업데이트가 진행되고 있다고 생각합니다.

브라우저는 장치 및 윈도우 창 크기에 따른 최상의 이미지 크기를 표시하기가 어렵습니다.

src 및 img 태그는 이 문제를 처리하는데 그다지 효율적이지 않습니다. 새로운 태그 <srcset>를 사용하면 가능할 것입니다.

이 태그를 사용하면 브라우저에서 최상의 뷰를 보여주기 위해 둘 이상의 이미지 중에서 하나를 선택할 수 있습니다.

HTML6 전용 라이브러리 (HTML6 Dedicated Libraries)

HTML6에 캐시 가능한 라이브러리를 도입하는 것은 웹 디자이너와 사용자의 생산성을 향상시키는 단계가 될 것입니다.

이미지 및 비디오에 대한 주석 (Annotations for Images and Videos)

HTML로 이미지와 비디오에 주석을 달 수 있다면 좋을 것입니다. HTML5는 이미지, 비디오가 아닌 단어, 문장 및 단락을 해석 할 수있는 기능을 제공합니다.

이 분야의 많은 조직들이 솔루션을 제공했으며 WHATWG가 적어도 일부를 고려한 것처럼 보입니다.

곧 HTML에서 이미지와 동영상에 주석을 달 수 있을것입니다.

인증 향상 (Authentication Enhancement)

HTML5는 보안 측면에서 나쁘지 않지만, 브라우저와 웹 기술도 합리적인 보호 기능을 제공합니다. 의심 할 여지 없이 인증 및 보안 영역에서 더 많은 작업을 수행할 수 있습니다.

키는 오프라인 사이트에 저장할 수 있습니다. 이것은 권한이 없는 사람들의 접근을 막고 인증을 강화합니다. 쿠키 대신 내장되어 있는 키 사용, 디지털 서명 개선 등등

사람들과 싱크 탱크는 WHATWG가 수락하거나 거부 할 수있는 많은 솔루션을 제공합니다.

HTML6의 사용자 메뉴 (Customized Menus in HTML6)

The UL and OL tags are beneficial but do not fit well in every need. A tag or menu tag that could handle interactive elements better is the need of the hour.

<ul><ol> 태그는 유용하지만 모든 상황에 적합하지는 않습니다. 대화형 요소를 보다 잘 처리할 수있는 태그 혹은 <menu> 태그는 시간이 좀 더 필요합니다.

<menu> 요소는 메뉴 내부의 버튼으로 트리거 된 목록 요소를 처리 할 수 있습니다.

<menu type="toolbar">
  <li><button>Cut</button></li>
  <li><button>Copy</button></li>
  <li><button>Paste</button></li>
</menu>

이 메뉴는 HTML에서 목록의 기능을 향상시킬 수 있으며 일반적인 목록과 마찬가지로 잘 작동 할 수 있습니다.

HTML6 통합 카메라 (HTML6 Integrated Camera)

HTML6을 사용하면 사용자 기기에서 카메라와 미디어를 최대한 활용할 수 있습니다. 카메라 및 카메라의 효과, 모드, 파노라마 이미지, HDR 등을 제어할 수 있습니다.

모든 미디어를 사용하고 용도를 변경할 수 있습니다. 카메라와 HTML6으로 더 나아질 수있는 것들이 많이 있습니다.

유용한 마이크로포맷 (Good Microformats)

인터넷에서 일반적인 정보를 정의해야하는 경우가 많습니다. 일반정보는 전화번호, 이름, 주소 등과 같은 공개정보일 수 있습니다. 마이크로포맷은 일반 데이터를 정의할 수 있는 표준입니다.

마이크로포맷은 디자이너의 능력을 향상시키고 공개 정보를 추론하는데 필요한 검색 엔진의 노력을 줄일 수 있습니다.

자바스크립트 없는 단일 페이지 애플리케이션 (Single-Page Apps without JavaScript)

FutureClaw 잡지의 편집장인 Bobby Mozumder 는 다음과 같이 제안합니다.

앵커 요소를 JSON / XML, API 엔드 포인트에 연결하여 브라우저가 내부적으로 데이터를 새로운 데이터 구조로 로드하면,
브라우저는 DOM 요소를 필요에 따라 로드된 데이터로 바꿉니다. 
초기 데이터(및 표준 오류 응답)는 헤더 픽스처에 있을 수 있으며 원하는 경우 나중에 교체 할 수 있습니다.

그에 따르면, 이것은 자바스크립트를 로드 할 필요가 없기 때문에 응답성과 로딩 시간을 향상시키는 단일 페이지 앱 웹 디자인 패턴입니다.

결론

HTML도 완벽하지는 않습니다. 그러므로 HTML 사양을 개선 할 수 있는 사항들은 많이 있습니다.

HTML의 힘을 향상시키기 위해 몇 가지 유용한 규범들을 표준화해야 합니다. 작은 변화들은 이미 실행되기 시작했습니다.

기술 전문가들이 말하는 것을 고려하고 또한 일반 대중들의 의견을 듣는 것이 하나의 아이디어를 제공할 수 있습니다.

블루투스 지원 강화, p2p 파일 전송, 멀웨어 방지, 클라우드 스토리지 통합 등은 HTML의 다음 버전에서 고려해야 할 사항들입니다.

이것은 미래를 위한 것입니다. 그러나 이미 소개된 업데이트도 있고, 조만간 발표될 가능성이 가장 높은 반면, 단순한 예측에 불과한 업데이트도 있습니다.

이 기사가 당신이 HTML6에 대한 통찰력을 얻는데 도움이 되기를 바랍니다.

for과 for-in 패턴.md

이 글은 "JavaScript Patterns" 책을 공부하며 요약해 쓴 글입니다.


for

for 루프는 배열, arguments, HTMLCollection 등 배열과 비슷한 객체를 순회한다.

 

*HTMLCollection: HTML 요소들의 리스트로 유사배열객체이다.

 

 

일반적인 for 문

 

이 패턴은 루프 순회시마다 arr의 length에 접근한다.

 

만약 arr이 배열이 아닌 HTMLCollection이라면 코드가 느려질 수 있다.

  • 실제 DOM의 접근 비용은 일반적으로 크다.
  • HTMLCollection 객체의 length 속성 접근은 실제 DOM에 질의를 요청하는 것과 같다.
  • 실제 DOM 질의는 실시간으로 처리된다. 브라우저는 DOM 조작이 일어나면 다시 브라우저에 렌더링하는데에 수 많은 처리 과정을 거치는데, 이는 많은 비용이 요구된다. (reflow를 참고)

arr.length의 값이 10000이라면 브라우저를 10000번 렌더링하는 것과 같다.

 

여러 최적화 방법들

 

1. 배열(또는 콜렉션)의 length를 캐시
 

HTMLCollection 객체의 length 값을 초기화 변수에 저장하여 한 번의 DOM 접근만이 이루어진다.

 

2. 변수 갯수 줄이기, 배열을 거꾸로 순회
 

length 변수를 없애고, 배열의 카운트를 감소시켜 0으로 내려간다. (미세 최적화)

  • 0과 비교하는 것이 배열의 length 또는 0이 아닌 값과 비교하는 것보다 대게 더 빠르다.
  • 성능이 결정적인 요소가 되는 작업에서 사용하는 것을 권장

for-in

for-in 루프는 배열이 아닌 객체를 순회할 때 사용해야 한다.

  • 자바스크립트의 배열은 객체이기 때문에 for-in 루프를 통해 순회할 수 있지만, 권장사항이 아니다.
  • 배열 객체에 사용자가 정의한 기능이 추가되면 논리적인 오류가 발생할 수 있다.
  • 열거 순서가 정해져있지 않다. 실제로 배열은 for-in이 아닌 for 루프로 순회하는 것이 좀 더 빠르다.
 

 

일어날 수 있는 오류 피하기

코드 내에 'Object.prototype.메서드명'이라는 사용자가 지정한 메서드가 모든 객체에 추가되었다고 가정하자.

이 메서드 프로퍼티는 프로토타입 체인을 따라 상속되어 모든 객체의 프로퍼티로 사용할 수 있게 된다.

이 문제로 인해 어떤 객체가 for-in 루프로 순회하는 과정에서 의도치 않게 메서드가 사용될 수 있다.

ex)

 

 

1. hasOwnProperty() 사용

Object의 hasOwnProperty 메서드를 사용하여 객체 변수의 고유 프로퍼티만을 사용할 수 있다.

 

 

2. Object.prototype.hasOwnProperty.call() 사용

이 패턴은 만약 fruits 객체의 hasOwnProperty 메서드를 오버라이딩 했을 경우에도, 온전한 hasOwnProperty 메서드를 사용할 수 있게 해준다.

 

 

3. Object.prototype.hasOwnProperty 캐시

프로퍼티 탐색이 체인을 따라 Object까지 거슬러 올라가지 않게 하기 위해, 지역 변수를 사용하여 메서드를 캐시한다.

 

 

hasOwnProperty()를 사용하지 않았다고 해서 오류가 발생하지는 않으며, 루프 속도가 약간 감소될 수 있지만, 객체와 객체 프로토타입 체인의 내용을 보장할 수 없다면 hasOwnProperty()로 확인하는 것이 좀 더 안전한 방법이다.

about-objects.md

Ruby koans의 about_objects.rb를 정리한 내용


is_a

 

인수의 클래스가 오브젝트의 클래스이거나 부모 클래스의 오브젝트 중 하나 혹은 모듈이 오브젝트에 속해 있으면 true를 반환한다.

=> 위의 예제는 Integer, Float, String, nil, Object 모두 Object 클래스를 부모 클래스로 가지고 있으므로 true를 반환한다.

 

to_s

 

to_s는 어떤 오브젝트든 문자열로 표현할 수 있는 메서드이다.

=> 위의 예제는 숫자 123(Integer)을 문자열 "123"로, nil("아무것도 없음"을 의미, nothing)을 문자열 ""로 변환한다.

 

inspect

 

inspect는 to_s처럼 오브젝트를 문자열로 변환한다. 하지만 차이점이 있다.

to_s는 오브젝트의 내용 자체를 문자열 변환하며, 객체 클래스의 경우 obejct_id를 문자열로 변환한다.

반면, inspect는 객체에 기록된 내용을 지정된 형식의 문자열 형태로 변환한다. 즉, 개발자가 디버깅하는데에 좀 더 친숙한 문자열 형태로 반환해준다.

ex) inspect user obj

 

=> 위의 예제에서 nil.inspect의 경우는 개발자가 읽기 쉬운 형태로 값을 변환해주기 때문에 nil을 문자열 형태로 변환하여 표현한다.

 

obj.object_id.class ==? Fixnum

 

Ruby의 Fixnum은 'Lisp'에서 온 것으로 32bit(in VM)의 고정된 정수 값을 나타낸다. 정수 값의 범위는 -((2^30)-1)에서 (2^30)-1로 -1073741824에서 1073741824의 정수를 표현한다. (그 외의 작고 큰 정수 값은 Bignum으로 표현한다.)

ex)

 

=> 위의 예제에서 object_id는 일반적으로 Fixnum이 표현할 수 있는 범위 내의 정수 값을 할당받게 되므로 object_id의 클래스명은 Fixnum이다.

 

object has different id

 

모든 객체 인스턴스는 자신을 유일하게 식별할 수 있는 고유한 object_id를 갖는다. 여기서 object_id는 정수(Interger) 값으로 표현한다. 고유한 정수 값이기 때문에 메모리 주소 값을 할당 받는다고 생각할 수 있다.

=> 위의 예제에서 obj와 another_obj 객체 인스턴스는 생성될 때 서로 다른 object_id를 갖기 때문에 not 비교문에서 true를 반환한다.

 

object_id pattern for small integers

 

위의 몇 가지 예제를 통해 객체 인스턴스는 고유한 obejct_id를 갖고 Fixnum을 통한 정수 값을 할당받는다고 설명했다. 그렇다면 true, false, nil과 같이 항상 같은 값을 갖는 오브젝트들은 어떻게 object_id 값을 설정할까? 또한 Fixnum 범위 내에서 정수(Integer)의 object_id 값은 어떻게 설정할까?

이렇게 객체 인스턴스뿐만 아니라 고정 오브젝트 타입의 obejct_id 값들을 설정하기 위해 bit pattern을 사용했다. (여러 참고 문서를 통한 추측일뿐 확실한 정보는 아님)

object_id는 "(Fixnum * 2) + 1"의 연산 결과값이 할당된다.

아래의 예제를 보면, Ruby에서 false는 값을 0으로 하드코딩한 것이 아니라 상단의 비트패턴 연산을 사용하여 값을 구한 것을 알 수 있다.

ex)

 

그러면 (Fixnum * 2) + 1의 비트 연산 과정을 자세히 살펴보자.

먼저 Fixnum은 32bit를 사용한다고 했다. 여기서 흥미로운 점은 만약 Fixnum의 마지막 비트가 0인 경우에는 31bit만을 사용하고, Fixnum의 마지막 비트가 1인 경우 32bit 모두를 사용한다.

아래는 정수 4와 5의 비트연산 예제이다.

ex) object_id of 4

 

ex) object_id of 5

 

이러한 계산 방식에는 2 가지의 부작용이 있다.

첫 번째로 위의 Fixnum 연산은 마지막에 1을 추가하므로 모든 Fixnum object_id는 홀수이다. 이를 통해 시스템에 다른 모든 객체의 object_id는 짝수라는 것을 알 수 있다.

두 번째로 홀수 Fixnum만이 Fixnum object_id로 사용된다. Fixnum 절반이 Fixnum object_id로 채워져 있고 나머지 절반에 다른 object_id를 채워넣어야 하는데, 다른 모든 obejct_id가 너무 커서 31비트에 들어가지 않는다는 것이다. 만약 시스템이 짝수 Fixnum 공간에 충분한 객체들을 인스턴스화 하는데에 써버린다면, 일반 객체의 object_id는 Bignum을 얻게 된다.

 

clone object

 

obj.clone을 사용하면 인스턴스 객체의 복사본을 생성할 수 있다.

일반적으로 객체는 주소값을 참조하기 때문에 코드 범위내에서 값을 공유한다. 객체의 값을 수정하면 같은 변수명을 가진 객체의 값 또한 변경된다.

하지만 객체의 복사본을 생성하면 서로 다른 주소값(object_id)을 할당 받기 때문에 값이 공유될 수 없으며 서로 다른 객체로 인식한다.

=> 그러므로 위의 예제의 비교문들은 true를 반환한다.


참고 자료

MVVM (Model-view-viewmodel).md
 

 

MVVM (Model-view-viewmodel) pattern

MVVM pattern은 Model-View-ViewModel의 약자로 소프트웨어 아키텍쳐 패턴이다. 초기 UI 개발자들은 모든 코드 로직(이벤트 핸들링, 초기화, 데이터 모델)을 뷰에 작성했다. 모든 코드들을 뷰에 작성하다보니 뷰의 크기가 커지고, UI와 데이터 바인딩간의 의존성 문제가 일어나다보니 개발자들의 협업 개발에서 많은 이슈가 일어나고 유지보수, 확장이 어려워졌다. 이를 해결하기 위해 사용자 인터페이스에 해당하는 뷰(View)와 뷰에 표시되는 데이터(Model) 그리고 뷰(View)와 모델(Model) 사이에서 여러 비즈니스 로직을 처리하는 뷰-모델(View-Model)로 분리하여, 유지보수를 쉽게하고 뷰(View) 처리에 다양한 기능을 사용할 수 있게 되었다.

Three key parts in the MVVM pattern

  1. Model (비즈니스 규칙, 데이터 접근, 모델 클래스)
  2. View (사용자 인터페이스)
  3. ViewModel (모델과 뷰 사이의 인터페이스)

뷰모델(ViewModel)은 모델(Model)과 뷰(View)사이에 인터페이스 역할을 한다. 뷰모델은 모델의 데이터를 뷰에 바인딩하고, 명령어를 사용하여 모든 UI의 동작들을 다룬다. 뷰는 뷰모델의 프로퍼티에 제어값을 바인딩하며 차례대로 모델 객체에 있는 데이터를 노출시킨다.

예를 들어 사용자가 뷰에 있는 계산기 프로그램을 사용하여 결과값을 요청하는 버튼을 클릭했을 때, 뷰모델이 요청받은 동작을 수행한다. 뷰모델의 연산 기능을 담당하는 명령어는 연산 후 모델의 데이터 값을 변경시킨다. 만약 뷰모델의 속성값이 변경되면(모델의 데이터 값이 변경되면) 새로운 속성 값들은 데이터 바인딩(data binding)과 알림(notification)을 통해 자동적으로 뷰에 적용된다.

 

MVVM in Vue.js

Vue.js는 위의 설명된 MVVM 패턴에서 ViewModel 계층에 초점을 둔 프레임워크이다. 뷰모델을 통해서 양방향 데이터 바인딩이 가능하게 해주며, 뷰 계층을 좀 더 간단하고 유연하게 디자인하게 해준다.

아래 그림은 Vue.js에서 MVVM을 나타낸 그림이다. (출처 : https://012.vuejs.org/images/mvvm.png)

MVVM Concepts

ViewModel in Vue.js

모델과 뷰의 동기화 역할을 하는 객체이다. Vue.js에서 모든 뷰 인스턴스(View instance)는 뷰모델(ViewModel)이다. 이들은 Vue 생성자 혹은 하위 클래스들에 의해 인스턴스화된다.

 

이렇게 초기 객체를 선언해줌으로써 뷰와 모델 사이에서 양방향 데이터 바인딩이 가능하게 해준다. 더 자세한 정보는 The Vue Constructor를 확인하자.

 

View in Vue.js

뷰의 실제 돔(DOM)은 Vue instances에 의해 관리된다.

 

Vue.js는 DOM 기반의 템플릿을 사용한다. 각 뷰 인스턴스는 해당 DOM 요소에 연관된다. 뷰 인스턴스가 생성되면 필요한 데이터 바인딩을 설정하는 동안 루트 요소의 모든 자식 노드를 반복적으로 탐색한다. 뷰가 컴파일이 되면 데이터 변경에 반응할 수 있게 된다.

즉, 해당 HTML 컴포넌트 범위(해당 DOM 요소가 담긴 템플릿)를 Vue instace의 vm.$el에 설정한다. 뷰는 Vue instance가 생성 될 때 컴파일 되며 뷰모델의 다양한 동작 기능들이 바인딩 된다. 그렇게 됨으로써 뷰의 변경이 감지되면 뷰모델이 이를 감지하여 반응할 수 있게된다. 추가적으로 뷰의 변경은 집단적으로, 비동기로 실행되기 때문에 높은 성능을 발휘한다.

 

Model in Vue.js

 

Vue.js에서 모델은 단순히 자바스크립트 객체 혹은 데이터 객체로 표현할 수 있다. 데이터 객체의 프로퍼티를 조작하면 이를 관찰하는 뷰 인스턴스가 변경을 알린다. Vue.js는 ES5 getter/setters로 데이터 객체의 프로퍼티를 변환한다. 그렇기에 뷰를 변경하기 위해 Vue에 명시적으로 신호를 보낼 필요가 없다. 또한 각 뷰 인스턴스는 데이터 객체에 있는 모든 프로퍼티들을 프록시한다.

아래 그림은 Vue.js에서 반응형 업데이트가 구현되는 방식을 보여준다. (출처 : https://012.vuejs.org/images/data.png)

high-level overview of how reactive updates

 

참고 자료

'Vue.js' 카테고리의 다른 글

Vue.js : 새롭게 추가된 Virtual DOM  (4) 2017.12.26
Webpack-dev-server를 사용한 웹팩 빌드 오류.md

Webpack-dev-server를 사용한 웹팩 빌드 오류

Bulid succeeding with webpack fails with webpack-dev-server (Unexpected token)

 

webpack/webpack-dev-server GIT 페이지의 issues를 참고했습니다.

링크 - https://github.com/webpack/webpack-dev-server/issues/1101

실행 환경 - 오류가 발생한

  • OS : Ubuntu 16.04 LTS

  • Node version : 8.2.1

  • NPM version : 5.6.0

  • webpack version : 3.10.0

  • webpack-dev-version : 2.10.0

에러 메세지

 

webpack을 이용한 빌드는 성공적으로 이루어졌음에도 불구하고 동일한 환경에서 webpack-dev-server를 사용하여 시작했을 때, 위와 같은 에러 메세지를 볼 수 있습니다.

 

에러 추적

  • npm install [dependencies] (의존성 설치)

  • npm list webpack

  • npm list webpack-dev-server (2.10.0이 최신 버전이지만 2.8.0 or 2.8.1 부터 위와 같은 오류 발생)

  • package.json에서 일반적으로 두 가지의 script를 작성합니다.

    • npm run build : 웹팩을 사용한 번들링의 경우 성공적으로 빌드됩니다.
    • npm start : 동일한 환경으로 webpack-dev-server를 사용하여 빌드했을 경우 예외적으로 오류가 발생합니다.

에러 원인

확실하게 원인에 대해 알지 못 하지만 webpack-dev-server의 최신 버전의 경우 ES6(es2015)를 지원하는 반면에 UglifyJS-Plugin은 ES6를 지원하지 않기 때문에 발생하는 오류로 예상하고 있습니다.

현재 uglifyjs-webpack-plugin의 경우 ES6을 지원한다고 합니다. 다만 uglifyjs의 추가 설치 단계가 필요합니다.

 

해결 방법

이러한 문제는 webpack-dev-server 2.8.0에서 나타나는 오류라고 합니다. 검증을 위해

  • npm install webpack-dev-server@~2.7.0
  • npm start

webpack-dev-server version을 2.7.1로 다운그레이드 시킴으로써 간단히 해결할 수 있습니다.

 

그 외 해결 방법들

  • install UglifyJS-Plugin separately

  • temporarily remove UglifyJS-plugin until webpack includes an es6-capable version

  • transpile webpack-dev-server

    •  

 

전역 변수 맛보기.md

이 글은 "JavaScript Patterns" 책을 공부하며 요약해 쓴 글입니다.


전역 변수의 최소화는 좋은 코드 작성과 유지보수를 함에 있어 큰 역할을 한다!!

그렇기에 전역 변수를 사용함에 있어, 안티 패턴을 최대한 피하며 개발을 하는 것이 좋다.

 

전역 변수 맛보기

자바스크립트는 함수를 사용하여 유효 범위를 관리한다. 아래는 지역 변수를 나타낸다.

 

ex) 지역변수 사용 예

 

 

반대로 전역 변수는 어떤 함수에도 속하지 않은 상태에서 선언되거나, 함수에 속하더라도 var를 통해 선언되지 않은 채로 사용되는 변수를 가리킨다.

 

ex) 전역 변수 사용 예

 

 

모든 자바스크립트 실행 환경에는 전역 객체(global object)가 존재하는데, 전역 변수를 선언하면 이는 전역 객체의 프로퍼티가 된다. 브라우저에서는 전역 객체에 window라는 프로퍼티가 존재하는데 이는 전역 객체 자신을 가리킨다.

 

ex) 모두 전역 변수

 

 

전역 객체는 this를 통해서도 접근이 가능하다.

 

ex)

 

 

전역 변수의 문제점

전역 변수의 문제점은 애플리케이션이나 웹페이지 내 모든 코드 사이에서 공유된다는 점이다.

ex) 덮어 쓰기

 

만약 개발자가 자신이 작성하지 않은 외부 코드를 가져와 삽입했을 때, yyy = 0;은 개발자가 정의한 코드이며 test 함수는 외부 코드라고 가정한다면 개발자가 test 함수를 실행했을 때 전역 변수 yyy가 10이 되는 원치않는 결과를 초래할 것이다.

 

이러한 문제를 피하기 위해서 전역 변수에 대한 안티 패턴과 개선하는 코드를 알아 보자.


1. var를 통한 변수 선언

ex) 암묵적 전역 코드 사용 == 안티 패턴

 

자바스크립트에는 암묵적 전역(implied globals)이라는 개념이 있기 때문에 선언하지 않고 사용한 변수는 자동으로 전역 객체의 프로퍼티가 되어 명시적으로 선언된 전역 변수처럼 사용될 수 있다.

 

안티 패턴을 피하기 위해서는 언제나 var를 사용하여 변수를 선언하는 것이 좋다.

 

ex) var 변수 선언

 

유효 범위 안에서만 사용 가능하여 덮어쓰기 같이 의도치 않는 실수가 일어나지 않도록 방지해준다.

 


2. var 선언에서의 연쇄적 할당

아래는 var 선언에 여러 변수를 연쇄적으로 할당한 코드의 예이다.

 

ex)

 

두 변수가 지역 변수로 할당될 것이라 예상하지만 사실 b는 전역 변수가 된다. 그 이유는 자바스크립트는 표현식의 "평가(evaulation)"가 오른쪽에서 왼쪽으로 진행되기 때문이다. 코드의 평가는 아래와 같이 된다.

 

괄호 안의 b = 0 이라는 식이 먼저 평가되는데, 이때 b는 var를 통해 선언되는 것이 아니므로 전역 변수가 된다.

 

 

변수를 미리 선언해둠으로써 연쇄 할당문의 전역 변수 생성을 피할 수 있다.

 

ex) 안티 패턴 피하기

 

 


3. 단일 var 패턴 (유용)

함수의 상단에 var 선언을 한 번만 쓰는 패턴은 유용하고 시도해 볼 만하다.

책 에서는 다음과 같은 이점이 있다고 소개한다.

  • 함수에서 필요로 하는 모든 지역 변수를 한군데서 찾을 수 있다.
  • 변수를 선언하기 전에 사용할 때 발생하는 로직상의 오류를 막아준다. [호이스팅(hoisting)과 같은]
  • 변수를 먼저 선언한 후에 사용해야 한다는 사실을 상기시키기 때문에 전역 변수를 최소화하는 데 도움이 된다.
  • 코드량이 줄어든다. (작성량과 전송량 모두 줄어든다)

코드는 아래와 같이 표현한다.

 

ex) 단일 var 패턴의 예

 

var 선언을 하나만 쓰고 쉼표를 통해 여러 변수들을 선언했다.

자바스크립트는 C와 Java와 같은 언어처럼 정적 타이핑(static type)이 아닌 동적 타이핑(dynamic type)이다. int와 char와 같이 변수의 용도에 따라 타입(type)을 미리 명시해주는 것이 아닌, var 변수에 어떤 값을 할당하든 실행 시에 자바스크립트 엔진에서 자동으로 타입(type)을 구분해준다.

이런 성격으로 인해 개발자가 매우 편리하게 코드를 작성할 수 있지만, 나중에 코드가 매우 방대해지고 용어의 뜻이 불분명할 때는 변수의 용도를 확인하기가 어려워지며 오류 또한 발생하기 쉽다.

그러므로 위와 같이 변수를 선언할 때 초기 값을 주어 초기화하는 것 역시 좋은 습관이다. 문법 오류를 막을 수 있고 코드 가독성도 향상된다.

또한 자바스크립트는 "호이스팅(hoisting, 끌어올리기)"이라는 동작 방식이 있다. 실행 문맥(execution context) 글을 보면 자세히 알 수 있는데, 함수 범위 내에 흩어져 있는 변수는 값이 할당되기 전에 모두 함수 상단으로 끌어올려져 undefined 형태로 선언된다. 이러한 특성은 로직상의 오류를 범하기 쉽기 때문에, 함수 상단에 하나의 var 선언문을 사용하여 변수들을 모아놓는 패턴을 사용하는 것이 좋다.

 

DOM(Document Object Model) 참조를 다루는 것도 좋은 예다.
다음 예제와 같이 DOM 참조를 할당한 지역 변수들을 하나의 선언문에 모아놓는다.

 

ex)

 

'JavaScript' 카테고리의 다른 글

자바스크립트 : for, for-in 패턴  (0) 2018.01.22
Vue.js : Virtual DOM.md

Vue.js 2.0에 새롭게 추가된 "Virtual DOM"에 대하여...

Vue.js 는 주로 Angular와 React의 장점들을 고루 갖고 있는 특징이 있다.

이번에 Vue.js 2.0 버전의 주요 특징 중 하나로 페이지 변경을 위한 "Virtual DOM" 이 추가되었다.

"Virtual DOM"은 React에서 많이 들어보았을 것이다.

React와 Ember에서 사용하는 이 "가상 돔"은 웹 페이지의 변경 속도를 매우 빠르게 해준다.

 

먼저 가상 돔의 원리를 이해하기 전에 브라우저의 동작 원리DOM에 대한 몇 가지 특징을 알아볼 필요가 있다.

 

 

브라우저의 동작

사용자가 웹 브라우저의 주소 표시줄(사용자 인터페이스)에 URL을 입력하면 브라우저 엔진은 이를 해석하고,

적절한 HTTP Request Message를 만들어 웹 서버에 전달하게 된다. 웹 서버는 요청된 방식에 따라 응답 메시지를 만들

어 클라이언트에게 다시 보내준다. 브라우저의 렌더링 엔진 은 웹 서버에서 응답한 메시지의 콘텐츠를 화면에 표시한다.

( 예를 들어 HTML을 요청하면 HTML과 CSS를 파싱하여 화면에 표시 )

 

렌더링 엔진의 기본적인 동작 과정 ( HTML만을 예시로 들자면 )
DOM 트리 구축을 위한 HTML 파싱 => 렌더 트리 구축 => 렌더 트리 배치 => 렌더 트리 그리기 -> 표시

( 보다 자세한 렌더링 과정은 "브라우저는 어떻게 동작하는가?" 문서를 보길 바란다 )

HTML 파싱 과정에서 DOM 트리가 생성되는데 "DOM" 이 무엇인지 알아보자

 

DOM(Document Object Model)

문서의 객체 모델

- HTML 내에 들어 있는 요소를 구조화 객체 모델로 표현 하는 양식

 

HTML 문서가 아래와 같다면

 

 

DOM 트리 구조는 아래처럼 표현할 수 있다. ( 이미지 출처 - http://d2.naver.com/helloworld/59361 )

 

domtree

 

 

DOM의 특징

  • 위의 그림과 같이 트리의 부모 자식 관계로 형성

  • HTML 요소들(nodes)을 탐색하고 수정할 수 있는 API를 제공

    ex) getElementById, removeChild

     

DOM의 문제점

= "It’s expensive to update the DOM"

 

우리는 스크립팅 언어인 자바스크립트를 사용하여 웹페이지를 동적으로 변경시킨다.

이 때, 브라우저는 목표 DOM 노드들을 찾은 후 원하는 변경 사항에 맞게 조작하기 위해 몇 가지 작업을 한다.

 

 

일반적인 앱에서, DOM에는 수 천개의 노드들이 존재할 수 있고 업데이트를 위해 복잡한 처리 과정이 필요하게 된다.

이로 인해 브라우저의 속도는 느려지게 된다. 상단의 브라우저 동작 원리를 설명한 이유는 이 문제점 속에 있다.

먼저 브라우저에서 페이지를 로드하게 되면 렌더링 트리와 돔 트리를 생성하게 되고 여러 과정을 거쳐서 브라우저에 CSS가 적용된 페이지가 그려지게 된다. 여기서 자바스크립트로 DOM을 조작할 때 렌더링 트리는 각 변경 사항마다 하나씩 해석하여 렌더링을 시키게 되는 구조이다.

그런데 만약 한 번의 상태 변경으로 여러곳의 DOM 변경(노드들의 수정)이 일어난다면 어떻게 될까?

수 천개의 노드들이 변경되어 렌더링 되기까지 적지 않은 시간이 걸릴 것이다.

현재까지 웹에서는 DOM 변경에 맞추어 렌더링도 여러번 하게 되는 구조일 수 밖에 없었다. 그리고 사실 pure JavaScript를 사용해 DOM 객체를 조작하는 비용보다 DOM을 조작했을 때 화면을 다시 그리는 비용(렌더링 계산)이 훨씬 크다.

(https://www.slideshare.net/gyeongseokseo/virtual-dom 참고)

 

이를 해결하기 위해 등장한 것이 "Virtual DOM" 가상 돔이다.

 

가상 돔 (Virtual DOM)

  • 먼저 가상 돔은 리액트에서 나온 개념이 아니다. 하지만 리액트는 무료로 이 개념을 사용하고 사용자들에게 제공한다. Vue.js도 마찬가지이다.

  • 가상 돔은 HTML 돔의 추상화 개념이다. 이것은 가볍고, 브라우저 스펙의 구현체와는 분리되어있다. 사실, 돔은 이미 추상화 개념이기 때문에 가상 돔은 추상화를 또 추상화한 개념이다.

  • DOM의 복사본을 메모리 내에 저장하여 사용

  • 변경 사항을 "가상의" 위치에서 처리하고, "실제 DOM"의 조작을 최소화한다. 즉, DOM트리를 모방한 가벼운 자바스크립트 객체를 통해 직접 DOM을 핸들링 하지 않고 퍼포먼스를 향상시킨다.

     

DOM 노드들은 일반적으로 HTML 문서에서 아래와 같이 표현된다.

 

아마도 아래 코드는 우리가 DOM API를 사용하여 DOM을 변경하는 방법일 것이다.

 

 

가상 DOM 노드들은 이처럼 자바스크립트 객체 형식으로 표현될 수 있다.

 

아마도 아래 코드는 우리가 가상 DOM을 변경하는 방법일 것이다.

 

 

DOM 조작을 위해서 getElementById와 같은 DOM API를 사용한 코드가 아닌 가상 돔을 사용한다면,
코드는 단지 자바스크립트 객체로 변경되는 매우 저렴한 비용이 들 것이다.

 

그런 다음, 아래 코드를 통해 가상 돔 변경 부분과 실제 돔의 동기화 작업이 이루어진다.

 

 

이런 방법으로 한 번의 상태 변경으로 여러곳의 DOM이 변경된다고 해도 가상화된 DOM에서 전부 변경하고
진짜 돔과 비교해서 변경된 부분을 한번에 적용시키는 방식으로 DOM의 렌더링 횟수를 줄이게 된다.

 

Vue.js version 2에서 추가된 가상 돔은 과연 괜찮을까?

 

1. 크기

가상 돔의 추가와 같은 여러 기능을 추가하기 위해서는 코드 패키지에서 많은 수의 라인을 추가하는 것을 의미한다.

그렇지만 Vue.js 2.0은 여전히 작은 파일 크기를 유지한다. (현재 릴리즈는 21.4kb)

2. 메모리

가상 돔의 유지를 위해서는 메모리 내에 DOM의 복사본을 생성한다.

돔의 변경 속도와 메모리 사용을 교환한 것이다.

3. 사용 환경

가상 돔은 많은 수의 변경 사항을 한꺼번에 처리할 때 사용하는 것을 추천한다.

하지만 단일 변경 사항이 드물게 일어난다면? 가상 돔은 돔 변경을 하기위해 무의미한 연산을 할 것이다.

 

그러므로, 만약 프로젝트가 상대적으로 적은 노드 수가 있다면 오히려 가상 돔으로 인해 페이지의 변경 속도가 느려질 것이다.

하지만 대부분의 단일 페이지 애플리케이션에서는 향상된 성능을 가질 것이다.

 


 

Vue.js의 가상 돔의 코드를 확인하고 싶다면 https://github.com/vuejs/vue/tree/dev/src/core/vdom 확인

 


 

Vue.js를 공부하다 나온 "가상 돔"을 이해하기 쉽게 설명드리고 싶었지만 어쩌다보니 구글링한 문서들의 내용들이 짬뽕이 되었습니다.. 아직 확실하게 이해못한 가상돔 개념과 처음으로 시도한 블로그 포스팅이 만나, 매우 부족한 글을 쓰게된 것 같습니다. 너그러운 마음으로 글을 봐주시길 바랍니다! Vue.js를 공부하면서 확실한 개념을 잡아갈 때마다 글을 다시 수정하도록 하겠습니다. 감사합니다.

 


 

참고 링크들

'Vue.js' 카테고리의 다른 글

MVVM(Model-View-ViewModel) in Vue.js  (0) 2018.01.19

+ Recent posts