210417 Mobile first 방식의 이점과 간단한 HTML 마크업과 CSS 스타일링 예시

Mobile first & Responsive design

Mobile-First 방식 ?

이번 포스팅에서는 모바일 우선(Mobile-First) 웹 디자인에 대해서 정리를 하려고 한다.
요즘 간단한 화면의 구성요소들을 모듈형태로 나눠서 프로젝트식으로 만들어보고 있는데, 모두 Mobile-first 방식으로 웹 디자인을 하고 있다.
이전에 반응형 웹 페이지를 만들때는 아무 생각없이 처음에 Desktop 기준으로 웹 페이지를 디자인하는 경우가 많았는데, 모바일 우선 방식으로 웹 페이지를 디자인 하는 것이 더 효율적이라는 것을 알게 된 후부터는 시작할때 모바일 기준으로 HTML 마크업을 하고 CSS 스타일링을 하고 있다.

이번 포스팅에서는 왜 모바일 우선으로 웹 페이지를 디자인해야 되는지에 대해서 공부한 내용을 기반으로 내용을 작성해보려고 한다.

우선 Desktop과 Mobile의 사용률을 보았을때 2014년도를 기점으로 Mobile 사용률이 Desktop 사용률을 넘어섰다. 단순히 이러한 사용률만의 문제가 아니라 모바일 우선 방식으로 웹 페이지를 디자인했을때 생기는 이점들에 대해서 정리를 해보겠다.

우선 첫 번째, 구글은 Mobile-First Index를 사용한다. 구글은 우리가 모두 다 아는 대규모 검색 엔진으로 구글이 모바일에 올인하고 있다. 구글의 검색 알고리즘이 모바일 버전 사이트의 콘텐츠를 사용하여 해당 사이트의 검색 노출 페이지 순위를 매긴다는 의미이다. 만약 본인이 개발한 웹 페이지가 구글에서 많이 노출되길 원한다면 웹 페이지를 모바일 우선 방식으로 디자인하는 것이 좋다.

두 번째, 좋은 사용자 경험(UX)을 줄 수 있다. 일반적으로 모바일 사용자는 빠른 웹 사이트 로드를 기대한다. 만약 웹 페이지가 모바일 우선 방식으로 디자인이 되어있다면, 모바일 사용자가 초기에 웹 페이지를 로드했을때 빠르게 페이지가 로드되어 사용자에게 좋은 경험을 줄 수 있다.

세 번째, 빠른 웹 사이트를 만들 수 있다. 두 번째 이점과 거의 같은 맥락의 이야기지만, 모바일 화면에서 보여지는 페이지의 요소는 상대적으로 데스크탑 웹 페이지에 비해 화면에 보여지는 요소가 적다. 만약 반응형 디자인으로 페이지가 디자인되어 있고, 모바일에서 해당 웹 페이지를 로드한다면, 초기에 로드되어야 하는 화면의 요소가 데스크탑 기준으로 우선 로드되고, 미디어 태그로 조건 처리된 모바일 기준 스타일이 다음으로 적용되어 상대적으로 느린 웹 페이지 로드를 보여 줄 수 있다.

Read More

210417 Self Development TIL

Thought of the day

쉬워 보이는 일도 해보면 어렵다. 못할 것 같은 일도 시작해 놓으면 이루어진다. 쉽다고 얕볼 것이 아니고, 어렵다고 팔짱을 끼고 있을 것이 아니다. 쉬운 일도 신중히 하고 곤란한 일도 겁내지 말고 해보아야 한다. (채근담)

인생일식 - Must와 Want가 Cross되었을때 이때를 위해 인생을 살고 있는 것일지도 모른다. 바로 이때 목숨을 걸고 최선을 다해야 한다.

2021년 04월 17일 오늘은 02시 30분에 일어나서 03시 20분에 공부를 시작했다. 오늘부터 5월초까지 새로운 생활루틴으로 한 번 생활해보려고 한다. 기회가 오기 전까지 실력을 끌어올리자.

