๋ณธ๋ฌธ์œผ๋กœ ๊ฑด๋„ˆ๋›ฐ๊ธฐ

"๋ฉด์ ‘ ์ค€๋น„" ํƒœ๊ทธ๋กœ ์—ฐ๊ฒฐ๋œ 7๊ฐœ ๊ฒŒ์‹œ๋ฌผ๊ฐœ์˜ ๊ฒŒ์‹œ๋ฌผ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

๋ชจ๋“  ํƒœ๊ทธ ๋ณด๊ธฐ

ยท ์•ฝ 14๋ถ„

TypeScript#

๋ชฉํ‘œ#

  • TypeScript๋กœ ํƒ€์ดํ•‘์„ ์ž˜ํ•˜๋ฉด, ๋Ÿฐํƒ€์ž„ ์ „์— ๋ฏธ๋ฆฌ ์˜ค๋ฅ˜๋ฅผ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์ฝ”๋“œ์˜ ๊ตฌํ˜„์ž๊ฐ€ ์‚ฌ์šฉ์ž์—๊ฒŒ ์˜๋„๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค.

ํƒ€์ž… ์‹œ์Šคํ…œ#

  • ์ปดํŒŒ์ผ๋Ÿฌ์—๊ฒŒ ์‚ฌ์šฉํ•˜๋Š” ํƒ€์ž…์„ ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •ํ•˜๋Š” ์‹œ์Šคํ…œ

  • ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ž๋™์œผ๋กœ ํƒ€์ž…์„ ์ถ”๋ก ํ•˜๋Š” ์‹œ์Šคํ…œ

โ˜ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๋Š” ํƒ€์ž…์„ ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๊ณ  ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฉด์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ž๋™์œผ๋กœ ํƒ€์ž…์„ ์ถ”๋ก ํ•œ๋‹ค.


๋ช…์‹œ์  ํƒ€์ž… vs ์ถ”๋ก #

// ํ•จ์ˆ˜์˜ ๋ฆฌํ„ด ํƒ€์ž…์€ number๋กœ ์ถ”๋ก ๋œ๋‹ค.// ํ•˜์ง€๋งŒ ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ํƒ€์ž…์„ ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •ํ•˜์ง€ ์•Š์•„์„œ, any๋กœ ์ถ”๋ก ๋œ๋‹ค.function f(a) {    return a * 38;}
// ์‚ฌ์šฉ์ž๋Š” a๊ฐ€ any ์ด๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉ๋ฒ•์— ๋งž๊ฒŒ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ–ˆ์ง€๋งŒ, ์‚ฌ์šฉ์ž๋Š” ์˜ˆ์ธกํ•˜์ง€ ๋ชปํ•œ ๊ฒฐ๊ณผ๋ฅผ ์–ป๊ฒŒ ๋œ๋‹ค.console.log(f(10)); // 380console.log(f('Mark')); // NaN

์ด๊ฒƒ์€ noImplicitAny ์˜ต์…˜์„ ํ†ตํ•ด ๋ฐฉ์–ดํ•  ์ˆ˜ ์žˆ๋‹ค. ํƒ€์ž…์„ ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •ํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ any ๋กœ ์ถ”๋ก ๋˜๋Š” ๋ณ€์ˆ˜๊ฐ€ ์žˆ์œผ๋ฉด ์ปดํŒŒ์ผ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.


// ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ํƒ€์ž…์„ ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •ํ–ˆ๋‹ค.// ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •ํ•˜์ง€ ์•Š์€ ๋ฆฌํ„ด ํƒ€์ž…์€ number๋กœ ์ถ”๋ก ๋œ๋‹ค.function f(a: number) {    if (a > 0) {        return a * 38;    }}
// ์‚ฌ์šฉ์ž๋Š” ์‚ฌ์šฉ๋ฒ•์— ๋งž๊ฒŒ ์ˆซ์žํ˜•์„ ์‚ฌ์šฉํ•ด์„œ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ–ˆ์ง€๋งŒ,// ์‹ค์ œ๋กœ๋Š” ํ•จ์ˆ˜์˜ ๋ฆฌํ„ด์ด undefined๋กœ, undefined + 5๊ฐ€ ์‹คํ–‰๋˜์–ด NaN์ด ์ถœ๋ ฅ๋œ๋‹ค.
console.log(f(5)); // 190;console.log(f(-5) + 5); // NaN

strictNullChecks ์˜ต์…˜์„ ์ผœ๋ฉด ๋ชจ๋“  ํƒ€์ž…์— ์ž๋™์œผ๋กœ ํฌํ•จ๋˜์–ด ์žˆ๋Š” null ๊ณผ undefined ๋ฅผ ์ œ๊ฑฐํ•ด์ค€๋‹ค.


// ์ด ํ•จ์ˆ˜์˜ ๋ฆฌํ„ด ํƒ€์ž…์€ number | undefined๋กœ ์ถ”๋ก ๋œ๋‹ค.function f(a: number) {    if (a > 0) {        return a * 38;    }}
// ํ•ด๋‹น ํ•จ์ˆ˜์˜ ๋ฆฌํ„ด ํƒ€์ž…์€ number | undefined ์ด๊ธฐ ๋•Œ๋ฌธ์—,// ํƒ€์ž…์— ๋”ฐ๋ฅด๋ฉด ์ปดํŒŒ์ผ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.// ์ปดํŒŒ์ผ ์—๋Ÿฌ๋ฅผ ๊ณ ์น˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ์ž์™€ ์ž‘์„ฑ์ž๊ฐ€ ์˜๋…ผํ•ด์•ผ ํ•œ๋‹ค.console.log(f(-5) + 5); // error TS2532: Object is possibly 'undefined'

ํ•˜์ง€๋งŒ ๊ฐ€๊ธ‰์ ์ด๋ฉด ๋ช…์‹œ์ ์œผ๋กœ ๋ฆฌํ„ด ํƒ€์ž…์„ ์ง€์ •ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

noImplicitReturns ์˜ต์…˜์„ ์ผœ๋ฉด ํ•จ์ˆ˜ ๋‚ด์˜ ๋ชจ๋“  ์ฝ”๋“œ์˜ ์ค„๊ธฐ๊ฐ€ ๊ฐ’์„ ๋ฆฌํ„ดํ•˜์ง€ ์•Š์œผ๋ฉด ์ปดํŒŒ์ผ ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค.


// error TS7030: Not all code paths return a valuefunction f(a: number) {    if (a > 0) {        return a * 38;    }}

์ด๋กœ ์ธํ•ด ๋ฆฌํ„ด ํƒ€์ž…์„ ๋ช…์‹œํ•˜๊ณ , ๋ชจ๋“  ์ค„๊ธฐ์— return ์„ ์ง์ ‘ ํ•˜๋„๋ก ๊ตฌํ˜„์ž์—๊ฒŒ๊ฐ•์ œํ•  ์ˆ˜ ์žˆ๋‹ค.


๋งค๊ฐœ๋ณ€์ˆ˜์— object๊ฐ€ ๋“ค์–ด์˜ค๋Š” ๊ฒฝ์šฐ#

function f(a) {  return `์ด๋ฆ„์€ ${a.name}์ด๊ณ  ์—ฐ๋ น๋Œ€๋Š” ${Math.floor(a.age / 10) * 10)}๋Œ€ ์ž…๋‹ˆ๋‹ค.`}
console.log(f({ name: 'Mark', age: 38 })); // ์ด๋ฆ„์€ Mark์ด๊ณ , ์—ฐ๋ น๋Œ€๋Š” 30๋Œ€ ์ž…๋‹ˆ๋‹ค.console.log(f('Mark')); // ์ด๋ฆ„์€ undefined์ด๊ณ , ์—ฐ๋ น๋Œ€๋Š” NaN๋Œ€ ์ž…๋‹ˆ๋‹ค.

JavaScript์—์„œ๋Š” ์ œ์•ฝ์‚ฌํ•ญ์œผ๋กœ ์•Œ๋ ค์ฃผ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋Ÿฐํƒ€์ž„์—์„œ ์˜ค๋ฅ˜๋ฅผ ํŒŒ์•…ํ•  ์ˆ˜์žˆ๋‹ค.

  • Object literal type
function f(a: { name: string, age: number }): string {  return `์ด๋ฆ„์€ ${a.name}์ด๊ณ  ์—ฐ๋ น๋Œ€๋Š” ${Math.floor(a.age / 10) * 10)}๋Œ€ ์ž…๋‹ˆ๋‹ค.`}
  • ๋‚˜๋งŒ์˜ ํƒ€์ž…์„ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•
interface PersonInterface {  name: string;  age: number;}
type PersonTypeAlias = {  name: string;  age: number;}
function f1(a: PersonInterface): string {  return `์ด๋ฆ„์€ ${a.name}์ด๊ณ  ์—ฐ๋ น๋Œ€๋Š” ${Math.floor(a.age / 10) * 10)}๋Œ€ ์ž…๋‹ˆ๋‹ค.`}
function f2(a: PersonTypeAlias): string {  return `์ด๋ฆ„์€ ${a.name}์ด๊ณ  ์—ฐ๋ น๋Œ€๋Š” ${Math.floor(a.age / 10) * 10)}๋Œ€ ์ž…๋‹ˆ๋‹ค.`}

interface vs type alias#

structural vs nominal type system#

ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๋Š” structural ํƒ€์ž… ์‹œ์Šคํ…œ์„ ์‚ฌ์šฉํ•œ๋‹ค.

  • structural type system : ๊ตฌ์กฐ๊ฐ€ ๊ฐ™์œผ๋ฉด, ๊ฐ™์€ ํƒ€์ž…์ด๋‹ค.

  • nominal type system : ๊ตฌ์กฐ๊ฐ€ ๊ฐ™์•„๋„ ์ด๋ฆ„์ด ๋‹ค๋ฅด๋ฉด, ๋‹ค๋ฅธ ํƒ€์ž…์ด๋‹ค.

interface IPerson {    name: string;    age: number;    speak(): string;}
type PersonType = {    name: string;    age: number;    speak(): string;};
  • typescript๋ฅผ nominal ์ฒ˜๋Ÿผ ์“ฐ๋Š” ๊ผผ์ˆ˜ ? - ์•„์ง ์ž˜ ์ดํ•ด๋ฅผ ๋ชปํ•จ
    type PersonID = string & {readonly brand: unique symbol};
    function PersonID(id: string): PersonID {    return id as PersonID;}
    function getPersonById(id: PersonID) {}
    getPersonById(PersonID('id-aaaaaa'));getPersonById('id-aaaaaa');

  • function
    type EatType = (food: string) => void;
    interface IEat {    (food: string): void;}
  • array
    type PersonList = string[];
    interface IPersonList {    [index: number]: string;}
  • intersection
    interface ErrorHandling {    success: boolean;    error?: {message: string};}
    interface ArtistsData {    artists: {name: string}[];}
    type ArtistsResponseType = ArtistsData & ErrorHandling;
    interface IArtistsResponse extends ArtistsData, ErrorHandling {}
  • union
    interface Bird {    fly(): void;    layEggs(): void;}
    interface Fish {    swim(): void;    layEggs(): void;}
    type BirdType = {    fly(): void;    layEggs(): void;};
    type FishType = {    swim(): void;    layEggs(): void;};
    // union์€ type alias๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.type PetType = Bird | Fish;
    // ์—๋Ÿฌ ๋ฐœ์ƒinterface IPet extends PetType {}class Pet implements PetType {}
    // ๊ฐ€๋Šฅinterface IBird extends BirdType {}class IFish implements FishType {}

Declaration Merging - interface#

  • ์ค‘๋ณต๋˜๋Š” ์ด๋ฆ„์œผ๋กœ ์„ ์–ธ๋˜์—ˆ์„ ๋•Œ ๋จธ์ง€๋˜๋Š” ๊ธฐ๋Šฅ์€ interface์—์„œ๋งŒ ์ œ๊ณต๋œ๋‹ค.

  • type์€ ์ค‘๋ณต์‹œ์— ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

  • ์ด๋Š” ์™ธ๋ถ€ ์œ ํ‹ธ์—์„œ ์‚ฌ์šฉ์ž๊ฐ€ ์›ํ•˜๋Š” ํƒ€์ž…์„ ์ถ”๊ฐ€ํ•ด์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

interface MergingInterface {    a: string;}
interface MergingInterface {    b: string;}
let mi: MergingInterface;// mi: { a: string, b: string }

์–ธ์ œ type์„ ์‚ฌ์šฉํ•˜๊ณ  ์–ธ์ œ interface๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๊ฐ€

  • ์˜๋ฏธ์ ์œผ๋กœ, ์—ญํ• ์ ์œผ๋กœ type alias๋ฅผ ํƒ€์ž…์— ๋ณ„์นญ์„ ๋ถ™์ผ ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

  • ์ฆ‰, ์ด๋ฏธ ์žˆ๋Š” ํƒ€์ž…์— ๋ณ„์นญ์„ ๋ถ™์—ฌ ๋‹ค๋ฅธ ์ด๋ฆ„์œผ๋กœ ๋ถ€๋ฅด๊ณ  ์‹ถ์„ ๋•Œ, ์ด๋ฏธ ์žˆ๋Š” ํƒ€์ž…์„ union์œผ๋กœ ์กฐํ•ฉํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

  • ๊ทธ ์™ธ์— ์ƒˆ๋กœ์šด ํƒ€์ž…์„ ์ƒ์„ฑํ•  ๋•Œ interface๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

    • ์‹ค์ œ ๋™์ž‘ ์ƒ์˜ ์ฐจ์ด๋Š” Merging์—์„œ์˜ ์ฐจ์ด๊ฐ€ ๊ฐ€์žฅ ์ค‘์š”ํ•˜๋‹ค.

์„œ๋ธŒ ํƒ€์ž…๊ณผ ์Šˆํผ ํƒ€์ž…#

์ง‘ํ•ฉ์˜ ๊ด€๊ณ„์—์„œ ํฌํ•จ๋˜๋Š” ์ชฝ์ด ์„œ๋ธŒ ํƒ€์ž…, ํฌํ•จํ•˜๋Š” ์ชฝ์ด ์Šˆํผ ํƒ€์ž…์ด๋‹ค.

let sub1: 1 = 1;let sup1: number = sub1;sub1 = sup1; // error! Type 'number' is not assignable to type '1'.
let sub2: number[] = [1];let sup2: object = sub2;sub2 = sup2; // error! Type '{}' is missing the following the properties from type 'number[]': length, pop, push, concat, and 16 more.
let sub3: [number, number] = [1, 2];let sup3: number[] = sub3;sub3 = sup3; // error! Type 'number[]' is not assignable to type '[number, number]'. Target requires 2 element(s) but source may have fewer.
let sub4: number = 1;let sup4: any = sub4;sub4 = sup4;
let sub5: never = 0 as never;let sup5: number = sub5;sub5 = sup5; // Type 'number' is not assignable to type 'never'.
class Animal {}class Dog extends Animal {    eat() {}}
let sub6: Dog = new Dog();let sup6: Animal = sub6;sub6 = sup6; // Property 'eat' is missing in type 'Animal' but required in type 'Dog'.

