캐시라는 단어를 들어봤더라도 그것이 웹에서 정확하게 어떤 의미인지는 잘 모를겁니다. 흔히 캐싱의 의미는 어떤 것을 나중에 유용하게 사용하기위해 저장한다는 뜻입니다. 브라우저나 웹에서의 캐시는 이와 동일한 뜻이고 추가로 프로그램과 웹사이트 자산을 저장합니다. 웹사이트를 방문했을 때, 당신의 브라우저는 몇 개의 페이지를 가지고 있고 그것을 컴퓨터 하드디스크에 저장합니다. 브라우저가 저장할 자산은 아래와 같습니다.
이미지: 로고, 사진, 백그라운드 등
HTML
CSS
Javascript
간단히 말해서 브라우저는 정적인 자산(웹페이지에 방문할 때마다 변하지 않는 것들)을 캐시합니다.
무엇을 캐시하고 얼마나 저장할지는 웹사이트에 의해 결정됩니다. 어떤 자산을 며칠만에 제거되지만 어떤 것들은 1년 넘게 캐시되어 있을 수 있습니다.
많은 사람이 웹사이트가 당신의 컴퓨터에 허락도 없이 자산을 저장한다고 했을 때, 그들은 약간 신경쓰입니다. 그리고 우리는 웹 개발자가 파괴적이고 악의적인 것들을 우리의 다바이스에 저장시키지 않도록 희망하면서 신뢰하고 있다고 말할 수 있습니다.
브라우저 캐싱의 이점은 위험보다 훨씬 큽니다. 좋은 방화벽, 바이러스 스캐너는 당신의 기계가 안전하도록 유지합니다.
캐시의 이점
웹사이트에 처음 방문했을 때, 당신의 브라우저는 원격으로 호스트 사이트 서버와 커뮤니케이션을 합니다. 브라우저는 요청하고 서버는 응답을 하면서 웹사이트 자산을 전달해 줍니다. HTML이 처음 다운로드되고 이것이 어떤 사이트를 그려야 하는지에 대한 정보가 담겨있습니다. 브라우저가 HTML 코드를 읽을 때 서버에게 다른 페이지에 대한 정보를 추가로 요청하는데 대부분 위에서 언급한 정적 자산입니다.
이 프로세스는 bandwidth을 사용합니다. 일부 웹페이지는 자산이 많고 크기때문에 모든 페이지를 다운로드하고 기능을 수행하는데 오랜 시간이 걸립니다.
예를 들어, 텍스트가 이미지가 먼저 나타나는 것을 웹사이트 처음 방문했을 때 느꼈을 겁니다. 텍스트가 자산 크기가 작기때문에 다운로드하는데 적은 시간이 걸리는 겁니다. 반면에 고화질의 이미지가 로드되는데는 몇초가 걸릴 수 있습니다.
캐싱은 브라우실 속도를 향상시킵니다. 일단 자산을 다운로드하면 그것은 어러분의 기계에 일정 기간동안 존재합니다. 당신의 하드디스크에서 파일을 검색하는 것이 인터넷이 아무리 빠르더라도 원격으로 서번에 요청하는것보다 효율적입니다.
일반적인 이커머스 사이트로 생각했을 때, 로고와 같은 자산은 사이트 어느 페이지에 있던 간에 동일한 위치에 표시됩니다. 캐시 기능이 없다면 다른 페이지로 이동할 때 마다 로고를 다운로드해야합니다.
고 퀄리티 이미지와 같이 복잡한 사이트는 큰 자바스크립트 파일을 사용합니다. 구매하기 버튼이 제품 하단에 나타나는데 5~10초 정도 걸린다고 가정했을 때 유저의 전환률이 부정적인 영향을 준다고 상상을 해봅시다. 유저가 편안하고 전환율을 높일 수 있게 하기위해서는 웹페이지는 빠르고 유동적이어야 합니다. 더불어 다음번에 캐시가 된 웹페이지에 방문하면 당신 디바이스에 저장된 자산을 활용해 빠르게 로딩할 수 있습니다.
모바일 디바이스는 빈번하게 bandwidth에 의해 제한됩니다. 일부 모바일데이터는 bandwidth에 대한 캡과 비용을 부과합니다. 유저입장에서 웹사이트를 다운로드를 하지않아야 좋을 것입니다.
캐시의 문제점
웹사이트에서 캐싱된 자산을 사용할 수 있도록 허용했습니다. 다음 날 로고는 색을 변경했습니다. 로고 색이 변경되고 웹사이트에서 변경된 색으로 확인했습니다. 그러나 오래된 로고는 여전시 웹사이트에 있습니다.
이미지 교체를 완벽하게 교체해도 문제는 캐싱이 되고 있다는 뜻입니다.
당신의 기기는 하드디스크에 캐시된 로고 버전이 있습니다. 그것은 새로운 이미지를 다운받도록 요청하지 않습니다. 그러므로 캐시가 만료되지 않는 한 새로운 로고를 얻을 수 있습니다.
유저가 하드디스크에 최신버전파일이 캐시되어 있지 않으면 여러 문제가 발생할 수 있습니다. 포맷이 안맞고, 자바스크립트가 깨지고 올바르지 않는 이미지가 나타납니다.
대부분의 경우 서버가 어떤 자산이 업데이트되고 유저 기기에서 교체되어야하는지 알고있기 때문에 문제가 되지 않습니다. 만약 일부 유저가 홈페이지가 깨졌다고 문제제기를 하면 브라우저캐시를 삭제해보라고 권하면 됩니다.
대부분의 브라우저는 ‘캐시 제거’버튼이 있습니다. 버튼을 클릭하면 캐시된 모든 파일이 삭제됩니다. 캐시를 지우고 자주 방문하던 사이트에 들어가봤을 때 로드되는 얼마나 걸리는지 확인해보세요.
브라우저는 특정 웹사이트만의 캐시를 삭제할 수 있습니다. 특정 사이트만 캐싱 이슈가 있다면 문제가 되는 사이트의 캐시를 지우고 기존 캐싱이 되어있는 사이트를 빠르고 유동적으로 사용하세요.
import { Component } from 'react';
import BooleanComponent from './03/BooleanComponent';
import ChildComponent2 from './03/ChildComponent2';
class App extends Component {
render() {
return (
<div>
<ChildComponent2 objValue={{ age: '20살' }} />
</div>
);
}
}
export default App;
age에 number가 아닌 String을 대입한 에러1과, 필수 프로퍼티로 지정한 RequiredStringVaule에 값이 전달되지 않아서 에러가 나게 됐다.
import { Component } from 'react';
import BooleanComponent from './03/BooleanComponent';
import ChildComponent2 from './03/ChildComponent2';
class App extends Component {
render() {
return (
<div>
<ChildComponent2 objValue={{ age: 20 }} requiredStringValue="문자" />
</div>
);
}
}
export default App;
수정해주니까 에러 사라짐~
컴포넌트 상태 관리하기
1. state로 상태관리하기.
import React from "react";
class StateExample extends React.Component {
constructor(props) {
super(props);
// 상태 정의
this.state = {
loading: true,
formData: "no data",
};
// 이후 콜백 함수를 다룰때 bind를 선언하는 부분에 대해 다룹니다
this.handleData = this.handleData.bind(this);
// 생성 후 4초 후에 handleData를 호출합니다.
setTimeout(this.handleData, 4000);
}
handleData() {
const data = "new data";
const { formData } = this.state;
// 상태 변경
this.setState({
loading: false,
formData: data + formData,
});
// this.state.loading 은 현재 true 입니다.
// 이후 호출될 출력함수에서의 this.state.loading은 false입니다.
}
// 다음과 같이 setState함수를 사용할 수 있습니다.
// handleData(data) {
// this.setState(function(prevState) {
// const newState = {
// loading : false,
// formData: data + prevState.formData,
// };
// return newState;
// });
// }
render() {
return (
<div>
{/* 상태 데이터는 this.state로 접근 가능합니다. */}
<span>로딩중: {String(this.state.loading)}</span>
<span>결과: {this.state.formData}</span>
</div>
);
}
}
export default StateExample;
state를 사용할 떄 주의점
: 생성자에서 반드시 초기화 해야 한다.
: state값을 변경할 떄는 setState()함수(상태관리함수)를 반드시 사용해야함
: setState()함수는 비동기로 처리되며, setState() 코드 이후로 연결된 함수들의 실행이 완료된 시점에
화면 동기화 과정을 거친다.
2. 클래스 인스턴스 변수와 forceUpdate()함수로 State관리하기
import React from "react";
class ForceUpdateExample extends React.Component {
constructor(props) {
super(props);
//state 정의
this.loading = true;
this.formData = "no data";
//이후 콜백 함수를 다룰 때 bind를 선언하는 부분에 대해 다룹니다
this.handleData = this.handleData.bind(this);
// 4초후 호출
setTimeout(this.handleData, 4000);
}
handleData() {
const data = "new data, ";
//state 변경
this.loading = false;
this.formData = data + this.formData;
// 컴포넌트 내장 함수 forceUpdate()를 호출하여 강제로 화면을 새로고침 한다.
this.forceUpdate;
}
render() {
return (
<div>
{/* 상태 데이터는 this.state로 접근 가능합니다. */}
<span>로딩중: {String(this.state.loading)}</span>
<span>결과: {this.state.formData}</span>
</div>
);
}
}
export default ForceUpdateExample;
C;
위에 것과 결과는 같지만 리액트 성능에 제약이 있으므로, 매번 새롭게 화면을 출력해야 되는 경우가 아니라면
사용하고 싶은 도메인 이름을 Check 해봅니다. ‘Free’라는 태그가 붙은 도메인은 무료이므로 사용하고 싶은 것을 고르면 됩니다. [Get it now!]를 클릭합니다. 버튼이 [Selected]로 바뀌면 발급이 완료된 것입니다.
Period 에서 무료로 사용할 수 있는 기간을 선택할 수 있습니다. 12개월을 선택 후 [Continue]를 클릭합니다.
구글 로그인으로 무료 체크아웃하기
생성된 도메인은 상단의 [Services] -> [My Domains]를 클릭하면 위와 같이 구매한 도메인을 확인할 수 있습니다.
2. Route 53 에 도메인 등록
이제 AWS 콘솔로 넘어가겠습니다. Route 53 콘솔로 들어가 [Hosted zones] -> [Create Hosted Zone]을 클릭합니다.
Domain Name에 이전에 발급받은 도메인을 기입합니다. [Create]를 클릭합니다.
생성 완료!
NS 타입과 SOA 타입의 레코드 셋이 생성되어 있는 것을 확인할 수 있습니다. NS는 네임 서버 레코드, SOA는 권한 시작 레코드입니다.
레코드 생성 버튼을 클릭해 빠른 레코드를 생성합니다.
Name 에는 하위 도메인을 설정할 수 있습니다. 여기서는 일반적으로 쓰이는 www를 사용하겠습니다. Type은 A 레코드를 선택하고 값에 인스턴스 퍼블릭 IP 주소를 입력합니다. 설정을 마쳤으면 [Create]를 클릭합니다.
레코드 생성 완료!
Record Set에 방금 생성한 A 레코드의 도메인을 확인할 수 있습니다. 하지만 여기서 끝난 것이 아닙니다. 네임서버를 이전에 발급받은 무료 도메인에 적용해 주어야 합니다.
3. 도메인 AWS Route53의 NameServer로 변경
freenom 사이트의 My Domains에서 구매한 도메인의 [Manage Domain]을 클릭합니다.
[Management Tools] -> [Nameservers] 를 클릭한 다음, Use custom nameservers (enter below)를 체크하고 Route 53 NS 레코드의 Value 값을 넣어줍니다. 전부 입력하고 [Change Nameservers]를 클릭합니다.
네트워크 전파 속도 때문에 네임서버를 변경하면 바로 적용이 안 되기 때문에 몇 분 내지는 몇 시간의 시간이 필요합니다.
위의 url 로 파라미터를 던지고 결과를 받아야 하는데 아래와 같은 오류가 발생할 것이다.
Mixed Content: The page at ‘https://page.com‘ was loaded over HTTPS, but requested an insecure XMLHttpRequest endpointThis request has been blocked; the content must be served over HTTPS.
이럴 경우 2가지의 해결 방법이 있다.
싱글페이지를 포기하고 https 주소가 꼭 필요한 부분에서만 https 주소를 사용하는 페이지로 이동을 한다.
Microsoft Windows [Version 10.0.19041.804]
(c) 2020 Microsoft Corporation. All rights reserved.
C:\Users\bit\Documents\boiler-plate>git init
Initialized empty Git repository in C:/Users/bit/Documents/boiler-plate/.git/
C:\Users\bit\Documents\boiler-plate>git status
On branch master
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
index.js
models/
node_modules/
package-lock.json
package.json
nothing added to commit but untracked files present (use "git add" to track)
C:\Users\bit\Documents\boiler-plate>
git add를 하면 소ㅑㄹ라소ㅑㄹ라~~ 라이브러리까지 다 올라감.. (staging area에)
C:\Users\bit\Documents\boiler-plate>git add .
warning: LF will be replaced by CRLF in node_modules/.bin/mime.
The file will have its original line endings in your working directory
warning: LF will be replaced by CRLF in node_modules/.bin/mime.ps1.
The file will have its original line endings in your working directory
warning: LF will be replaced by CRLF in node_modules/.bin/semver.
The file will have its original line endings in your working directory
C:\Users\bit\Documents\boiler-plate>git status
On branch master
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: index.js
new file: models/User.js
new file: node_modules/.bin/mime
new file: node_modules/.bin/mime.cmd
new file: node_modules/.bin/mime.ps1
new file: node_modules/.bin/semver
new file: node_modules/.bin/semver.cmd
C:\Users\bit\Documents\boiler-plate>git status
On branch master
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: index.js
new file: models/User.js
new file: package-lock.json
new file: package.json
Untracked files:
(use "git add <file>..." to include in what will be committed)
.gitignore
C:\Users\bit\Documents\boiler-plate>git commit -m "처음 저장소 올림"
[master (root-commit) 1540315] 처음 저장소 올림
4 files changed, 668 insertions(+)
create mode 100644 index.js
create mode 100644 models/User.js
create mode 100644 package-lock.json
create mode 100644 package.json
C:\Users\bit\Documents\boiler-plate>git status
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
.gitignore
C:\Users\bit\Documents\boiler-plate>git commit -m "깃이그노어 추가"
[master 684ec62] 깃이그노어 추가
1 file changed, 1 insertion(+)
create mode 100644 .gitignore
C:\Users\bit\Documents\boiler-plate>git status
On branch master
nothing to commit, working tree clean
C:\Users\bit\Documents\boiler-plate>
C:\Users\bit>node -v
v14.16.0
C:\Users\bit>cd documents
C:\Users\bit\Documents>mkdir boiler-plate
C:\Users\bit\Documents>cd boiler-plate
C:\Users\bit\Documents\boiler-plate>npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.
See `npm help init` for definitive documentation on these fields
and exactly what they do.
Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.
Press ^C at any time to quit.
package name: (boiler-plate)
version: (1.0.0)
description:
entry point: (index.js)
test command:
git repository:
keywords:
author:
license: (ISC)
About to write to C:\Users\bit\Documents\boiler-plate\package.json:
{
"name": "boiler-plate",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
Is this OK? (yes)