TO DO LIST

  • A → V → R → Z


  • Vanilla JS and ReactJS 실습

    • VanillaJS로 sidebar, modal (+scroll) 만들기 (완료)
    • ReactJS로 sidebar + modal 만들기 (완료) - custom hook (useContext + AppContext 관련 내용 정리하기)

  • 기본 알고리즘 문제풀기

    • 기본 알고리즘 문제 10문제 풀이 (1/10 완료)


  • 블로그 포스팅

    • Mobile-First 방식의 이점과 간단한 HTML 마크업과 CSS 스타일링 관련 글 포스팅하기 (완료)
    • Vanilla JavaScript Traversing DOM & using Selectors inside of the element에 대해서 포스팅하기 (예정)
    • React TIL 작성 (작성중...)
    • React 상태관리에 대해서 블로그 포스팅하기 (작성중...)
    • React project의 개괄적인 내용에 대해서 블로그 포스팅하기 (작성중...)
    • Vanilla JavaScript TDD Practice 관련 블로그 포스팅하기 (작성중...)
    • 동기/비동기에 대해서 블로그 포스팅하기 (예정)

  • Slack clone

    • Repository 생성하기 (예정)


  • TDD Practice with VanillaJS

    • ~#Issue ~ (예정)

  • TDD Practice with NodeJS

    • #Issue 10 ~ (진행중...)

    Read More

210416 JavaScript와 친해지기 - 클로저(Closure)와 즉시실행 함수(IIEF)에 대한 이야기

Closure와 IIFE

이번 포스팅에서는 아직은 조금 낯설은 클로저(Closure)에 대해서 정리를 해보려고 한다.

클로저(Closure)

클로저에 대한 정의는 ECMAScript에 없다. 다만 클로저는 자바스크립트가 채용하고 있는 기술적 기반/컨셉이다.
자바스크립트는 클로저를 이용하여 스코프적 특징과 함수에 대한 명세를 구현하였다.
다시 말해 클로저(Closure)는 ECMAScript의 명세에는 없지만 스코프와 스코프와 긴밀한 관련이 있는 1급 객체로서의 함수와 매우 관련이 깊다.

자 그럼 누군가 클로저(Closure)가 뭐냐고 물어본다면 뭐라고 대답할 수 있을까?

inner function은 항상 outer function의 변수와 인자에 접근을 할 수 있다. 비록 outer function이 이미 호출되어 값이 반환되었을지라도 outer function의 변수 객체에 접근이 가능한 이유가 바로 클로저(Closure) 덕분이다.

아직 설명이 부족하기 때문에 아래 간단한 예시를 살펴보자.

simple example(1)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function add(a) {
var x = '두 숫자의 합은 ';
return function (b) {
var sum = a + b;
console.log(x + sum);
};
}

var totalSum = add(10);
totalSum(5);

// output: 두 숫자의 합은 15

add(10);
/*
ƒ(b){
var sum = a + b;
console.log(x + sum);
}
*/

add(10)(4);
// output: 두 숫자의 합은 14

JavaScript에서 함수는 1급 객체(First-Class Objects)로써 정의되었기 때문에 위와같이 함수 내에서 함수를 반환할 수 있는 것이다.

자 그럼 위의 결과값부터 말을 하자면 두 숫자의 합은 15이다. 새로운 함수는 새로운 함수 실행 컨텍스트를 갖는다. 이전에 스코프에 대해서 블로그 포스팅을 했을때 이미 자세히 다뤘듯이 실행 컨텍스트 내부에는 코드가 실행되기 위한 다양한 정보(변수, 함수 등)들과 참조 속성에 대한 정보가 담긴다. 이 참조 속성이 상위 스코프의 실행 컨텍스트의 참조 속성으로 연결되어 변수를 참조하는 것을 스코프 체인(Scope chain)이라고 정의를 한다.

Read More

210416 기본 정렬 알고리즘 자바스크립트로 구현하기 (선택정렬, 버블정렬, 삽입정렬)

Basic sorting algorithms

기본 정렬 알고리즘 구현하기

이 기본 정렬 알고리즘은 직접 손 코딩 할 수 있을 정도로 코드를 익혀야 하기 때문에 반복 복습을 위해 블로그 포스팅을 해두기로 했다.
코딩 테스트 문제를 풀때 내장된 sort 함수를 사용해서 간편하게 정렬을 해서 문제 해결을 하지만, 기존에 있는 정렬 알고리즘의 구현을 이해하고 필요에 따라 기존 정렬 알고리즘을 응용해서 새로운 알고리즘을 만들어 낼 수 있는 능력도 필요하다.
그럼 자바스크립트 언어로 코딩테스트를 준비하고 있기 때문에 자바스크립트로 각 기본 정렬 알고리즘을 구현 및 정리를 해보겠다.