โ˜ any ์™€ never ๋Š” ์ถ”ํ›„์— ๋‹ค์‹œ ํ•™์Šต

๊ฐ™๊ฑฐ๋‚˜ ์„œ๋ธŒ ํƒ€์ž…์ธ ๊ฒฝ์šฐ ํ• ๋‹น์ด ๊ฐ€๋Šฅํ•˜๋‹ค. โ‡’ ๊ณต๋ณ€#

let sub7: string = '';let sup7: string | number = sub7;
// object - ๊ฐ๊ฐ์˜ ํ”„๋กœํผํ‹ฐ๊ฐ€ ๋Œ€์‘ํ•˜๋Š” ํ”„๋กœํผํ‹ฐ์™€ ๊ฐ™๊ฑฐ๋‚˜ ์„œ๋ธŒํƒ€์ž…์ด์–ด์•ผ ํ•œ๋‹ค.let sub8: {a: string; b: number} = {a: '', b: 1};let sup8: {a: string | number; b: number} = sub8;
// array - object์™€ ๋งˆ์ฐฌ๊ฐ€์ง€let sub9: Array<{a: string; b: number}> = [{a: '', b: 1}];let sup9: Array<{a: string | number; b: number}> = sub9;

ํ•จ์ˆ˜์˜ ๋งค๊ฐœ๋ณ€์ˆ˜ ํƒ€์ž…๋งŒ ๊ฐ™๊ฑฐ๋‚˜ ์Šˆํผํƒ€์ž…์ธ ๊ฒฝ์šฐ, ํ• ๋‹น์ด ๊ฐ€๋Šฅํ•˜๋‹ค โ‡’ ๋ฐ˜๋ณ‘#

class Person {}class Developer extends Person {    coding() {}}class StartupDeveloper extends Developer {    burning() {}}
function tellme(f: (d: Developer) => Developer) {}
// Developer => Developer ์—๋‹ค๊ฐ€ Developer => Developer ๋ฅผ ํ• ๋‹นํ•˜๋Š” ๊ฒฝ์šฐtellme(function dToD(d: Developer): Developer {    return new Developer();});
// Developer => Developer ์—๋‹ค๊ฐ€ Person => Developer ๋ฅผ ํ• ๋‹นํ•˜๋Š” ๊ฒฝ์šฐ// ๋ฐ˜๋ณ‘tellme(function pToD(d: Person): Developer {    return new Developer();});
// Developer => Developer ์—๋‹ค๊ฐ€ StartupDeveloper => Developer ๋ฅผ ํ• ๋‹นํ•˜๋Š” ๊ฒฝ์šฐ// strictFunctionType์œผ๋กœ ์—๋Ÿฌ ํ‘œ์‹œ ๊ฐ€๋Šฅtellme(function sToD(d: StartupDeveloper): Developer {    return new Developer();});

any#

  • ์ž…๋ ฅ์€ ๋งˆ์Œ๋Œ€๋กœ

  • ํ•จ์ˆ˜ ๊ตฌํ˜„์ด ์ž์œ ๋กญ๊ฒŒ โ‡’ ์ž์œ ๊ฐ€ ํ•ญ์ƒ ์ข‹์€ ๊ฑด ์•„๋‹ˆ๋‹ค.

unknown#

  • ์ž…๋ ฅ์€ ๋งˆ์Œ๋Œ€๋กœ

  • ํ•จ์ˆ˜ ๊ตฌํ˜„์€ ๋ฌธ์ œ ์—†๋„๋ก

ํƒ€์ž… ์ถ”๋ก  ์ดํ•ดํ•˜๊ธฐ#

  • let๊ณผ const์˜ ํƒ€์ž… ์ถ”๋ก  (+ as const)

  • as const

let a = 'Mark'; // stringconst b = 'Mark'; // 'Mark' => literal type
let c = 38; // numberconst d = 38; // 38 => literal type
let e = false; // booleanconst f = false; // false => literal type
let g = ['Mark', 'Haeun']; // string[]const h = ['Mark', 'Haeun']; // string[]
const i = ['Mark', 'Haeun', 'Bokdang'] as const; // readonly ['Mark', 'Haeun', 'Bokdang']
  • best common type (๊ฐ€์žฅ ๊ณตํ†ต์ ์ธ ํƒ€์ž…์„ ์ถ”๋ก ํ•ด๋‚ธ๋‹ค)
let j = [0, 1, null]; // (number | null)[]const k = [0, 1, null]; // (number | null)[]
class Animal {}class Rhino extends Animal {}class Elephant extends Animal {}class Snake extends Animal {}
let l = [new Rhino(), new Elephant(), new Snake()]; // (Rhino | Elephant | Snake)[]const m = [new Rhino(), new Elephant(), new Snake()]; // (Rhino | Elephant | Snake)[]const n = [new Animal(), new Rhino(), new Elephant(), new Snake()]; // Animal[]const o: Animal[] = [new Rhino(), new Elephant(), new Snake()]; // Animal[]
  • Contextual Typing - ์œ„์น˜์— ๋”ฐ๋ผ ์ถ”๋ก ์ด ๋‹ค๋ฆ„
// Parameter 'e' implicitly has an 'any' type.const click = (e) => {    e; // any};
document.addEventListener('click', click);document.addEventListener('click', (e) => {    e; // MouseEvent});

Type Guard๋กœ ์•ˆ์ „ํ•จ์„ ํŒŒ์•…ํ•˜๊ธฐ#

typeof Type Guard - ๋ณดํ†ต Primitive ํƒ€์ž…์ผ ๊ฒฝ์šฐ#

  • typeof๋กœ primitive ํƒ€์ž…์„ ๊ฑธ๋Ÿฌ๋‚ผ ์ˆ˜ ์žˆ๋‹ค.
function getNumber(value: number | string): number {    value; // number | string    if (typeof value == 'number') {        return value;    }    value; // string    return -1;}

instanceof Type Guard - Error ๊ฐ์ฒด ๊ตฌ๋ถ„์— ๋งŽ์ด ์“ฐ์ธ๋‹ค.#

class NegativeNumberError extends Error {}
function getNumber(value: number): number | NegativeNumberError {    if (value < 0) return new NegativeNumberError();
    return value;}
function main() {    const num = getNumber(-10);
    if (num instanceof NegativeNumberError) {        return;    }
    num; // number}

in operator Type Guard - object์˜ ํ”„๋กœํผํ‹ฐ ์œ ๋ฌด๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒฝ์šฐ#

interface Admin {    id: string;    role: string;}
interface User {    id: string;    emain: string;}
function redirect(user: Admin | User) {    if ('role' in user) {        routeToAdminPage(user.role);    } else {        routeToHomePage(user.email);    }}

literal Type Guard - object์˜ ํ”„๋กœํผํ‹ฐ๊ฐ€ ๊ฐ™๊ณ , ํƒ€์ž…์ด ๋‹ค๋ฅธ ๊ฒฝ์šฐ#

interface IMachine {    type: string;}
class Car implements IMachine {    type: 'CAR';    wheel: number;}
class Boat implements IMachine {    type: 'BOAT';    motor: number;}
function getWheelOrMotor(machine: Car | Boat): number {    if (machine.type === 'CAR') {        return machine.wheel;    } else {        return machine.motor;    }}

custom Type Guard#

function getWheelOrMoter(machine: any): number {    if (isCar(machine)) {        return machine.wheel;    } else if (isBoat(machine)) {        return machine.motor;    } else {        return -1;    }}
function isCar(arg: any): arg is Car {    return arg.type === 'CAR';}
function isBoat(arg: any): arg is Boat {    return arg.type === 'BOAT';}

Conditional Type#

  • `Item T`
    interface StringContainer {    value: string;    format(): string;    split(): string[];}
    interface NumberContainer {    value: number;    nearestPrime: number;    round(): number;}
    type Item1<T> = {    id: T;    container: any;};
    const item1: Item1<string> = {    id: 'aaaaaa',    container: null, // container type์— any๋ฅผ ์‚ฌ์šฉํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— null์„ ๋„ฃ๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.};
  • `Item T` - T๊ฐ€ string์ด๋ฉด StringContainer, ์•„๋‹ˆ๋ฉด NumberContainer
    type Item2<T> = {    id: T;    container: T extends string ? StringContainer : NumberContainer;};
    const item2: Item2<string> = {    id: 'aaaaaa',    container: null, // Type 'null' is not assignable to type 'StringContainer'.};
  • `Item T` - T๊ฐ€ string์ด๋ฉด StringContainer, number๋ฉด NumberContainer, ์•„๋‹ˆ๋ฉด ์‚ฌ์šฉ ๋ถˆ๊ฐ€
    type Item3<T> = {    id: T extends string | number ? T : never;    container: T extends string        ? StringContainer        : T extends number        ? NumberContainer        : never;};
    const item3: Item3<boolean> = {    id: true, // Type 'boolean' is not assignable to type 'never'.    container: null, // Type 'null' is not assignable to type 'never'.};
  • `ArrayFilter T`
    type ArrayFilter<T> = T extends any[] ? T : never;type StringsOrNumbers = ArrayFilter<string | number | string[] | number[]>;

1:11:12 ๊นŒ์ง€ ์‹œ์ฒญ ...


ยท ์•ฝ 4๋ถ„

SSR and Next.js#

์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง(SSR)์ด๋ž€ ์„œ๋ฒ„์—์„œ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•ด์„œ ๋ Œ๋”๋งํ•˜๋Š” ๊ฒƒ์„ ๋งํ•œ๋‹ค.

2020-11-11-201112-image-0

๋‹ค์Œ์˜ ์žฅ์ ์„ ๊ฐ€์ง„๋‹ค.

  • ๊ฒ€์ƒ‰ ์—”์ง„ ์ตœ์ ํ™”(SEO)

  • ๋น ๋ฅธ ์ฒซ ํŽ˜์ด์ง€ ๋ Œ๋”๋ง

์งง์€ ํžˆ์Šคํ† ๋ฆฌ#

  • (AJAX๊ฐ€ ์—†๋˜ ์‹œ์ ˆ) ์„œ๋ฒ„์—์„œ ์ „์ฒด HTML์„ ๋งŒ๋“œ๋Š” ๋ฐฉ์‹

  • AJAX์˜ ๋“ฑ์žฅ

    • ๋น„๋™๊ธฐ์ ์œผ๋กœ ์„œ๋ฒ„์™€ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ตํ™˜ํ•˜์—ฌ ํŽ˜์ด์ง€ ์ „์ฒด๋ฅผ ๋‹ค์‹œ ๋ Œ๋”๋งํ•˜์ง€ ์•Š๊ณ , ๊ฐฑ์‹ ์ด ํ•„์š”ํ•œ ์ผ๋ถ€๋งŒ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋จ.

    • ๋™์ ์œผ๋กœ HTML์„ ๋งŒ๋“ค๋ฉด์„œ JavaScript์˜ ์—ญํ• ์ด ๋Š˜์–ด๋‚˜๊ฒŒ ๋จ.

  • SPA๋กœ..

  • JavaScript MVC Framework์˜ ๋“ฑ์žฅ

    • Backbone.js, Ember, Knockout ...

    • MVC Framework์˜ ๋ํŒ์™• AngularJS

  • React์˜ ๋“ฑ์žฅ

    • Virtual DOM์„ ์ด์šฉ

    • Flux ์•„ํ‚คํ…์ณ

    • ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง ์ง€์›

      • (๋ฐฐ๊ฒฝ) V8 ์—”์ง„, Node.js ๋“ฑ์œผ๋กœ ์„œ๋ฒ„์—์„œ๋„ JS ๊ธฐ๋ฐ˜์˜ ํด๋ผ์ด์–ธํŠธ์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋™์ž‘ํ•  ์ˆ˜ ์žˆ์Œ

์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง์€ ๋‘ ๋ฒˆ ๋ Œ๋”๋ง ํ•œ๋‹ค. ์„œ๋ฒ„ ์‚ฌ์ด๋“œ์—์„œ ์ƒ์„ฑ๋œ HTML์—๋Š” ์ด๋ฒคํŠธ ์†์„ฑ์ด ์—†๋‹ค. ๋‘ ๋ฒˆ์งธ ๋ Œ๋”๋งํ•  ๋•Œ ์ด๋ฏธ ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง์ด ๋˜์–ด ์žˆ๋‹ค๋ฉด, ์ƒ์„ฑ๋œ DOM์— ์˜ค์ง ์ด๋ฒคํŠธ ์†์„ฑ๋งŒ ์ถ”๊ฐ€ํ•œ๋‹ค.

์™œ React์™€ ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง์ธ๊ฐ€?

๋ฆฌ์•กํŠธ์™€ ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง#

  • renderToString : ๋ฌธ์ž์—ด์„ ๋ฐ˜ํ™˜ํ•˜์—ฌ HTML์— DOM์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

  • hydrate : ๋” ์š”์†Œ์— ํ•„์š”ํ•œ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ ํ•จ์ˆ˜๋ฅผ ์—ฐ๊ฒฐํ•œ๋‹ค.

๐Ÿ“Œ ๋‚˜์ค‘์— ์ง์ ‘ ํ•ด๋ด์•ผ๊ฒ ๋‹ค..!

Next.js#

Next๋Š” ์„œ๋ฒ„์‚ฌ์ด๋“œ ๋ Œ๋”๋ง์— ํŠนํ™”๋œ ํ”„๋ ˆ์ž„์›Œํฌ๋‹ค.

  • ์„œ๋ฒ„์‚ฌ์ด๋“œ ๋ Œ๋”๋ง์˜ ์žฅ์ 

    • SEO

    • ์ดˆ๊ธฐ ๋กœ๋”ฉ ์„ฑ๋Šฅ ๊ฐœ์„ 

  • ์ด๋ฏธ์ง€ ๋ฆฌ์†Œ์Šค ์ตœ์ ํ™”

  • ์ •์  ํŒŒ์ผ ์„œ๋น™

    • ๋ฐฐ๋„ˆ ์ด๋ฏธ์ง€, ์•„์ด์ฝ˜ ๋“ฑ๋“ฑ์—์„œ ์‚ฌ์šฉํ•จ
  • ์ฝ”๋“œ ์Šคํ”Œ๋ฆฌํŒ… ์ž๋™ํ™”

  • ์›นํŒฉ ๊ธฐ๋ฐ˜ ํ™˜๊ฒฝ (create-react-app๊ณผ ๋‹ฌ๋ฆฌ ์›นํŒฉ ์„ค์ • ๋ณ€๊ฒฝ์ด ์‰ฝ๋‹ค.)

์„œ๋ฒ„์—์„œ ์ƒ์„ฑ๋œ ๋ฐ์ดํ„ฐ ์ „๋‹ฌํ•˜๊ธฐ#

  • getInitialProps : ๊ตฌ๋ฒ„์ „์—์„œ ์‚ฌ์šฉํ•œ data fetching ๋ฐฉ์‹

  • getStaticProps : ๋นŒ๋“œ ์‹œ ๊ณ ์ •๋˜๋Š” ๊ฐ’์œผ๋กœ ๋นŒ๋“œ ์ดํ›„์—๋Š” ๋ณ€๊ฒฝ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.

    • static data๋ฅผ ์œ„ํ•ด (๋ณ€๊ฒฝ๋˜์ง€ ์•Š์„ ๋ฐ์ดํ„ฐ. ๋ธ”๋กœ๊ทธ ํฌ์ŠคํŠธ ๋“ฑ๋“ฑ ...)
  • getServerSideProps : ๋นŒ๋“œ์™€ ์ƒ๊ด€์—†์ด ๋งค ์š”์ฒญ๋งˆ๋‹ค ๋ฐ์ดํ„ฐ๋ฅผ ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๊ฐ€์ ธ์˜จ๋‹ค.

    • ๋งค๋ฒˆ ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์œ„ํ•ด (์ƒํ’ˆ ๋ชฉ๋ก. ์‹ค์‹œ๊ฐ„ ๋‰ด์Šค ๋“ฑ๋“ฑ ...)
  • getStaticPaths : ๋นŒ๋“œ ํƒ€์ž„ ๋•Œ ์ •์ ์œผ๋กœ ๋ Œ๋”๋งํ•  ๊ฒฝ๋กœ ์„ค์ •.


ยท ์•ฝ 12๋ถ„

๋ชจ๋ฐ”์ผ ์‚ฌํŒŒ๋ฆฌ ๋””๋ฒ„๊น…#

  • ์•„์ดํฐ์„ ๋งฅ๋ถ์— ์—ฐ๊ฒฐํ•œ๋‹ค.

  • ์•„์ดํฐ์—์„œ ๋””๋ฒ„๊น…ํ•˜๊ณ ์ž ํ•˜๋Š” ์›นํŽ˜์ด์ง€๋ฅผ Safari์— ๋„์šด๋‹ค.

  • ๋งฅ๋ถ์—์„œ Safari๋ฅผ ์‹คํ–‰ํ•œ๋‹ค.

  • ๊ฐœ๋ฐœ์ž์šฉ > iPhone > Safari ์›น ํŽ˜์ด์ง€ ์„ ํƒ

    2020-11-10-201110-image-0

  • ์š”์†Œ, ์ฝ˜์†”, ์†Œ์Šค, ๋„คํŠธ์›Œํฌ ๋“ฑ ์‚ฌํŒŒ๋ฆฌ์˜ ๊ฐœ๋ฐœ์ž ๋„๊ตฌ๋กœ ๋””๋ฒ„๊น…ํ•  ์ˆ˜ ์žˆ๋‹ค.

    2020-11-10-201110-image-1

Debugging Your iPhone Mobile Web App With Safari Dev Tools

๋ชจ๋ฐ”์ผ ์‚ฌํŒŒ๋ฆฌ๋ฅผ ๋งฅ์˜ Chrome์—์„œ ๋””๋ฒ„๊น…ํ•˜๊ธฐ#

๋ชจ๋ฐ”์ผ Safari๋ฅผ ๋งฅ์˜ Chrome์—์„œ ๋””๋ฒ„๊น…ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ์— ์•Œ์•„๋ด์•ผ๊ฒ ๋‹ค.

Jon Sadka - How to debug an issue in Chrome for iOS using remote debugging

๋ฆฌ์•กํŠธ#

  • ๋ฆฌ์•กํŠธ๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” ์—˜๋ฆฌ๋จผํŠธ๋“ค์„ ํŠธ๋ฆฌ ํ˜•ํƒœ๋กœ ๊ด€๋ฆฌํ•˜๊ณ  ํ‘œํ˜„ํ•œ๋‹ค.

  • ์ด๋ฅผ Virtual-DOM์œผ๋กœ ๋ถ€๋ฅด๋Š”๋ฐ, ์ด๋Š” JavaScript ์ผ๋ฐ˜ ๊ฐ์ฒด์ด๋‹ค. (Plain Object)

  • ๊ธฐ์กด VanillaJS๋Š” UI๋ฅผ ๋ช…๋ นํ˜•์œผ๋กœ ์ž‘์„ฑํ•ด์•ผ ํ•˜์ง€๋งŒ, React๋Š” ์„ ์–ธํ˜•์œผ๋กœ UI๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

์ปดํฌ๋„ŒํŠธ#

  • ์ปดํฌ๋„ŒํŠธ๋Š” ๋‚ด๋ถ€์—์„œ ๊ด€๋ฆฌํ•˜๋Š” ์ƒํƒœ ๊ฐ’์ธ state ์™€ ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์—์„œ ๋‚ด๋ ค ์ฃผ๋Š”์†์„ฑ ๊ฐ’ props ๋ฅผ ๊ฐ€์ง„๋‹ค.

  • ์ปดํฌ๋„ŒํŠธ๋Š” state , props ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด render() ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋˜์–ด ํ™”๋ฉด์„ ๊ฐฑ์‹ ํ•œ๋‹ค.

  • UI ๋ฐ์ดํ„ฐ(์ƒํƒœ๊ฐ’๊ณผ ์†์„ฑ๊ฐ’)๋กœ ๋ทฐ๋ฅผ ๋ Œ๋”๋งํ•˜๋Š” ๊ฒƒ์ด ๋ฆฌ์•กํŠธ์˜ ํ•ต์‹ฌ์ด๋‹ค.

  • setState ๋Š” ๋น„๋™๊ธฐ๋กœ ๋™์ž‘ํ•œ๋‹ค.

๋ฆฌ์•กํŠธ์˜ ๋ Œ๋”๋ง ๊ณผ์ •#

  • ์ปดํฌ๋„ŒํŠธ์˜ Props๋‚˜ State์˜ ๋ณ€๊ฒฝ์ด ์žˆ์„ ๋•Œ, ์ปดํฌ๋„ŒํŠธ์˜ ์ด์ „ ์ƒํƒœ ์—˜๋ฆฌ๋จผํŠธ์™€ ์ƒˆ๋กœ ๋งŒ๋“ค์–ด์ง„ ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ๋น„๊ตํ•˜๊ณ  ์‹ค์ œ DOM์˜ ์—…๋ฐ์ดํŠธ ์—ฌ๋ถ€๋ฅผ ๊ฒฐ์ •ํ•œ๋‹ค. ๋น„๊ตํ•˜์—ฌ์ฐพ์€ ๋ณ€๊ฒฝ ์ ์— ๋Œ€ํ•ด์„œ๋งŒ ๊ฐฑ์‹ ํ•œ๋‹ค.

  • ์ปดํฌ๋„ŒํŠธ์˜ setState ๋ฉ”์„œ๋“œ๊ฐ€ ์ˆ˜ํ–‰๋˜๋ฉด, ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋ฅผ Dirty ์ฒดํฌํ•˜๊ณ , ๋‹ค์Œ์ด๋ฒคํŠธ ๋ฃจํ”„์—์„œ ๋ฐฐ์น˜ ์ž‘์—…์œผ๋กœ ๋Œ€์ƒ ์ปดํฌ๋„ŒํŠธ๋“ค์˜ ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ๋ Œ๋”๋งํ•œ๋‹ค. (๋น„๋™๊ธฐ )

  • ์ด๋Ÿฌํ•œ ๋ฆฌ์•กํŠธ์˜ ๋ Œ๋”๋ง ๊ณผ์ •์„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ชผ๊ฐค ์ˆ˜ ์žˆ๋‹ค.

    • ๋ณ€๊ฒฝ ์ ์„ ์ฐพ๋Š” Reconciliation์˜ Diffing ์•Œ๊ณ ๋ฆฌ์ฆ˜ (render or reconciliation phase)

    • ๋ณ€๊ฒฝ ์ ์„ ์‹ค์ œ UI์— ์ ์šฉํ•˜๋Š” ReactDOMComponent.updateComponent (commit phase)

Reconciliation: The diffing algorithm#

Reconciliation์€ ์–ด๋–ค ๋ณ€๊ฒฝ์— ๋Œ€ํ•œ ์ „/ํ›„ ์—˜๋ฆฌ๋จผํŠธ ํŠธ๋ฆฌ๋ฅผ ๋น„๊ต(Diff)ํ•˜์—ฌ, ๊ฐฑ์‹ ์ดํ•„์š”ํ•œ ๋ถ€๋ถ„๋งŒ์„ ์ฐพ์•„ ์—…๋ฐ์ดํŠธํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋ธŒ๋ผ์šฐ์ €์˜ DOM ์กฐ์ž‘์„์ตœ์†Œํ™”์‹œํ‚จ๋‹ค.

๋‹ค์‹œ ์ •๋ฆฌ

  • render() ์—์„œ ์ƒˆ๋กœ์šด ์—˜๋ฆฌ๋จผํŠธ ํŠธ๋ฆฌ๋ฅผ ์ƒ์„ฑ

  • ์ด์ „ ์—˜๋ฆฌ๋จผํŠธ ํŠธ๋ฆฌ์™€ ๋น„๊ตํ•˜์—ฌ ๋ณ€๊ฒฝ ์ ์„ ์ฐพ์•„ ์—…๋ฐ์ดํŠธ

๊ทธ๋Ÿฐ๋ฐ Diff ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ O(n^3)์˜ ์‹œ๊ฐ„๋ณต์žก๋„๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. ๋ฆฌ์•กํŠธ๋Š” ๋‹ค์Œ์˜ ๋ฐฉ๋ฒ•์œผ๋กœ O(n)์— ๊ทผ์‚ฌํ•œ ํœด๋ฆฌ์Šคํ‹ฑ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๊ตฌํ˜„ํ•˜์˜€๋‹ค.

  • ๋‹ค๋ฅธ ํƒ€์ž…์˜ ๋‘ ์—˜๋ฆฌ๋จผํŠธ๋Š” ๋‹ค๋ฅธ ํŠธ๋ฆฌ๋ฅผ ๋งŒ๋“ค ๊ฒƒ์ด๋‹ค.

  • ๊ฐ™์€ ๋ ˆ๋ฒจ์˜ ์—˜๋ฆฌ๋จผํŠธ์— key ํ”„๋กœํผํ‹ฐ๋ฅผ ํ†ตํ•ด ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์•„์•ผ ํ•  ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ํ‘œ์‹œํ•œ๋‹ค.

โ˜ ํœด๋ฆฌ์Šคํ‹ฑ ์•Œ๊ณ ๋ฆฌ์ฆ˜ : ์ง๊ด€์— ์˜์กดํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜. ์ฆ‰ ํœด๋ฆฌ์Šคํ‹ฑ์€ ๋ณดํ†ต ํ•ฉ๋ฆฌ์ ์ธ์‹คํ–‰ ์‹œ๊ฐ„์„ ๊ฐ€์ง€์ง€๋งŒ ๊ทธ๊ฒƒ์ด ํ•ญ์ƒ ๊ทธ๋ ‡๋‹ค๋Š” ์–ด๋– ํ•œ ์ถ”๋ก  ๊ณผ์ •์ด๋‚˜ ์ฆ๋ช…์ด ์—†๋‹ค.

๊ฐ™์€ ์œ„์น˜์—์„œ ์—˜๋ฆฌ๋จผํŠธ์˜ ํƒ€์ž…์ด ๋‹ค๋ฅธ ๊ฒฝ์šฐ

  1. ๊ธฐ์กด ํŠธ๋ฆฌ๋ฅผ ์ œ๊ฑฐ ํ›„ ์ƒˆ๋กœ์šด ํŠธ๋ฆฌ๋ฅผ ๋งŒ๋“ ๋‹ค.

  2. ๊ธฐ์กด ํŠธ๋ฆฌ ์ œ๊ฑฐ ์‹œ ํŠธ๋ฆฌ ๋‚ด๋ถ€(ํ•˜์œ„)์˜ ์—˜๋ฆฌ๋จผํŠธ/์ปดํฌ๋„ŒํŠธ๋“ค์€ ๋ชจ๋‘ ์ œ๊ฑฐํ•œ๋‹ค. (์ปดํฌ๋„ŒํŠธ์˜ ๊ฒฝ์šฐ ์ œ๊ฑฐ๋˜๋ฉด์„œ componentWillUnmount() ๊ฐ€ ์‹คํ–‰๋จ.) ์ด์ „ ํŠธ๋ฆฌ์˜ ๋ชจ๋“  state๊ฐ€ ์‚ฌ๋ผ์ง„๋‹ค.

  3. ์ƒˆ๋กœ์šด ํŠธ๋ฆฌ๋ฅผ ๋งŒ๋“ค ๋•Œ ๋‚ด๋ถ€ ์—˜๋ฆฌ๋จผํŠธ/์ปดํฌ๋„ŒํŠธ๋“ค๋„ ๋ชจ๋‘ ์ƒˆ๋กœ ๋งŒ๋“ ๋‹ค. (์ปดํฌ๋„ŒํŠธ์˜ ๊ฒฝ์šฐ componentDidMount() ๊ฐ€ ์‹คํ–‰๋จ.)

๊ฐ™์€ ์œ„์น˜์—์„œ ์—˜๋ฆฌ๋จผํŠธ์˜ ํƒ€์ž…์ด ๊ฐ™์€ ๊ฒฝ์šฐ

  1. ์—˜๋ฆฌ๋จผํŠธ์˜ attributes ๋ฅผ ๋น„๊ตํ•œ๋‹ค.

  2. ๋ณ€๊ฒฝ๋œ attributes ๋งŒ ์—…๋ฐ์ดํŠธํ•œ๋‹ค.

  3. ์ž์‹ ์—˜๋ฆฌ๋จผํŠธ๋“ค์— diff ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์žฌ๊ท€์ ์œผ๋กœ ์ ์šฉํ•œ๋‹ค.

๊ฐ™์€ ์œ„์น˜์—์„œ ์—˜๋ฆฌ๋จผํŠธ๊ฐ€ ์ปดํฌ๋„ŒํŠธ๋ฅผ ํ‘œํ˜„ํ•˜๊ณ  ๊ทธ ํƒ€์ž…์ด ๊ฐ™์€ ๊ฒฝ์šฐ

  1. ์ปดํฌ๋„ŒํŠธ ์ธ์Šคํ„ด์Šค ์ž์ฒด๋Š” ๋ณ€ํ•˜์ง€ ์•Š๋Š”๋‹ค. (state๊ฐ€ ์œ ์ง€๋œ๋‹ค.)

  2. ์ปดํฌ๋„ŒํŠธ ์ธ์Šคํ„ด์Šค์˜ ์—…๋ฐ์ดํŠธ ์ „ ๋ผ์ดํ”„์‚ฌ์ดํด ๋ฉ”์„œ๋“œ ๋“ค์ด ํ˜ธ์ถœ๋˜๋ฉฐ props๊ฐ€ ์—…๋ฐ์ดํŠธ ๋œ๋‹ค.

  3. render() ๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ์ปดํฌ๋„ŒํŠธ์˜ ์ด์ „ ์—˜๋ฆฌ๋จผํŠธ ํŠธ๋ฆฌ์™€ ๋‹ค์Œ ์—˜๋ฆฌ๋จผํŠธ ํŠธ๋ฆฌ์—๋Œ€ํ•ด diff ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์žฌ๊ท€์ ์œผ๋กœ ์ ์šฉํ•œ๋‹ค.

์ž์‹ ์—˜๋ฆฌ๋จผํŠธ ์žฌ๊ท€

  • ๋ฆฌ์•กํŠธ๋Š” ์ž์‹ ์—˜๋ฆฌ๋จผํŠธ์— ๋Œ€ํ•œ ๋ฐ˜๋ณต์ ์ธ ๋น„๊ต๋ฅผ ํ•  ๋•Œ ๋‘ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ˆœํšŒํ•˜๊ณ  ์ฐจ์ด์ ์ด ์žˆ์œผ๋ฉด ๋ณ€๊ฒฝ์„ ์ƒ์„ฑํ•œ๋‹ค.

  • ์ •๋ ฌ๊ณผ ๊ฐ™์€ ์ƒํ™ฉ์— ์ทจ์•ฝํ•˜๋‹ค.

keys

  • ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์ž์‹ ์—˜๋ฆฌ๋จผํŠธ๋“ค์ด key๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๋ฉด key๋ฅผ ํ†ตํ•ด ๊ธฐ์กด ํŠธ๋ฆฌ์™€ ์ดํ›„ ํŠธ๋ฆฌ์˜ ์ž์‹ ๋“ค์ด ์ผ์น˜ํ•˜๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.

Avoid Reconciliation#

  • ์ปดํฌ๋„ŒํŠธ์˜ ๋ถˆํ•„์š”ํ•œ ๋ Œ๋”๋ง์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•œ๋‹ค.

    • ShouldComponentUpdate ํ•จ์ˆ˜๊ฐ€ return false ํ•˜๋„๋ก ํ•œ๋‹ค.

    • ์ปดํฌ๋„ŒํŠธ๊ฐ€ PureComponent ๋ฅผ ์ƒ์†๋ฐ›๋„๋ก ํ•œ๋‹ค.

    • ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ๋ฅผ React.memo() ๋กœ ๊ฐ์‹ธ์„œ export ํ•œ๋‹ค.

โ˜ ํ•ต์‹ฌ์€ ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๊ฐ€ state , props ๊ฐ€ ๋ณ€๊ฒฝ ๋˜์—ˆ์„ ๋•Œ๋งŒ ๋ Œ๋”๋งํ•˜๋„๋กํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์ด๊ฒƒ์ด ๊ฐ€๋Šฅํ•œ ๊ฒƒ์€ ๋ฆฌ์•กํŠธ๊ฐ€ ์ปดํฌ๋„ŒํŠธ ๋ Œ๋”๋ง ๊ฒฐ๊ณผ๋ฅผ ๋ฉ”๋ชจ์ด์ง•ํ•˜๋Š”๊ฒƒ์ด๋‹ค.

๊ฐ€์žฅ ์ข‹์€ ์ผ€์ด์Šค๋Š” ๊ฐ™์€ ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์— ์˜ํ•ด ๊ฐ™์€ props ๋กœ ์ž์ฃผ ๋ Œ๋”๋ง ๋ ๋•Œ์ด๋‹ค. ์ด์ „ ๋ฉ”๋ชจ์ด์ง• ๊ฒฐ๊ณผ์™€ props ๊ฐ€ ๊ฐ™๋‹ค๋ฉด ๋‚ด๋ถ€๋ฅผ ๋น„๊ตํ•˜์ง€ ์•Š๊ณ  ๋ฉ”๋ชจ์ด์ง•๋œ๊ฒฐ๊ณผ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

ํ•˜์ง€๋งŒ ๋ฐ˜๋Œ€๋กœ props ๊ฐ€ ๋‹ค๋ฅธ ๊ฒฝ์šฐ๊ฐ€ ๋Œ€๋ถ€๋ถ„์ด๋ผ๋ฉด, ์ด์ „ props ์™€ ๋‹ค์Œ props ๋น„๊ต๋ฅผ ํ•˜๊ณ , ์ปดํฌ๋„ŒํŠธ ๋ Œ๋”๋ง์„ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ถˆํ•„์š”ํ•œ props ๋น„๊ต๋ฅผ ํ•˜๊ฒŒ ๋งŒ๋“ ๋‹ค. ๋˜ํ•œ ๋ฉ”๋ชจ์ด์ง•์€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋‚จ์šฉํ•ด์„  ์•ˆ๋œ๋‹ค.

์ฒ˜์Œ๋ถ€ํ„ฐ ์„ฑ๋Šฅ์— ์ตœ์ ํ™”๋œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์„ค๊ณ„ํ•˜๋Š” ๊ฒƒ ์ž์ฒด๊ฐ€ ๋น„ํšจ์œจ์ ์ด๋‹ค. ํ•˜์ง€๋งŒ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ ์ ˆํžˆ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ์€ ์ค‘์š”ํ•˜๋‹ค. ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ ์ ˆํžˆ ๋ถ„๋ฆฌํ•˜์—ฌ ์ด์Šˆ๋ฅผ๋น ๋ฅด๊ฒŒ ํŒŒ์•…ํ•˜๊ณ  ๋Œ€์‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด ์ „๋žต์ด๋‹ค.

UI ๋Ÿฐํƒ€์ž„์œผ๋กœ์„œ์˜ React

์žฌ์กฐ์ • (Reconciliation) - React

์„ฑ๋Šฅ ์ตœ์ ํ™” - React

React ๋ Œ๋”๋ง๊ณผ ์„ฑ๋Šฅ ์•Œ์•„๋ณด๊ธฐ : TOAST Meetup

React.memo() ํ˜„๋ช…ํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๊ธฐ

๋ฆฌ์•กํŠธ ํ›…(Hook)#

ํ›…(Hook)์ด๋ž€?#

  • ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ์—์„œ React state๋ฅผ ์—ฐ๋™(hook into)ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ํ•จ์ˆ˜.

  • ์ฆ‰ ์ƒํƒœ๋ฅผ ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ์— ๋™๊ธฐํ™” ํ•ด์ค€๋‹ค. (์ด ๋ง์€ ์ƒํƒœ๊ฐ€ ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ ์™ธ๋ถ€์—์„œ ๊ด€๋ฆฌ๋˜๊ณ  ์žˆ๋‹ค๋Š” ์˜๋ฏธ๋ฅผ ๋‚ดํฌํ•จ.)

๋™๊ธฐ#

  • ์ปดํฌ๋„ŒํŠธ ์‚ฌ์ด์—์„œ ์ƒํƒœ์™€ ๊ด€๋ จ๋œ ๋กœ์ง์„ ์žฌ์‚ฌ์šฉํ•˜๊ธฐ ์–ด๋ ต๋‹ค.

    • render props, HOC์™€ ๊ฐ™์€ ํŒจํ„ด์€ ๋ž˜ํผ๋ฅผ ๊นŠ๊ฒŒ ๋งŒ๋“ ๋‹ค.
  • ๋ผ์ดํ”„์‚ฌ์ดํด ๋ฉ”์„œ๋“œ ๋“ค์ด ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ณต์žกํ•˜๊ณ  ์ดํ•ดํ•˜๊ธฐ ์–ด๋ ต๊ฒŒ ๋งŒ๋“ ๋‹ค.

  • ํด๋ž˜์Šค๋ณด๋‹ค ํ•จ์ˆ˜๊ฐ€ ์ง๊ด€์ ์ด๋‹ค. this ๋ฐ”์ธ๋”ฉ


ํ›…์˜ ๊ทœ์น™#

โ˜ ๋ฆฌ์•กํŠธ๋Š” ํ›…์ด ํ˜ธ์ถœ๋˜๋Š” ์ˆœ์„œ์— ์˜์กดํ•œ๋‹ค. (์ƒํƒœ๋ฅผ ์‹๋ณ„ํ•˜๊ธฐ ์œ„ํ•ด ํ˜ธ์ถœ ์ˆœ์„œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๋ณด์ธ๋‹ค.)

  • ์ตœ์ƒ์œ„(at the Top Level)์—์„œ๋งŒ ํ›…์„ ํ˜ธ์ถœํ•ด์•ผ ํ•œ๋‹ค. (๋ฐ˜๋ณต๋ฌธ, ์กฐ๊ฑด๋ฌธ, ์ค‘์ฒฉ๋œ ํ•จ์ˆ˜ ๋‚ด์—์„œ Hook์„ ํ˜ธ์ถœํ•˜์ง€ ๋ง๋ผ)

    // ๐Ÿ”ด ์กฐ๊ฑด๋ฌธ์— Hook์„ ์‚ฌ์šฉํ•จ์œผ๋กœ์จ ์ฒซ ๋ฒˆ์งธ ๊ทœ์น™์„ ๊นผ์Šต๋‹ˆ๋‹คif (name !== '') {    useEffect(function persistForm() {        localStorage.setItem('formData', name);    });}
  • ์˜ค์ง React ํ•จ์ˆ˜ ๋‚ด์—์„œ Hook์„ ํ˜ธ์ถœํ•ด์•ผ ํ•œ๋‹ค. (์ผ๋ฐ˜ JS ํ•จ์ˆ˜์—์„œ ํ˜ธ์ถœํ•˜์ง€ ๋ง๋ผ)

โ˜ ๋ฆฌ์•กํŠธ์˜ ํ›…์€ ๋ Œ๋”๋ง ๋˜๋Š” ๊ฐœ๋ณ„ ์ปดํฌ๋„ŒํŠธ์˜ ํ•œ ์ˆ˜์ค€ ์œ„์˜ ์™ธ๋ถ€ ๊ณต๊ฐ„(์‹คํ–‰ ์ปจํ…์ŠคํŠธ)์— ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ(๋ฐฐ์—ด)ํ˜•ํƒœ๋กœ ์ €์žฅ๋˜๋Š” ๋ฐ์ดํ„ฐ( state , setter )์ด๋‹ค. ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ์™€ ๊ณต์œ ๋˜์ง€ ์•Š๊ณ , ๋ฆฌ๋ Œ๋”๋ง๋˜๋Š” ์ปดํฌ๋„ŒํŠธ์—์„œ ์—‘์„ธ์Šคํ•  ์ˆ˜ ์žˆ๋‹ค.

useState#

useState์—์„œ ๋ฐ˜ํ™˜๋œ setter ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด, React์—๊ฒŒ ๋‚ด๋ถ€์ ์œผ๋กœ ์•ก์…˜์„ dispatch ํ•˜๊ฒŒ ๋˜๊ณ , ์ด ์ปดํฌ๋„ŒํŠธ๊ฐ€ new state๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ณ , ์—…๋ฐ์ดํŠธ ํ•ด์•ผ ๋œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๋ฆฐ๋‹ค.

React hooks: not magic, just arrays

useEffect#

  • ๋ Œ๋”๋ง ์ดํ›„(DOM ์—…๋ฐ์ดํŠธ ํ›„)์— ์ˆ˜ํ–‰ํ•  "side effect"๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

Fiber#

  • virtualDOM์˜ ์ฆ๋ถ„ ๋ Œ๋”๋ง์„ ํ™œ์„ฑํ™”ํ•˜๊ธฐ ์œ„ํ•จ.

  • requestIdleCallback ์„ ํ™œ์šฉ.

  • ์ปดํฌ๋„ŒํŠธ ํŠธ๋ฆฌ์— ๋Œ€ํ•œ ์ถ”๊ฐ€ ์ •๋ณด๋ฅผ ํฌํ•จํ•˜๊ธฐ ์œ„ํ•œ ๋‚ด๋ถ€ ๊ฐ์ฒด

  • ๋‚ด์žฅ ์Šคํƒ์— ์˜์กดํ•œ ๋™๊ธฐ์‹ ์žฌ๊ท€ ๋ชจ๋ธ์—์„œ ๋งํฌ๋“œ ๋ฆฌ์ŠคํŠธ์™€ ํฌ์ธํ„ฐ๊ฐ€ ์žˆ๋Š” ๋น„๋™๊ธฐ์‹๋ชจ๋ธ๋กœ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์žฌ๊ตฌํ˜„ํ•จ.

    • ํ˜ธ์ถœ ์Šคํƒ์„ ๋งˆ์Œ๋Œ€๋กœ ์ค‘๋‹จํ•˜๊ณ  ์Šคํƒ ํ”„๋ ˆ์ž„์„ ์ˆ˜๋™์œผ๋กœ ์กฐ์ž‘ํ•˜๊ธฐ ์œ„ํ•ด

React Fiber Architecture - A Deep Dive

ยท ์•ฝ 8๋ถ„

์›นํŒฉ#

  • ์›นํŒฉ์€ static module bundler์ด๋‹ค.

  • ์›นํŒฉ์€ ์—”ํŠธ๋ฆฌ ํฌ์ธํŠธ๋ถ€ํ„ฐ ํ”„๋กœ์„ธ์Šคํ•˜์—ฌ, ์˜์กดํ•˜๊ณ  ์žˆ๋Š” ๋ชจ๋“ˆ์— ๋Œ€ํ•ด ๋‚ด๋ถ€์ ์œผ๋กœ dependency graph๋ฅผ ๊ตฌ์„ฑํ•˜๊ณ , ์ตœ์ข…์ ์œผ๋กœ ํ•˜๋‚˜์˜ ๋ฒˆ๋“ค ํŒŒ์ผ์„ ๊ตฌ์„ฑํ•œ๋‹ค .

    • Entry : dependency graph๋ฅผ ๊ตฌ์„ฑํ•˜๊ธฐ ์‹œ์ž‘ํ•  ์ง„์ž…์ 

    • Output : ๋ฒˆ๋“ค๋œ ๊ฒฐ๊ณผ ํŒŒ์ผ

    • Loader : ๊ธฐ๋ณธ์ ์œผ๋กœ js, json ํŒŒ์ผ๋งŒ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์ง€๋งŒ, loader๋Š” ์›นํŒฉ์ด ๋‹ค๋ฅธ์œ ํ˜•์˜ ํŒŒ์ผ๋„ ๋ชจ๋“ˆ๋กœ์„œ ๊ฐ€์ ธ์˜ค๊ณ  dependency graph๋ฅผ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ค€๋‹ค. ex) jpg ์ด๋ฏธ์ง€, ํฐํŠธ, ...

    • Plugin : ๋ฒˆ๋“ค๋ง ์ตœ์ ํ™”, ์ž์› ๊ด€๋ฆฌ, ํ™˜๊ฒฝ ๋ณ€์ˆ˜์˜ ์ฃผ์ž… ๋“ฑ ๋‹ค์–‘ํ•œ ๋ชฉ์ ์˜ ํ™˜๊ฒฝ ์„ค์ •์„ ์œ„ํ•ด ์‚ฌ์šฉ.

    • Mode : production | development ๋“ฑ ํ™˜๊ฒฝ์— ๋”ฐ๋ผ ์›นํŒฉ์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

HTTP#

HTTP ๋ฒ„์ „๋ณ„ ์ฐจ์ด์ #

HTTP์˜ ์ง„ํ™”

HTTP/0.9#

  • ์ดˆ๊ธฐ ๋ฒ„์ „

  • GET ์ด ์œ ์ผํ•œ ๋ฉ”์„œ๋“œ

  • HTTP ํ—ค๋”๊ฐ€ ์—†์—ˆ๊ณ  HTML ํŒŒ์ผ๋งŒ ์ „์†ก๋  ์ˆ˜ ์žˆ์—ˆ์Œ.

  • ์ƒํƒœ๋‚˜ ์˜ค๋ฅ˜ ์ฝ”๋“œ๋„ ์—†์—ˆ๋‹ค.

HTTP/1.0#

  • ๋ฒ„์ „ ์ •๋ณด๊ฐ€ ์š”์ฒญ์œผ๋กœ ์ „์†ก๋˜๊ธฐ ์‹œ์ž‘ ex) GET /mypage.html HTTP/1.0

  • ์ƒํƒœ ์ฝ”๋“œ๊ฐ€ ์‘๋‹ต์˜ ์‹œ์ž‘ ๋ถ€๋ถ„์— ๋ถ™์–ด ์ „์†ก๋จ.

  • HTTP ํ—ค๋” ๊ฐœ๋…์ด ๋„์ž…๋จ.

    • HTML ํŒŒ์ผ ์™ธ์— ๋‹ค๋ฅธ ๋ฌธ์„œ๋ฅผ ์ „์†กํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋จ.

HTTP/1.1#

  • HTTP์˜ ์ฒซ ๋ฒˆ์งธ ํ‘œ์ค€ ๋ฒ„์ „

  • ์ปค๋„ฅ์…˜์„ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋จ.

    • ์›๋ณธ ๋ฌธ์„œ ๋‚ด์— ์ž„๋ฒ ๋“œ๋œ ๋ฆฌ์†Œ์Šค๋ฅผ ์œ„ํ•ด์„œ, ๊ธฐ์กด์— ์—ฐ๊ฒฐ๋œ ์ปค๋„ฅ์…˜์„ ๋‹ค์‹œ ์‚ฌ์šฉํ• ์ˆ˜ ์žˆ์Œ.
  • ํŒŒ์ดํ”„๋ผ์ด๋‹์œผ๋กœ ์ฒซ ๋ฒˆ์งธ ์š”์ฒญ์— ๋Œ€ํ•œ ์‘๋‹ต์ด ์™„์ „ํžˆ ์ „์†ก๋˜๊ธฐ ์ „์— ๋‘ ๋ฒˆ์งธ ์š”์ฒญ์ „์†ก์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ–ˆ๋‹ค.

2020-11-08-201108-image-0

HTTP/2#

  • ์ด์ง„ ํ”„๋กœํ† ์ฝœ (1.1์€ ํ…์ŠคํŠธ ํ”„๋กœํ† ์ฝœ)

  • Multiplexing

2020-11-08-201108-image-1

2020-11-08-201108-image-2

โ˜ multiplexing vs pipelining

  • pipelining์€ ์ˆœ์„œ๊ฐ€ ์ค‘์š”ํ•˜๋‹ค โ†’ Head Of Line blocking ๋ฌธ์ œ

  • multiplexing์€ ์ˆœ์„œ๊ฐ€ ์ค‘์š”ํ•˜์ง€ ์•Š๋‹ค.

2020-11-08-201108-image-3

HTTP 1.1 vs HTTP.2 vs HTTP/2 with Push - Manning

HTTP ์ƒํƒœ ์ฝ”๋“œ#

1xx : ์ •๋ณด ์‘๋‹ต#

2xx : ์„ฑ๊ณต ์‘๋‹ต#

  • 200 : OK. ์š”์ฒญ ์„ฑ๊ณต

  • 201 : Created. ์ƒ์„ฑ ์š”์ฒญ ์„ฑ๊ณต

  • 202 : Accepted. ์š”์ฒญ ์ˆ˜๋ฝ

  • 204 : ์„ฑ๊ณตํ–ˆ์œผ๋‚˜ ๋ฐ˜ํ™˜ํ•  ๊ฒƒ์ด ์—†์Œ

3xx : ๋ฆฌ๋‹ค์ด๋ ‰์…˜ ๋ฉ”์‹œ์ง€#

  • 300 : Multiple choices. ์—ฌ๋Ÿฌ ๋ฆฌ์†Œ์Šค์— ๋Œ€ํ•œ ์š”์ฒญ ๊ฒฐ๊ณผ ๋ชฉ๋ก

  • 301 , 302 , 303 : Redirect. ๋ฆฌ์†Œ์Šค ์œ„์น˜๊ฐ€ ๋ณ€๊ฒฝ๋œ ์ƒํƒœ

  • 304 : Not modified. ๋ฆฌ์†Œ์Šค๊ฐ€ ์ˆ˜์ •๋˜์ง€ ์•Š์•˜์Œ

4xx : ํด๋ผ์ด์–ธํŠธ ์—๋Ÿฌ ์‘๋‹ต#

  • 400 : Bad Request. ์š”์ฒญ ์˜ค๋ฅ˜

  • 401 : Unauthorized. ๊ถŒํ•œ ์—†์Œ

  • 403 : Forbidden. ์š”์ฒญ ๊ฑฐ๋ถ€

  • 404 : Not Fount. ๋ฆฌ์†Œ์Šค๊ฐ€ ์—†๋Š” ์ƒํƒœ

5xx : ์„œ๋ฒ„ ์—๋Ÿฌ ์‘๋‹ต#

  • 500 : ์„œ๋ฒ„๊ฐ€ ์š”์ฒญ์„ ์ฒ˜๋ฆฌ ๋ชปํ•จ

  • 501 : Not Implemented. ์„œ๋ฒ„๊ฐ€ ์ง€์›ํ•˜์ง€ ์•Š๋Š” ์š”์ฒญ

  • 503 : Service Unavailable. ๊ณผ๋ถ€ํ•˜ ๋“ฑ์œผ๋กœ ๋‹น์žฅ ์„œ๋น„์Šค๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•œ ์ƒํƒœ

๋ธŒ๋ผ์šฐ์ € ๋ Œ๋”๋ง ๊ณผ์ •#

2020-11-08-201108-image-4

2020-11-08-201108-image-5

  • DOM ๋ฐ CSSOM ํŠธ๋ฆฌ๋Š” ๊ฒฐํ•ฉ๋˜์–ด ๋ Œ๋”๋ง ํŠธ๋ฆฌ๋ฅผ ํ˜•์„ฑํ•ฉ๋‹ˆ๋‹ค.

  • ๋ Œ๋”๋ง ํŠธ๋ฆฌ์—๋Š” ํŽ˜์ด์ง€๋ฅผ ๋ Œ๋”๋งํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ๋…ธ๋“œ๋งŒ( ๋ฉ”ํƒ€ ํƒœ๊ทธ, ์Šคํฌ๋ฆฝํŠธํƒœ๊ทธ, display: none ๋“ฑ์ด ์ œ์™ธ๋จ. )ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.

    โ˜ visibility: hidden , display: none ์€ ๋‹ค๋ฅด๋‹ค.

  • ๋ ˆ์ด์•„์›ƒ์€ ๊ฐ ๊ฐ์ฒด์˜ ์ •ํ™•ํ•œ ์œ„์น˜ ๋ฐ ํฌ๊ธฐ๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค. (๊ฒฝ์šฐ์— ๋”ฐ๋ผ "๋ฆฌํ”Œ๋กœ์šฐ" ๋ผ๊ณ ๋„ ํ•œ๋‹ค.)

  • ๋งˆ์ง€๋ง‰ ๋‹จ๊ณ„๋Š” ์ตœ์ข… ๋ Œ๋”๋ง ํŠธ๋ฆฌ์—์„œ ์ˆ˜ํ–‰๋˜๋Š” ํŽ˜์ธํŠธ์ด๋ฉฐ, ํ”ฝ์…€์„ ํ™”๋ฉด์— ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. (๊ฒฝ์šฐ์— ๋”ฐ๋ผ "๋ฆฌํŽ˜์ธํŠธ"๋ผ๊ณ ๋„ ํ•œ๋‹ค.)


๋ธŒ๋ผ์šฐ์ € ๋ Œ๋”๋ง ์ตœ์ ํ™”#

์˜ค๋Š˜๋‚  ๋Œ€๋ถ€๋ถ„์˜ ๊ธฐ๊ธฐ๋Š” ์ดˆ๋‹น 60ํšŒ(60fps)์˜ ๋นˆ๋„๋กœ ํ™”๋ฉด์„ ์ƒˆ๋กœ ๊ณ ์นœ๋‹ค. ๋”ฐ๋ผ์„œ๊ฐ ํ”„๋ ˆ์ž„์—๋Š” 16ms ๊ฐ€๋Ÿ‰์˜ ์‹œ๊ฐ„๋งŒ ํ• ๋‹น๋œ๋‹ค. (1์ดˆ / 60 = 16.66ms) ์‹ค์ œ๋กœ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์‹คํ–‰ ์ค€๋น„๋ฅผ ํ•˜๋Š” ์‹œ๊ฐ„์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— 10ms ๋‚ด์— ๋ชจ๋“  ์ž‘์—…์„ ์™„๋ฃŒํ•ด์•ผ ํ•œ๋‹ค.

ํ”ฝ์…€ ํŒŒ์ดํ”„๋ผ์ธ#

2020-11-08-201108-image-6

2020-11-08-201108-image-7

  • ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ : ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ์‹œ๊ฐ์  ๋ณ€ํ™”๋ฅผ ์ผ์œผํ‚ค๋Š” ์ž‘์—…. CSS Animation, Transitions, Web Animation API ์—ญ์‹œ ํฌํ•จ.

  • ์Šคํƒ€์ผ ๊ณ„์‚ฐ : ์–ด๋–ค ์Šคํƒ€์ผ ๊ทœ์น™(CSS)์„ ์–ด๋–ค ์š”์†Œ์— ์ ์šฉํ• ์ง€ ๊ณ„์‚ฐํ•˜๋Š” ํ”„๋กœ์„ธ์Šค

  • ๋ ˆ์ด์•„์›ƒ : ํ™”๋ฉด์—์„œ ์–ผ๋งˆ์˜ ๊ณต๊ฐ„์„ ์ฐจ์ง€ํ•˜๊ณ  ์–ด๋””์— ๋ฐฐ์น˜๋˜๋Š”์ง€ ๊ณ„์‚ฐํ•˜๊ธฐ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ๋‹ค.

  • ํŽ˜์ธํŠธ : ํ”ฝ์…€์„ ์ฑ„์šฐ๋Š” ํ”„๋กœ์„ธ์Šค. ํ…์ŠคํŠธ, ์ƒ‰, ์ด๋ฏธ์ง€, ๊ฒฝ๊ณ„ ๋ฐ ๊ทธ๋ฆผ์ž ๋“ฑ ๋ชจ๋“  ์‹œ๊ฐ์  ๋ถ€๋ถ„์„ ๊ทธ๋ฆฌ๋Š” ์ž‘์—…. ๋ ˆ์ด์–ด๋ผ๊ณ  ํ•˜๋Š” ๋‹ค์ˆ˜์˜ ํ‘œ๋ฉด์—์„œ ์ˆ˜ํ–‰

  • ํ•ฉ์„ฑ : ํŽ˜์ด์ง€์˜ ์—ฌ๋Ÿฌ ๋ถ€๋ถ„์ด ์—ฌ๋Ÿฌ ๋ ˆ์ด์–ด๋กœ ๊ทธ๋ ค์กŒ๊ธฐ ๋•Œ๋ฌธ์— ํŽ˜์ด์ง€๊ฐ€ ์ •ํ™•ํžˆ๋ Œ๋”๋ง ๋˜๋ ค๋ฉด ์ •ํ™•ํ•œ ์ˆœ์„œ๋กœ ํ™”๋ฉด์— ๊ทธ๋ ค์•ผ ํ•œ๋‹ค.

โ˜ ์ฝ”๋“œ๊ฐ€ ํŒŒ์ดํ”„๋ผ์ธ์˜ ์–ด๋–ค ๋ถ€๋ถ„์„ ํŠธ๋ฆฌ๊ฑฐ ํ•˜๋Š”์ง€ ์ •ํ™•ํžˆ ์ดํ•ดํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”

1. JS / CSS > ์Šคํƒ€์ผ > ๋ ˆ์ด์•„์›ƒ > ํŽ˜์ธํŠธ > ํ•ฉ์„ฑ#

2020-11-08-201108-image-8

๋ ˆ์ด์•„์›ƒ ๋„ˆ๋น„, ๋†’์ด, ์™ผ์ชฝ ๋˜๋Š” ์ƒ๋‹จ ์œ„์น˜ ๋“ฑ ์š”์†Œ์˜ ๊ธฐํ•˜ํ•™์  ํ˜•ํƒœ์— ์˜ํ–ฅ์„ ์ฃผ๋Š” "layout" ์†์„ฑ์„ ๋ณ€๊ฒฝํ•˜๋ฉด ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋‹ค๋ฅธ ๋ชจ๋“  ์š”์†Œ๋ฅผ ํ™•์ธํ•˜๊ณ  ํŽ˜์ด์ง€์— ๋Œ€ํ•ด "๋ฆฌํ”Œ๋กœ์šฐ"๋ฅผ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•œ๋‹ค. ์˜ํ–ฅ์„ ๋ฐ›์€ ์˜์—ญ์ด ์žˆ์œผ๋ฉด ๋‹ค์‹œ ํŽ˜์ธํŠธํ•˜๊ณ , ๋‹ค์‹œํ•ฉ์„ฑํ•ด์•ผ ํ•œ๋‹ค.

2. JS / CSS > ์Šคํƒ€์ผ > ํŽ˜์ธํŠธ > ํ•ฉ์„ฑ#

2020-11-08-201108-image-9

ํŽ˜์ด์ง€์˜ ๋ ˆ์ด์•„์›ƒ์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๋Š” ๋ฐฐ๊ฒฝ ์ด๋ฏธ์ง€, ํ…์ŠคํŠธ ์ƒ‰์ƒ, ๊ทธ๋ฆผ์ž ๋“ฑ์˜ "paint only" ์†์„ฑ์„ ๋ณ€๊ฒฝํ•˜๋ฉด ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋ ˆ์ด์•„์›ƒ์„ ๊ฑด๋„ˆ๋›ฐ๊ณ  ํŽ˜์ธํŠธ ์ž‘์—…, ํ•ฉ์„ฑ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

3. JS / CSS > ์Šคํƒ€์ผ > ํ•ฉ์„ฑ#

2020-11-08-201108-image-10

๋ ˆ์ด์•„์›ƒ๊ณผ ํŽ˜์ธํŠธ๊ฐ€ ํ•„์š” ์—†๋Š” ์†์„ฑ์„ ๋ณ€๊ฒฝํ•˜๋ฉด ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ํ•ฉ์„ฑ ๋‹จ๊ณ„๋กœ ๊ฑด๋„ˆ ๋›ด๋‹ค. ๊ฐ€์žฅ ์ด์ƒ์ ์ด๊ณ  ๋น„์šฉ์ด ๊ฐ€์žฅ ์ ๊ฒŒ ๋“œ๋Š” ๋ฒ„์ „์ด๋‹ค. ( ํ˜„์žฌ ๋ถ€ํ•ฉ๋˜๋Š” ์†์„ฑ์€ transform , opacity 2๊ฐ€์ง€ ๋ฟ์ด๋‹ค. )

โ˜ CSS ์†์„ฑ์ด ์–ด๋–ค ๋ฒ„์ „์„ ํŠธ๋ฆฌ๊ฑฐํ•  ์ง€ ์•Œ๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ CSS ํŠธ๋ฆฌ๊ฑฐ๋ฅผ ์ฐธ์กฐ. ๋˜๋Š” ์ด ๋งํฌ ์ฐธ์กฐ

์ฐธ๊ณ ์ž๋ฃŒ#

Rendering Performance | Web Fundamentals | Google Developers


์ด๋ฏธ์ง€ ๋ ˆ์ด์ง€๋กœ๋“œ#

Lazy-loading images

The Complete Guide to Lazy Loading Images | CSS-Tricks


ยท ์•ฝ 11๋ถ„

์„ฑ๋Šฅ ์ธก์ •#

๋ธŒ๋ผ์šฐ์ € ๊ธฐ์ค€#

DOMContentLoadedย ์ด๋ฒคํŠธ#

  • HTML๊ณผ CSS ํŒŒ์‹ฑ์ด ๋๋‚˜๋Š” ์‹œ์ 

  • ๋ Œ๋” ํŠธ๋ฆฌ๋ฅผ ๊ตฌ์„ฑํ•  ์ค€๋น„๊ฐ€ ๋œ(DOM ๋ฐ CSSOM ๊ตฌ์„ฑ์ด ๋๋‚œ) ์ƒํ™ฉ

loadย ์ด๋ฒคํŠธ#

  • HTML ์ƒ์— ํ•„์š”ํ•œ ๋ชจ๋“  ๋ฆฌ์†Œ์Šค๊ฐ€ ๋กœ๋“œ๋œ ์‹œ์ 

๊ทธ๋ฆฌ๊ณ  ์ด ๋‘ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ์‹œ์ ์€ ๋‚ด๋น„๊ฒŒ์ด์…˜ ํƒ€์ด๋ฐ API๋ฅผ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ํฌ๋กฌ ๊ฐœ๋ฐœ์ž ๋„๊ตฌ๋ฅผ ํ†ตํ•ด ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

์‚ฌ์šฉ์ž ๊ธฐ์ค€#

2020-11-08-201109-image-0

FP(First Paint)#

  • ํฐ ํ™”๋ฉด์—์„œ ํ™”๋ฉด์— ๋ฌด์–ธ๊ฐ€๊ฐ€ ์ฒ˜์Œ์œผ๋กœ ๊ทธ๋ ค์ง€๊ธฐ ์‹œ์ž‘ํ•˜๋Š” ์ˆœ๊ฐ„์ด๋‹ค.

FCP(First Contentful Paint)#

  • ํ…์ŠคํŠธ๋‚˜ ์ด๋ฏธ์ง€๊ฐ€ ์ถœ๋ ฅ๋˜๊ธฐ ์‹œ์ž‘ํ•˜๋Š” ์ˆœ๊ฐ„์ด๋‹ค.

FMP(First Meaningful Paint)#

  • ์‚ฌ์šฉ์ž์—๊ฒŒ ์˜๋ฏธ ์žˆ๋Š” ์ฝ˜ํ…์ธ ๊ฐ€ ๊ทธ๋ ค์ง€๊ธฐ ์‹œ์ž‘ํ•˜๋Š” ์ฒซ ์ˆœ๊ฐ„์ด๋‹ค. ์ฝ˜ํ…์ธ ๋ฅผ ๋…ธ์ถœํ•˜๋Š”๋ฐ ํ•„์š”ํ•œ CSS, ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋กœ๋“œ๊ฐ€ ์‹œ์ž‘๋˜๊ณ  ์Šคํƒ€์ผ์ด ์ ์šฉ๋˜์–ด ์ฃผ์š” ์ฝ˜ํ…์ธ ๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ๋‹ค.

TTI(Time to Interactive)#

  • ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ์ดˆ๊ธฐ ์‹คํ–‰์ด ์™„๋ฃŒ๋˜์–ด์„œ ์‚ฌ์šฉ์ž๊ฐ€ ์ง์ ‘ ํ–‰๋™์„ ์ทจํ•  ์ˆ˜ ์žˆ๋Š” ์ˆœ๊ฐ„์ด๋‹ค.

์„ฑ๋Šฅ ์ตœ์ ํ™”

๋กœ๋”ฉ ์ตœ์ ํ™”#

๋ธ”๋ก ๋ฆฌ์†Œ์Šค(๋˜๋Š” ๋ Œ๋”๋ง ์ฐจ๋‹จ ๋ฆฌ์†Œ์Šค) ์ตœ์ ํ™”#

๋ธŒ๋ผ์šฐ์ € ๋กœ๋”ฉ ๊ณผ์ •์—์„œ ํŒŒ์‹ฑ ์ค‘ ๋ธ”๋ก ๋ฆฌ์†Œ์Šค๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ธ”๋ก ๋ฆฌ์†Œ์Šค์—๋Š” CSS ์™€ JavaScript๊ฐ€ ํฌํ•จ๋œ๋‹ค.

CSS ์ตœ์ ํ™”#

  • DOM ํŠธ๋ฆฌ๋Š” ํŒŒ์‹ฑํ•˜๋ฉด์„œ ์ˆœ์ฐจ์ ์œผ๋กœ ๊ตฌ์„ฑ๋œ๋‹ค.

  • CSSOM ํŠธ๋ฆฌ๋Š” CSS๋ฅผ ๋ชจ๋‘ ํ•ด์„ํ•ด์•ผ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

  • ์ฆ‰ CSSOM ํŠธ๋ฆฌ๊ฐ€ ๊ตฌ์„ฑ๋˜์ง€ ์•Š์œผ๋ฉด ๋ Œ๋” ํŠธ๋ฆฌ๋ฅผ ๋งŒ๋“ค์ง€ ๋ชปํ•˜๊ณ , ๋ Œ๋”๋ง์ด ์ฐจ๋‹จ๋˜์–ด์žˆ๋‹ค.

  • ๋”ฐ๋ผ์„œ CSS๋Š” ํ•ญ์ƒ HTML ๋ฌธ์„œ ์ตœ์ƒ๋‹จ์— ๋ฐฐ์น˜ํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

  • ๋˜ํ•œ ํŠน์ • ์กฐ๊ฑด(์„ธ๋กœ ๋ชจ๋“œ, ์ธ์‡„ ๋ชจ๋“œ ๋“ฑ)์—์„œ๋งŒ ํ•„์š”ํ•œ CSS๋Š”, ํ•ด๋‹น ๊ฒฝ์šฐ์—๋งŒ ๋กœ๋“œํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ฏธ๋””์–ด ์ฟผ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ตœ์ ํ™”ํ•œ๋‹ค.

    ๋ฏธ๋””์–ด ์ฟผ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ (์ตœ์ ํ™” ์ „)

    <link href="style.css" rel="stylesheet" /><link href="print.css" rel="stylesheet" /><link href="portrait.css" rel="stylesheet" />

    ๋ฏธ๋””์–ด ์ฟผ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ (์ตœ์ ํ™” ํ›„)

    <link href="style.css" rel="stylesheet" /><link href="print.css" rel="stylesheet" media="print" /><link href="portrait.css" rel="stylesheet" media="orientation:portrait" />
  • ์™ธ๋ถ€ ์Šคํƒ€์ผ์‹œํŠธ๋ฅผ ๊ฐ€์ ธ์˜ฌ ๋•Œ ์‚ฌ์šฉํ•˜๋Š” @import ๋ฌธ์€ ์Šคํƒ€์ผ์‹œํŠธ๋ฅผ ๋ณ‘๋ ฌ๋กœ ๋‹ค์šด๋กœ๋“œ ํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ๋กœ๋“œ ์‹œ๊ฐ„์ด ๋Š˜์–ด๋‚  ์ˆ˜ ์žˆ๋‹ค.

JavaScript ์ตœ์ ํ™”#

  • JavaScript๋Š” DOMํŠธ๋ฆฌ์™€ CSSOM ํŠธ๋ฆฌ๋ฅผ ๋™์ ์œผ๋กœ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— HTML ํŒŒ์‹ฑ์„์ฐจ๋‹จํ•˜๋Š” ๋ธ”๋ก ๋ฆฌ์†Œ์Šค์ด๋‹ค.

  • <script> ํƒœ๊ทธ๋ฅผ ๋งŒ๋‚˜๋ฉด ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์‹คํ–‰๋˜๋ฉฐ ๊ทธ ์ด์ „๊นŒ์ง€ ์ƒ์„ฑ๋œ DOM์—๋งŒ ์ ‘๊ทผํ• ์ˆ˜ ์žˆ๋‹ค.

  • ๊ทธ๋ฆฌ๊ณ  ์Šคํฌ๋ฆฝํŠธ ์‹คํ–‰์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ DOM ํŠธ๋ฆฌ ์ƒ์„ฑ์ด ์ค‘๋‹จ๋œ๋‹ค.

  • ์ด๋Ÿฌํ•œ ์ด์œ ๋กœ JavaScript๋ฅผ ๋ Œ๋”๋ง ์ฐจ๋‹จ ๋ฆฌ์†Œ์Šค๋ผ๊ณ  ํ•œ๋‹ค.

๋ฆฌ์†Œ์Šค ์š”์ฒญ ์ˆ˜ ์ค„์ด๊ธฐ#

์ด๋ฏธ์ง€ ์Šคํ”„๋ผ์ดํŠธ#

2020-11-08-201109-image-1

  • ์›น ํŽ˜์ด์ง€์—์„œ ์•„์ด์ฝ˜ ๋งˆ๋‹ค ๋‹ค๋ฅธ ์ด๋ฏธ์ง€๋ฅผ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ ๋ฆฌ์†Œ์Šค ์š”์ฒญ์ด ์•„์ด์ฝ˜ ๋งˆ๋‹ค๋ฐœ์ƒ

  • ์—ฌ๋Ÿฌ ์•„์ด์ฝ˜์„ ๋ฌถ์–ด ํ•˜๋‚˜์˜ ์ด๋ฏธ์ง€๋กœ ๋งŒ๋“ค๊ณ , CSS์˜ background-position ์†์„ฑ์„์‚ฌ์šฉํ•ด ๋ถ€๋ถ„ ์ด๋ฏธ์ง€๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ๋ฆฌ์†Œ์Šค ์š”์ฒญ ์ˆ˜๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.

CSS, JavaScript ๋ฒˆ๋“ค๋ง#

  • ๋ชจ๋“ˆ ๊ธฐ๋ฐ˜ ๊ฐœ๋ฐœ ์ด์ „์—๋Š” ์—ฌ๋Ÿฌ ๋ฆฌ์†Œ์Šค ํŒŒ์ผ์„ ๋ถ„๋ฆฌํ•ด์„œ ๊ฐ€์ ธ์™”์—ˆ๋‹ค.

  • Webpack, Rollup ๋“ฑ์˜ ๋ฒˆ๋“ค๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๋ชจ๋“ˆ ํŒŒ์ผ์„ ํ•˜๋‚˜๋กœ ๋ฌถ์–ด์„œ 1๊ฐœํŒŒ์ผ๋กœ ๋งŒ๋“ค์–ด ๋ฆฌ์†Œ์Šค ์š”์ฒญ ์ˆ˜๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.

๋‚ด๋ถ€ ์Šคํƒ€์ผ ์‹œํŠธ ?#

โ˜ ๋‚ด๋ถ€ ์Šคํƒ€์ผ ์‹œํŠธ๋Š” ๋ฆฌ์†Œ์Šค ์š”์ฒญ ํšŸ์ˆ˜๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด์ง€๋งŒ, ๋ฆฌ์†Œ์Šค ์บ์‹œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์–ด์„œ HTML์— CSS๊ฐ€ ๋งค๋ฒˆ ํฌํ•จ๋œ๋‹ค.

์ž‘์€ ์ด๋ฏธ์ง€๋ฅผ HTML, CSS๋กœ ๋Œ€์ฒด#

  • ์•„์ด์ฝ˜ ์ด๋ฏธ์ง€ ๊ฐœ์ˆ˜๊ฐ€ ์ ์€ ๊ฒฝ์šฐ, ์ด๋ฏธ์ง€๋ฅผ Base64๋กœ ๋ณ€ํ™˜ํ•œ URI๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ HTML, CSS์— ํฌํ•จํ•ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

    <img    src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAOCAYAAAAbvf3sAAAAAXNSR0IArs4c6QAAAHBJREFUKBVjYBimICwsLAaEsXmPGV0QqnAeUNxfW1v7/tWrVy8hq0HRgKQ4CahoIxDPQ9cE14CseNWqVUtAJoMUo2tiBFkXGRmp9/fv3zNAZhJIMUgMBmAGMTMzmyxfvhzhPJAmmCJ0Gp8cutqhwAcASWgwk+79LiQAAAAASUVORK5CYII="/>

๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ํ•„์š”ํ•œ ํ•จ์ˆ˜๋งŒ ๊ฐ€์ ธ์˜ค๊ธฐ#

import _ from 'lodash';
_.array(...);_.object(...);

โ‡’

import array from 'lodash/array';import object from 'lodash/fp/object';
array(...);object(...);

HTML ๋งˆํฌ์—… ์ตœ์ ํ™”#

  • ์ค‘์ฒฉ์„ ๋‹จ์ˆœํ•˜๊ฒŒ ๊ตฌ์„ฑํ•œ๋‹ค.

Avoid an excessive DOM size

์••์ถ•(Minify)ํ•˜์—ฌ ์‚ฌ์šฉ#

  • ์›นํŒฉ ํ”Œ๋Ÿฌ๊ทธ์ธ๊ณผ ๊ฐ™์€ ๋„๊ตฌ์˜ ๋„์›€์œผ๋กœ ๋ถˆํ•„์š”ํ•œ ์ฃผ์„์ด๋‚˜ ๊ณต๋ฐฑ์„ ๋ชจ๋‘ ์‚ญ์ œํ•˜๊ณ , ๋‚œ๋…ํ™” ํ•˜๋Š” ๋“ฑ ์ฝ”๋“œ์˜ ์šฉ๋Ÿ‰์„ ์••์ถ•ํ•  ์ˆ˜ ์žˆ๋‹ค.

๋ Œ๋”๋ง ์ตœ์ ํ™”#

requestAnimationFrame#

  • ์‹œ๊ฐ์  ๋ณ€ํ™”๊ฐ€ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ •ํ™•ํ•œ ์‹œ๊ฐ„(ํ”„๋ ˆ์ž„ ์‹œ์ž‘ ์‹œ)์— ์ˆ˜ํ–‰๋˜๊ธธ ์›ํ•œ๋‹ค.

  • ์ด๋ฅผ ๋ณด์žฅํ•˜๋Š” ์œ ์ผํ•œ ๋ฐฉ๋ฒ•์€ requestAnimationFrame ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

  • setTimeout ๋˜๋Š” setInterval ์€ ์ฝœ๋ฐฑ์ด ์ •ํ™•ํ•œ ์‹œ๊ฐ„์— ์ˆ˜ํ–‰๋˜๋Š” ๊ฒƒ์„ ๋ณด์žฅํ•˜์ง€์•Š๋Š”๋‹ค.

2020-11-08-201109-image-2

โ˜ setTimeout ๊ณผ setInterval ์˜ ์ฝœ๋ฐฑ์€ (macro)Task queue ๋ฅผ ์‚ฌ์šฉ. requestAnimationFrame ์€ AnimationFrame ์‚ฌ์šฉ.

์Šคํƒ€์ผ ๊ณ„์‚ฐ์˜ ๋ฒ”์œ„์™€ ๋ณต์žก์„ฑ ์ค„์ด๊ธฐ#

2020-11-08-201109-image-3

  • DOM ๋ณ€๊ฒฝ, ์š”์†Œ ์ถ”๊ฐ€ ๋ฐ ์ œ๊ฑฐ, ์†์„ฑ ๋ณ€๊ฒฝ, ํด๋ž˜์Šค ๋˜๋Š” ์• ๋‹ˆ๋ฉ”์ด์…˜์€ ๋ชจ๋‘ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์š”์†Œ ์Šคํƒ€์ผ์„ ์žฌ๊ณ„์‚ฐํ•˜๊ณ  ๋งŽ์€ ๊ฒฝ์šฐ์— ๋ ˆ์ด์•„์›ƒ ๋‹จ๊ณ„(๋ฆฌํ”Œ๋กœ์šฐ)๋ฅผ ๊ฑฐ์น˜๊ฒŒ ๋งŒ๋“ ๋‹ค.

  • ์Šคํƒ€์ผ ๊ณ„์‚ฐ ๋‹จ๊ณ„์˜ ์ฒซ ๋ถ€๋ถ„์€ ๋งค์นญ ์„ ํƒ๊ธฐ ์ง‘ํ•ฉ์„ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ด๋‹ค. (์š”์†Œ, ํด๋ž˜์Šค , ID, pseudo ์„ ํƒ์ž ๋“ฑ๋“ฑ)

  • ์Šคํƒ€์ผ ๊ณ„์‚ฐ์˜ ๋‘ ๋ฒˆ์งธ ๋‹จ๊ณ„๋Š” ๋งค์นญ๋œ ์„ ํƒ๊ธฐ์—์„œ ์Šคํƒ€์ผ ๊ทœ์น™์„ ๊ฐ€์ ธ์™€์„œ ์š”์†Œ์˜๋งˆ์ง€๋ง‰ ์Šคํƒ€์ผ์„ ๊ณ„์‚ฐํ•˜๋Š” ๊ณผ์ •์ด ํฌํ•จ๋œ๋‹ค.

  • ๋”ฐ๋ผ์„œ ์„ ํƒ๊ธฐ์˜ ๋ณต์žก์„ฑ์„ ์ค„์ด๊ณ  (BEM ๋“ฑ์˜ ๋ฐฉ๋ฒ•๋ก  ์ ์šฉ) ์Šคํƒ€์ผ์„ ๊ณ„์‚ฐํ•ด์•ผ ํ•˜๋Š”์š”์†Œ์˜ ์ˆ˜๋ฅผ ์ค„์—ฌ์•ผ ํ•œ๋‹ค.

ํฌ๊ณ  ๋ณต์žกํ•œ ๋ ˆ์ด์•„์›ƒ ๋ฐ ์Šค๋ž˜์‹ฑ ํ”ผํ•˜๊ธฐ#

  • ๋ ˆ์ด์•„์›ƒ์˜ ๋ฒ”์œ„๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ์ „์ฒด ๋ฌธ์„œ๋กœ ์ง€์ •๋œ๋‹ค.

    • ๋„ˆ๋น„, ๋†’์ด, ์™ผ์ชฝ ๋˜๋Š” ์ƒ๋‹จ ๋“ฑ "๊ธฐํ•˜ํ•™์  ์†์„ฑ"์˜ ๋ณ€๊ฒฝ์€ ๋ชจ๋‘ ๋ ˆ์ด์•„์›ƒ์ดํ•„์š”ํ•˜๋‹ค.

    • flexbox ๋ฅผ ์‚ฌ์šฉํ•œ ๋ ˆ์ด์•„์›ƒ์ด float ๋ฅผ ์‚ฌ์šฉํ•œ ๋ ˆ์ด์•„์›ƒ ๋ณด๋‹ค ๋น„์šฉ์ด ์ ๋‹ค.

  • DOM ์š”์†Œ์˜ ์ˆ˜๋Š” ์„ฑ๋Šฅ์— ์˜ํ–ฅ์„ ์ฃผ๋ฏ€๋กœ ๊ฐ€๊ธ‰์  ๋ ˆ์ด์•„์›ƒ ํŠธ๋ฆฌ๊ฑฐ๋ฅผ ํ”ผํ•ด์•ผ ํ•œ๋‹ค.

  • ๊ฐ•์ œ ๋™๊ธฐ์‹ ๋ ˆ์ด์•„์›ƒ ๋ฐ ๋ ˆ์ด์•„์›ƒ ์Šค๋ž˜์‹ฑ์„ ํ”ผํ•ด์•ผ ํ•œ๋‹ค.

    โ˜ ์›๋ž˜ ๋ ˆ์ด์•„์›ƒ์€ ๋น„๋™๊ธฐ์ด๋‚˜, ํŠน์ • ์ƒํ™ฉ์—์„œ ๋™๊ธฐ์ ์œผ๋กœ ๋ ˆ์ด์•„์›ƒ์ด ๋ฐœ์ƒํ•  ์ˆ˜์žˆ๋‹ค. ์ด๊ฒƒ์„ ๊ฐ•์ œ ๋™๊ธฐ์‹ ๋ ˆ์ด์•„์›ƒ ์ด๋ผ ํ•œ๋‹ค.

    function logBoxHeight() {    box.classList.add('super-big');
        // Gets the height of the box in pixels    // and logs it out.    console.log(box.offsetHeight);}
    • ์œ„์˜ ํ•จ์ˆ˜๋Š” ์Šคํƒ€์ผ์„ ๋ณ€๊ฒฝํ•œ ํ›„์—, ๋†’์ด๋ฅผ ์š”์ฒญํ•œ๋‹ค.

    • ๋†’์ด๋ฅผ ๊ตฌํ•˜๋Š” ๊ฒƒ ์—ญ์‹œ ๋ ˆ์ด์•„์›ƒ์„ ์‹คํ–‰ํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

    • ์Šคํƒ€์ผ ๊ณ„์‚ฐ๊ณผ ๋ ˆ์ด์•„์›ƒ์„ ๋™์‹œ์— ์‹คํ–‰ํ•˜๋ฉด ์ž ์žฌ์  ๋ณ‘๋ชฉ ํ˜„์ƒ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ผ๋ฐ˜์ ์œผ๋กœ ๋ฐ”๋žŒ์งํ•˜์ง€ ์•Š๋‹ค.

    function resizeAllParagraphsToMatchBlockWidth() {    // Puts the browser into a read-write-read-write cycle.    for (var i = 0; i < paragraphs.length; i++) {        paragraphs[i].style.width = box.offsetWidth + 'px';    }}
    • ์œ„์˜ ํ•จ์ˆ˜๋Š” ๊ฐ ๋ฃจํ”„์˜ ๋ฐ˜๋ณต์ด ์Šคํƒ€์ผ ๊ฐ’ box.offsetWidth ๋ฅผ ์ฝ์€ ๋‹ค์Œ, ์ฆ‰์‹œ paragraphs[i].style.width ๋ฅผ ์—…๋ฐ์ดํŠธ ํ•œ๋‹ค.

    • ์ด์ „ ๋ฐ˜๋ณต์—์„œ ๋ ˆ์ด์•„์›ƒ์ด ๋ณ€๊ฒฝ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— box.offsetWidth ์„ ์กฐํšŒํ•˜๋Š” ๊ฒƒ์—ญ์‹œ ๊ฐ•์ œ ๋™๊ธฐ์‹ ๋ ˆ์ด์•„์›ƒ์„ ์œ ๋ฐœํ•œ๋‹ค. ์ด๋ฅผ ์•„๋ž˜์™€ ๊ฐ™์ด ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

    // Read.var width = box.offsetWidth;
    function resizeAllParagraphsToMatchBlockWidth() {    for (var i = 0; i < paragraphs.length; i++) {        // Now write.        paragraphs[i].style.width = width + 'px';    }}

ํŽ˜์ธํŠธ ๋ณต์žก์„ฑ ๋‹จ์ˆœํ™” ๋ฐ ํŽ˜์ธํŠธ ์˜์—ญ ์ค„์ด๊ธฐ#

  • transform ๋˜๋Š” opacity ๋ฅผ ์ œ์™ธํ•œ ๋ชจ๋“  ์†์„ฑ ๋ณ€๊ฒฝ์€ ํ•ญ์ƒ ํŽ˜์ธํŠธ๋ฅผ ํŠธ๋ฆฌ๊ฑฐ ํ•œ๋‹ค.

  • ๊ฐ€๋Šฅํ•œ ํ•˜์œ„ ๋…ธ๋“œ์˜ DOM์„ ์กฐ์ž‘ํ•˜๊ณ  ์Šคํƒ€์ผ์„ ๋ณ€๊ฒฝ

    • DOM์ด ์ž‘๊ณ  ๊นŠ์ด๊ฐ€ ์–•์„์ˆ˜๋ก ๊ณ„์‚ฐ์ด ๋น ๋ฅด๋‹ค.

    • ๋ถˆํ•„์š”ํ•œ ๋ž˜ํผ ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ์ œ๊ฑฐํ•œ๋‹ค.

  • ์˜ํ–ฅ ๋ฐ›๋Š” ์—˜๋ฆฌ๋จผํŠธ ์ œํ•œ



ยท ์•ฝ 6๋ถ„

Strict Mode#

  • ES5 ๋ถ€ํ„ฐ ์ง€์›

  • ์ „์—ญ ๋˜๋Š” ํ•จ์ˆ˜ body์˜ ์„ ๋‘์— use strict ์ถ”๊ฐ€

  • ์•”๋ฌต์  ์ „์—ญ ๋ณ€์ˆ˜ ๋ฐฉ์ง€

  • ๋ณ€์ˆ˜, ํ•จ์ˆ˜, ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ์‚ญ์ œ ๋ฐฉ์ง€

    function foo(a) {    'use strict';
        delete a;    // SyntaxError: Delete of an unqualified identifier in strict mode.}
  • ๋งค๊ฐœ๋ณ€์ˆ˜ ์ด๋ฆ„์˜ ์ค‘๋ณต ๋ฐฉ์ง€

  • with ๋ฌธ์˜ ์‚ฌ์šฉ

  • ์ผ๋ฐ˜ ํ•จ์ˆ˜์˜ this ์— undefined ๋ฐ”์ธ๋”ฉ

    'use strict';
    function foo() {    console.log(this);}
    foo(); // undefined
    function foo() {    console.log(this);}
    foo(); // Window

DOCTYPE#

Document Type์˜ ์•ฝ์ž๋กœ ๋ฌธ์„œ๊ฐ€ ์–ด๋–ค ๋ฒ„์ „์œผ๋กœ ์ž‘์„ฑ๋˜์—ˆ๋Š”์ง€ ๋ฏธ๋ฆฌ ์„ ์–ธํ•˜์—ฌ ์›น ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋‚ด์šฉ์„ ์˜ฌ๋ฐ”๋กœ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ๋Š” ๊ฒƒ์ด๋‹ค.

โ˜ DOCTYPE ์€ ๋ ˆ๊ฑฐ์‹œํ•œ ์ด์œ ๋กœ ํ•„์š”ํ•˜๋‹ค. ์ƒ๋žตํ•˜๋ฉด ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋ฌธ์„œ๋ฅผ quirks mode(ํ˜ธํ™˜ ๋ชจ๋“œ) ๋กœ ๋ Œ๋”๋งํ•˜๊ณ , ํฌํ•จํ•˜๋ฉด ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋ฌธ์„œ๋ฅผ no-quirks-mode(๋˜๋Š” standard mode) ๋กœ ๋ Œ๋”๋ง ํ•œ๋‹ค.

quirks mode vs standard mode#

quirks mode#

  • ์˜ค๋ž˜๋œ ๋ฌธ์„œ๊ฐ€ ์ตœ์‹  ๋ธŒ๋ผ์šฐ์ €์—์„œ "๋น„ํ‘œ์ค€ ๋ชจ๋“œ"(๊ณผ๊ฑฐ Navigator 4 or IE 5)๋ฅผ ์ ์šฉํ•ด์„œ ๋™์ž‘ํ•œ๋‹ค.

  • ์ตœ์‹  ๋ธŒ๋ผ์šฐ์ €์—์„œ ๊นจ์ง€์ง€ ์•Š๊ณ  ๋ณด์—ฌ์ง€๊ฒŒ ๋˜์ง€๋งŒ, ๋ธŒ๋ผ์šฐ์ € ๋ณ„๋กœ ๋‹ค๋ฅด๊ฒŒ ๋ณด์—ฌ์ง€๊ฒŒ๋œ๋‹ค.

standard mode#

  • ํ‘œ์ค€ HTML, CSS๋ฅผ ์ ์šฉํ•˜์—ฌ ๋ Œ๋”๋งํ•œ๋‹ค.

DTD (Document Type Definition)#

๋ฌธ์„œ ํ˜•์‹์„ ์ •์˜ํ•œ ๊ฒƒ์œผ๋กœ DOCTYPE ์„ ๋ช…์‹œํ•  ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. DTD ์—๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒƒ๋“ค์ด ์žˆ๋‹ค. ๋ชจ๋“  ํƒ€์ž…์˜ ํŠน์„ฑ์„ ๋‹ค ํŒŒ์•…ํ•˜๋Š” ๊ฒƒ์€ ๋ฌด๋ฆฌ๊ฐ€ ์žˆ์„ ๊ฒƒ ๊ฐ™๊ณ , ํ˜„์žฌ ์‹œ์ ์—์„œ HTML5 ๋ฌธ์„œ๋ฅผ ์ž‘์„ฑํ•˜๊ธฐ ์œ„ํ•ด <!DOCTYPE html> ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ตœ์„ ์ด๋‹ค.

  • XHTML 1.1

  • XHTML 1.0

    • Strict DTD

    • Transitional DTD

    • Frameset DTD

  • HTML 4.01

    • Strict DTD

    • Transitional DTD

    • Frameset DTD

  • HTML 5

ํฌ๋กœ์Šค ๋ธŒ๋ผ์šฐ์ง•#

๋ฐ”๋ฒจ#

  • ๋ฐ”๋ฒจ์€ ํ˜„์žฌ ๋ฐ ์ด์ „ ๋ธŒ๋ผ์šฐ์ € ๋˜๋Š” ํ™˜๊ฒฝ์—์„œ ES6 ์ด์ƒ์˜ ์ฝ”๋“œ๋ฅผ ์ด์ „ ๋ฒ„์ „๊ณผ ํ˜ธํ™˜๋˜๋Š” JavaScript ๋ฒ„์ „์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋˜๋Š” ๋„๊ตฌ ๋ชจ์Œ(toolchain)์ด๋‹ค.

  • ๋ฐ”๋ฒจ์€ ์„ธ ๋‹จ๊ณ„๋กœ ๋นŒ๋“œ๋ฅผ ์ง„ํ–‰ํ•œ๋‹ค.

    1. ํŒŒ์‹ฑ (Parsing) : ์ฝ”๋“œ๋ฅผ ์ฝ๊ณ  ์ถ”์ƒ ๊ตฌ๋ฌธํŠธ๋ฆฌ(AST)๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๋‹จ๊ณ„

    2. ๋ณ€ํ™˜ (Transforming) : ๋ฐ”๋ฒจ ํ”Œ๋Ÿฌ๊ทธ์ธ์ด ์ถ”์ƒ ๊ตฌ๋ฌธ ํŠธ๋ฆฌ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๋‹จ๊ณ„

    3. ์ถœ๋ ฅ (Printing) : ๋ณ€๊ฒฝ๋œ ๊ฒฐ๊ณผ๋ฌผ์„ ์ถœ๋ ฅํ•˜๋Š” ๋‹จ๊ณ„

  • ์ปดํŒŒ์ผ๋Ÿฌ๋กœ์จ ๋ฐ”๋ฒจ ํ”Œ๋Ÿฌ๊ทธ์ธ(๊ตฌ๋ฌธ ๋ณ€ํ˜•)๊ณผ ํด๋ฆฌํ•„์ด ํ•˜๋Š” ์ผ(๋‚ด์žฅ๋œ ํ•จ์ˆ˜/๊ฐ์ฒด ๊ตฌํ˜„ )์„ ๊ตฌ๋ถ„ํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜๋‹ค.

    • ํ™”์‚ดํ‘œ ํ•จ์ˆ˜

      ๊ตฌ๋ฌธ ๋ณ€ํ˜•์œผ๋กœ ์ด์ „ ๋ฒ„์ „์˜ ์ฝ”๋“œ๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

      // ์ปดํŒŒ์ผ ์ „const sum = (a, b) => a + b;
      // ์ปดํŒŒ์ผ ํ›„'use strict';
      var sum = function sum(a, b) {    return a + b;};
    • Promise

      Promise ๋Š” ES6์—์„œ ์ถ”๊ฐ€๋œ ํ‘œ์ค€ ๋‚ด์žฅ ๊ฐ์ฒด(standard built-in object)์ด๋‹ค. ๋”ฐ๋ผ์„œ ๊ตฌ๋ฌธ ๋ณ€ํ˜•์œผ๋กœ ์ด์ „ ๋ฒ„์ „์˜ ์ฝ”๋“œ๋กœ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์ด๋ฅผ ์œ„ํ•œ ํด๋ฆฌํ•„์„ ์ถ”๊ฐ€ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

  • ๋ฐ”๋ฒจ์˜ useBuiltIns ์˜ต์…˜

    • ๊ธฐ๋ณธ์ ์œผ๋กœ import 'core-js' ๋Š” core-js ์˜ ๋ชจ๋“  ํด๋ฆฌํ•„ ๊ฐ€์ ธ์˜ด

    • useBuiltIns: entry ์˜ต์…˜์„ ์ฃผ๋ฉด import 'core-js' ์—์„œ "๋Œ€์ƒ ๋ธŒ๋ผ์šฐ์ €์— ํ•„์š”ํ•œ" ํด๋ฆฌํ•„์„ ๋ชจ๋‘ ๊ฐ€์ ธ์˜ด

    • useBuiltIns: usage ์˜ต์…˜์„ ์ฃผ๋ฉด import ๋ฅผ ํ•˜์ง€ ์•Š์•„๋„ ์ฝ”๋“œ๋ฅผ ์ •์  ๋ถ„์„ํ•˜์—ฌ, ์ฝ”๋“œ์—์„œ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ํด๋ฆฌํ•„๋งŒ ๊ฐ€์ ธ์˜จ๋‹ค.

      • ์ง€์›ํ•˜๋ ค๋Š” "๋ธŒ๋ผ์šฐ์ € ๋งˆ๋‹ค" ํ•„์š”ํ•œ ํด๋ฆฌํ•„๋งŒ import ํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ•˜๋Š”๊ฐ€? ex) ie, chrome์ด ํƒ€๊ฒŸ์ธ ๊ฒฝ์šฐ promise๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด, promise ํด๋ฆฌํ•„์„ import ํ•ด์•ผํ•˜์ง€๋งŒ, ์ด๋Š” chrome์—๊ฒŒ๋Š” ๋ถˆํ•„์š”ํ•˜๋‹ค.

      • ๋ฒˆ๋“ค์— ํฌํ•จ์‹œํ‚ค๋Š” ๊ฒƒ๊นŒ์ง€ ์ตœ์ ํ™” ํ•˜๋ ค๋ฉด ๋Ÿฐํƒ€์ž„ ๊ฒ€์‚ฌ๊ธฐ๋ฅผ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ User-agent ๊ธฐ๋ฐ˜ ๊ฐ์ง€๋ฅผ ํ•ด์•ผ ๋˜๋Š”๋ฐ, ์ด๋Š” ๋ฆฌ์†Œ์Šค๋ž‘ ์‹œ๊ฐ„์ด ๋งŽ์ด ๋“ ๋‹ค.

        zloirock/core-js

        [Feature Request] Polyfill using dynamic import. ยท Issue #518 ยท zloirock/core-js

      • module , nomodule ์˜ ์ง€์› ์—ฌ๋ถ€์— ๋”ฐ๋ผ ๋ฒˆ๋“ค๋ง์„ ๋‚˜๋ˆ  ์ตœ์ ํ™”ํ•˜๋Š” ๋ฐฉ๋ฒ•๋„์žˆ๋‹ค.

        Serve modern code to modern browsers for faster page loads


ยท ์•ฝ 4๋ถ„

์ผ๋ฐ˜ ํ•จ์ˆ˜ vs ํ™”์‚ดํ‘œ ํ•จ์ˆ˜#

const shape = {    radius: 10,    diameter() {        return this.radius * 2;    },    arrowDiameter: () => {        return this.radius * 2;    },};
console.log(shape.diameter());// 20console.log(shape.arrowDiameter());// NaN
const diameter = shape.diameter;const arrowDiameter = shape.arrowDiameter;
console.log(diameter());// NaNconsole.log(arrowDiameter());// NaN
function Shape() {    this.radius = 10;    this.diameter = function () {        return this.radius * 2;    };    this.arrowDiameter = () => {        return this.radius * 2;    };}
const shape = new Shape();
console.log(shape.diameter());// 20console.log(shape.arrowDiameter());// 20
const diameter = shape.diameter;const arrowDiameter = shape.arrowDiameter;
console.log(diameter());// NaNconsole.log(arrowDiameter());// 20
  • ์ผ๋ฐ˜ ํ•จ์ˆ˜๋Š” ํ˜ธ์ถœํ•  ๋•Œ ๋™์ ์œผ๋กœ this ๋ฅผ ๋ฐ”์ธ๋”ฉํ•œ๋‹ค.

  • ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” ์„ ์–ธํ•  ๋•Œ ์ •์ ์œผ๋กœ this ๋ฅผ ๋ฐ”์ธ๋”ฉํ•œ๋‹ค. (์–ธ์ œ๋‚˜ ์ƒ์œ„ ์Šค์ฝ”ํ”„์˜ this ๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.)

  • ์ผ๋ฐ˜ ํ•จ์ˆ˜๋Š” prototype ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ€์ง„๋‹ค. โ‡’ constructor ํ•จ์ˆ˜๋กœ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋‹ค.

  • ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” prototype ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์ง€ ์•Š๋‹ค. โ‡’ constructor ํ•จ์ˆ˜๋กœ์‚ฌ์šฉ๋  ์ˆ˜ ์—†๋‹ค.


์ƒ์„ฑ์ž ํ•จ์ˆ˜(constructor)์™€ ํ”„๋กœํ† ํƒ€์ž…(prototype)#

function Person(name, age) {    this.name = name;    this.age = age;}
// Person.prototype = { constructor: function Person(...) { ... } }// Person.prototype.constructor = function Person(...) { ... }
const foo = new Person('foo', 30);// foo: Person { name: 'foo', age: 30 }// foo.__proto__: { constructor: function Person(...) { ... } }// foo.__proto__.constructor = function Person(...) { ... }

2020-11-06-201106-image-0


2020-11-06-201106-image-1

โ˜ __proto__ ๋Š” ECMAScript์˜ ์ŠคํŽ™์ด ์•„๋‹Œ ์ผ๋ถ€ ๋ชจ๋˜ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๊ตฌํ˜„ํ•œ ๊ฒƒ์œผ๋กœ, [[Prototype]] ๋ฅผ ์ ‘๊ทผํ•˜๋Š” ์†์„ฑ์ด๋‹ค.

function Person(name) {    this.name = name;    this.getName = function () {        return this.name;    };}
console.log(Person.prototype); // { constructor: function Person(name) { ... } }
function Child(name, age) {    Person.call(this, name);    this.age = age;    this.getAge = function () {        return this.age;    };}
console.log(Child.prototype); // { constructor: function Child(name, age) { ... } }
Child.prototype = Object.create(Person.prototype);
console.log(Object.create(Person.prototype)); // Person {}console.log(Child.prototype); // Person {}console.log(Child.prototype.constructor); // function Person(name) { ... }
Child.prototype.constructor = Child;
console.log(Child.prototype);// Person { constructor: function Child(name, age) { ... } }
var child = new Child('foo', 20);
console.log(child.getName()); // 'foo'console.log(child.getAge()); // 20

ํด๋ž˜์Šค ๋ฌธ๋ฒ•์€ ๋‹จ์ง€ "๊ตฌ๋ฌธ์  ์„คํƒ•" ์ธ๊ฐ€?#

class User {    constructor(name) {        this.name = name;    }
    sayHi() {        alert(this.name);    }}
let user = new User('John');user.sayHi();
function User(name) {    this.name = name;}
User.prototype.sayHi = function () {    alert(this.name);};
let user = new User('John');user.sayHi();

ES6์˜ ํด๋ž˜์Šค ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๊ณผ ์ผ์น˜ํ•œ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ์กด function + prototype ๋ฌธ๋ฒ•์˜ ์กฐํ•ฉ์œผ๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ผ๋ถ€ ์‚ฌ๋žŒ๋“ค์€ ๋‹จ์ง€ ํด๋ž˜์Šค ๋ฌธ๋ฒ•์„ "๊ตฌ๋ฌธ์  ์„คํƒ•" (syntax sugar)๋ผ๊ณ  ๋งํ•œ๋‹ค.

ํ•˜์ง€๋งŒ ๋ช‡ ๊ฐ€์ง€ ์ค‘์š”ํ•œ ์ฐจ์ด๊ฐ€ ์žˆ๋‹ค.

  1. class ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•ด์„œ ๋งŒ๋“  ํ•จ์ˆ˜์—” ํŠน์ˆ˜ ๋‚ด๋ถ€ ํ”„๋กœํผํ‹ฐ์ธ [[FunctionKind]]: "classConstructor" ๊ฐ€ ์ด๋ฆ„ํ‘œ์ฒ˜๋Ÿผ ๋ถ™์–ด์„œ, ์ด ํด๋ž˜์Šค ์ƒ์„ฑ์ž๋ฅผ new ์™€ ํ•จ๊ป˜ ํ˜ธ์ถœํ•˜์ง€ ์•Š์œผ๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

  2. ํด๋ž˜์Šค์˜ ๋ฉ”์†Œ๋“œ๋Š” non-enumerable ๋กœ, for ... in ๊ตฌ๋ฌธ ๋“ฑ์˜ ๊ฐ์ฒด ์ˆœํšŒ์—์„œ๋ฉ”์†Œ๋“œ๋Š” ์ˆœํšŒํ•˜์ง€ ์•Š๋Š”๋‹ค. (enumerable ํ”Œ๋ž˜๊ทธ๊ฐ€ false ์ด๋‹ค.)

  3. ํด๋ž˜์Šค๋Š” ํ•ญ์ƒ use strict ๋ชจ๋“œ์ด๋‹ค.

  4. ์ด์™ธ์—๋„ getter, setter, ๋ฏน์Šค์ธ ๋“ฑ์˜ ๊ธฐ๋Šฅ์ด ์žˆ๋‹ค.

ํด๋ž˜์Šค์™€ ํ•จ์ˆ˜์—์„œ์˜ new ์—ฐ์‚ฐ์ž ๋™์ž‘#

2020-11-06-201106-image-2