선택정렬(Selection sort) - O(N^2) 시간복잡도/정수 6만개 기준, 10.842(sec)

우선 선택 정렬에 대해서 코드 구현을 하기 전에 간단하게 선택정렬을 어떻게 구현해야 되는지 설명을 하겠다.
선택정렬은 버블정렬과 같이 1회 순회에 한 개 요소의 위치가 결정이 된다. (가장 작은 값(왼쪽부터 오른쪽으로) 결정)
이중 for-loop의 형태로 i: 0 ~ arr.length, j: i+1 ~ arr.length로 순회를 한다.
그리고 j의 범주로 순회를 하면서 가장 작은 값의 index를 찾는다. 가장 작은 값의 index를 찾았다면, 최소값의 index위치와 i번째 index위치를 바꿔준다. 이 과정을 i의 범주로 순회를 하면 정렬이 완료된다.
그럼 코드로 한 번 구현을 해보겠다.

1
2
3
4
5
6
7
for (let i = 0; i < arr.length; i++) {
let index = i;
for (let j = i + 1; j < arr.length; j++) {
if (arr[j] < arr[index]) index = j;
}
[arr[i], arr[index]] = [arr[index], arr[i]];
}

Read More

210416 Self Development TIL

Thought of the day

쉬워 보이는 일도 해보면 어렵다. 못할 것 같은 일도 시작해 놓으면 이루어진다. 쉽다고 얕볼 것이 아니고, 어렵다고 팔짱을 끼고 있을 것이 아니다. 쉬운 일도 신중히 하고 곤란한 일도 겁내지 말고 해보아야 한다. (채근담)

인생일식 - Must와 Want가 Cross되었을때 이때를 위해 인생을 살고 있는 것일지도 모른다. 바로 이때 목숨을 걸고 최선을 다해야 한다.

2021년 04월 16일 오늘은 02시 00분에 일어나서 02시 45분에 공부를 시작했다. 오늘부터 5월초까지 새로운 생활루틴으로 한 번 생활해보려고 한다. 기회가 오기 전까지 실력을 끌어올리자.

TO DO LIST

  • A → V → R → Z


  • 기본 알고리즘 문제풀기

    • 기본 알고리즘 문제 10문제 풀이 (6/10 완료)


  • Vanilla JS and ReactJS 실습

    • VanillaJS로 Accordion 만들기 (완료)
    • ReactJS로 Accordion 만들기 (완료)
  • 블로그 포스팅

    • JavaScript IIFE와 클로저(Closure)에 대해서 블로그 포스팅하기 (완료)
    • Vanilla JavaScript Traversing DOM & using Selectors inside of the element에 대해서 포스팅하기 (예정)
    • React TIL 작성 (작성중...)
    • React 상태관리에 대해서 블로그 포스팅하기 (작성중...)
    • React project의 개괄적인 내용에 대해서 블로그 포스팅하기 (작성중...)
    • Vanilla JavaScript TDD Practice 관련 블로그 포스팅하기 (작성중...)
    • 동기/비동기에 대해서 블로그 포스팅하기 (예정)

  • Slack clone

    • Repository 생성하기 (예정)


  • TDD Practice with VanillaJS

    • ~#Issue ~ (예정)

  • TDD Practice with NodeJS

    • #Issue 10 ~ (진행중...)

    Read More

210415 React TIL - useReducer, setState의 비동기적 처리, useReducer에서 dispatch를 통한 state 업데이트(비동기 처리), 성능 최적화

React

본 포스팅 내용은 과거에 개인적으로 공부할때 정리했던 ReactJS의 내용을 복습의 목적으로 다시 정리하는 포스팅입니다.

useReducer

React에서 Redux의 핵심 기능을 useReducer로써 구현하였다. useReducer + context API의 조합으로 Redux를 대체할 수 있을 것이라고 생각할 수 있다. 작은 앱의 경우에는 괜찮지만, 비동기 처리의 한계로 어플리케이션의 규모가 커지게 되면 Redux를 사용해서 구현하는 편이 좋다.
state의 갯수가 늘어나게 되면, useState를 통한 state관리 코드가 많아진다. 이러한 경우 useReducer를 사용해서 하나의 state와 setState로 통합해 줄 수 있다.

state 객체는 아무도 직접적인 수정이 불가하다. 다만 dispatch를 통해 action object를 인수로써 호출하게 되면 action object의 type에 정의된 action의 종류에 따라 reducder 함수에서 정의된 state 업데이트 방식에 의해 state가 업데이트된다.

1
2
3
4
5
// useReducer의 첫 번째 인수로는 정의한 reducer 함수를 넣어주고, 두 번째 인수로는 state 초기 상태를 정의해준다.
const [state, dispatch] = useReducer(reducer, initialState);

// event 처리부분
dispatch({ type: 'SET_RESULT', result: 'ABC' });

reducer 함수 예시

1
2
3
4
5
6
7
8
9
const reducer = (state, action) => {
switch (action.type) {
case 'SET_RESULT':
return {
...state,
result: action.result
};
}
};

나중을 위해 action의 이름은 개별 상수로 따로 빼서 관리하도록 한다.
추가적으로 관리해야 될 state가 있다면 action을 추가하고 해당 action에 대한 구체적인 state 업데이트 방식을 reducer 함수에 정의하도록 한다.

기존의 state를 업데이트할때 사용할 상태값은 reducer 함수의 두 번째 인자(action)로부터 넘겨준다.

(Redux는 Facebook의 Flux와 함수형 프로그래밍에 영감을 받아 2015년 6월경에 Dan Abramov에 의해 개발되었다)

Read More

210415 Algorithm javascript로 queue를 사용한 문제풀이

JavaScript shift method

큐를 활용한 문제풀이

이번 포스팅에서는 자바스크립트로 큐(queue)를 이용한 문제풀이에 대해서 사용되는 배열의 메서드에 대해서 간단하게 정리하고 관련 문제를 풀이해보려고 한다.

우선 pop과 push의 경우에는 배열의 맨 마지막 요소를 빼거나(pop) 추가(push)할때 사용하고, shift는 배열의 맨 앞 요소를 빼고, unshift는 맨 앞에 요소를 추가할때 사용한다.

  • 배열을 일정 길이로 초기화하는 두 가지 방법

1
2
3
4
// index를 값으로 갖는 길이가 10인 배열 만들기
new Array(10).fill(null).map((v, i) => i);
// Array의 정적 메서드 from을 사용하여 길이 및 내부 요소값 초기화하기
Array.from({ length: 10 }, (v, i) => i + 1);
  • 문제풀이

    길이가 N개인 배열에서 0번째 인덱스부터 M번째 떨어진 숫자를 배열내에 한 개의 숫자가 남을때까지 반복해서 제거한다고 했을때 최종적으로 남을 단 하나의 숫자는 무엇인가?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
const fs = require('fs');
const stdin = (process.platform === 'linux' ?
fs.readFileSync('/dev/stdin').toString() :
`8 3`).split('\n');
const input = (() => {
let line = 0;
return () => stdin[line++];
})();

{
const [n, m] = input().split(' ').map(n => +n);

const queue = Array.from({ length: n, (v, i) => i + 1});
let answer;

while(queue.length){
for(let i = 1; i < m; i++){
queue.push(queue.shift());
}
// 세 번째 요소는 그냥 shift
queue.shift();
if(queue.length === 1) answer = queue.shift();
}
console.log(answer);
}

210413 React TIL - PureComponent와 React.memo, useMemo와 useCallback, 자식 컴포넌트의 props로 함수를 넘겨줄때, hooks의 순서

React

본 포스팅 내용은 과거에 개인적으로 공부할때 정리했던 ReactJS의 내용을 복습의 목적으로 다시 정리하는 포스팅입니다.

PureComponent와 React.memo

클래스형 컴포넌트에서는 PureComponent를 상속받아서 컴포넌트 최적화를 시켜줄 수 있고, 함수형 컴포넌트에서는 함수몸체를 React.memo로 감싸서 PureComponent와 같이 컴포넌트를 최적화 시켜 줄 수 있다. 이렇게 컴포넌트로 다른 컴포넌트를 감싸는 것을 HOC(Higher Order Component라고 한다.

useCallback과 useMemo의 비교

useCallback은 함수자체를 기억하고, useMemo는 함수의 반환값 자체를 기억한다.
함수형 컴포넌트의 경우에는 재실행될 때 함수 전체가 재실행되기 때문에 한 번 생성한 함수를 재생성하지 않고 재활용하기 위해서는 useCallback을 사용한다.
useCallback의 내부에서 사용되는 state 값이 있는 경우에는, 반드시 두 번째 인자인 []내에 작성해줘야 한다.

이렇게 되면 비효율적이기 때문에 특정 값이 변경될때에만 해당 함수가 호출되어 초기 상태값을 업데이트 할 수 있도록 useMemo를 사용해서 작성해줘야 한다.
만약 특정 함수로부터 반환받은 값을 상태의 초기값으로 사용하는 경우, 함수 자체를 useState의 초기값에 넣어주게 되면, 해당 함수는 함수 컴포넌트가 실행될 때마다 재생성된다. 따라서 아래와 같이 useMemo를 사용해서 상태값을 갱신해서 사용해야 한다.

Read More

210412 React TIL - setTimeout(), useEffect()/useMemo()/useCallback(), useState와 useRef의 차이, jsx에서 if/for문 작성, React class/function - 라이프 사이클

React

본 포스팅 내용은 과거에 개인적으로 공부할때 정리했던 ReactJS의 내용을 복습의 목적으로 다시 정리하는 포스팅입니다.

React에서 jsx를 구조있게 작성하기

필요에 따라 jsx 작성 부분이 조건문이나 반복문으로 복잡해진다면, 별도의 함수나 자식 컴포넌트로 작성해주도록 한다.

setTimeout() 사용법

setTimeout의 첫 번째 인수로는 콜백 함수를 넣어주고 두 번째 인수로는 ms단위로 interval time을 적어준다. setTimeout()은 비동기 함수이기 때문에 외부에 선언한 변수를 참조할 경우, 클로저 문제가 생긴다.
따라서 setTimeout()내에서 사용할 변수의 경우에는 setTimeout() 내에서 처리하도록 한다.
setTimeout()을 해줬다면 clearTimeout()을 해줘야 한다. 만약 clearTimeout()을 해주지 않으면, setTimeout()을 처리한 컴포넌트가 제거되더라도 call stack에 남아 계속 실행될 수 있다.

Read More

210411 React TIL - 상태의 불변성, React DevTools, 배포모드, 성능에 대한 이야기, React.createRef, props와 state 연결하기

React

본 포스팅 내용은 과거에 개인적으로 공부할때 정리했던 ReactJS의 내용을 복습의 목적으로 다시 정리하는 포스팅입니다.

상태의 불변성

push를 이용해서 컴포넌트의 상태를 직접 바꿔주게 되면, React가 구체적으로 무엇이 바뀌었는지 감지하지 못한다. 따라서 원본은 그대로 두고, 바뀌는 상태 데이터는 원본을 복사해서(얕은 복사) 상태를 업데이트 해주도록 한다.

React의 Rendering 기준은 이전 상태값과 현재 상태값이 다른 경우 Re-rendering을 해준다.

  • arr1 === arr2 // false (Re-rendering) - 이전 상태와 현재 상태가 같지 않은 경우만 렌더링
  • arr1 === arr2 // true

내부에서 this를 사용하지 않는 함수의 경우에는 외부로 빼주도록 한다.

setState에서의 함수형 업데이트

상태를 업데이트 해주는 setState 함수는 비동기 방식이기 때문에 setState함수를 여러번 연달아 사용하는 경우 문제가 생길 여지가 있다. 따라서 setState 내부에서 또 다른 상태값을 참조해서 상태를 업데이트 시키는 경우에는 함수형으로 이전 상태값을 받아서 새로운 상태로 업데이트시켜줘야 한다.
(class component, functional component(hooks) 둘 다 )

1
2
3
const [tries, setTries] = useState([]);

setTries((tries) => [...tries, { try: value, result: 'good!' }]);

Read More