[TIL] Day60 #Browser #반응형 웹

Beanxx·2022년 7월 25일
0

TIL

목록 보기
60/120
post-thumbnail

2022.07.21(Thurs)

[TIL] Day60
[SEB FE] Day61

☑️ Browser

: 웹 서버에서 양방향으로 통신하며 다양한 컨텐츠를 열람할 수 있도록 해주는 GUI 기반의 SW 프로그램

  • 브라우저는 페이지 다운로드를 위해 응용계층의 프로토콜인 HTTP를 통해 송수신

📎 Web

: World Wide Web (= Web Browser, Web 탐색기)
인터넷 상에서 멀티미디어 정보를 HyperText 방식으로 연결하여 제공


📌 Web Browser 종류

  • Mosaic: 최초 웹 브라우저로 1993년 ‘마크 안드레센’ & ‘에릭 비나’가 개발
  • Netscape
  • Chrome

✨ 각 브라우저의 공통점 → 동작 방식 !

  1. 사용자가 선택한 자원(Resource)을 서버에 요청(Request)
  2. 서버의 응답(Response)을 브라우저에 띄움(Rendering)

✋ 자원 주소 - URL(Uniform Resource Identifier)로 구성

➰ Web Page: HTML 언어를 사용하여 작성된 문서 형태로 제공
➰ Web Site: 서로 관련된 내용으로 작성된 웹 페이지들의 집합


📌 Web 동작 원리


📎 Browser 구조

  1. User Interface (UI): User와 가장 밀접하게 맞닿아 있는 부분 (GUI 부분 통칭)

  2. Browser Engine (= Layout Engine): UI와 렌더링 엔진 사이 동작을 제어하며, DOM 구현

    게코(Gecko)모질라 재단에서 만든 브라우저 엔진FireFox
    웹킷(Webkit)KHTML에서 파생된 브라우저 엔진Safari
    블링크(Blink)Webkit에서 파생된 브라우저 엔진Chrome, Opera
    트라이던트(Trident)마이크로소프트의 브라우저 엔진Explorer, Outlook Express …
    EdgeHTMLTrident에서 파생된 브라우저 엔진
  3. Rendering Engine: 요청한 콘텐츠를 화면에 출력하는 역할

  4. Networking(통신): HTTP 요청과 같은 네트워크 호출에 사용

  5. JavaScript Interpreter(해석기) (= JS Engine): 대체로 웹 브라우저에서 이용

    Rhino- 모질라 재단이 운영하는 오픈소스 엔진
    - Java로 개발
    SpiderMonkey- 최초 JS엔진으로 넷스케이프 내비게이터 지원
    - 현재는 파이어폭스 지원
    V8- 구글이 개발한 오픈 소스 엔진
    - 구글 크롬의 JS엔진
    JavascriptCore- 애플에서 개발
    -현재 Safari & React-Native App 지원
    Chakra- 마이크로소프트가 개발한 엔진
    - Edge 브라우저 지원

    • Heap Memory: 동적 메모리 할당에 사용되는 자료구조 → 객체 / 동적 데이터 저장

      • 가비지 컬렉션이 발생하는 곳
    • Call Stack: 프로그램 상에서 우리가 어디에 있는지 기록하는 자료구조

      • JS는 싱글 스레드 기반 언어 → 콜 스택 하나 의미 → 한번에 한 작업만 사용 가능
      • 함수 실행시, 해당 함수는 콜 스택 가장 상단에 위치 ⇒ 함수 실행 끝나면 바로 제거 가능
        ✋ Stack이 후입선출 구조이므로!

      ✨ Stack Frame (호출 스택의 각 단계)

      1. Stack Push(쌓임)
      2. Stack Pop(제거): return되는 순서대로 후입선출!
      3. 해당 메소드를 실행하는 순간 Stack 내에 실행 코드 Stack이 쌓이고,
        실행이 끝나면 Stack에서 제거
      4. Stack 완전히 Empty

      ✋ 콜 스택 동작 방식에서, 함수 실행 동안 return문으로 함수 호출 외의 특정한 값이 없으면
           특정 값을 얻을 때까지 콜 스택 내부에 함수 스택 프레임이 쌓이게 됨

      ✋ Call Stack은 크기 제한이 있음 ⇒ 한정된 메모리 공간을 넘어버리면 Stack Overflow Error 발생

      ✨ Stack Overflow
      : Call Stack 내부의 동일한 Stack Frame이 예상치 못한 수로 쌓일 때 발생

      ✨ Stack trace(추적)
      : 브라우저 Console.log로 에러 발생 원인을 추적할 수 있음

  6. UI Back-end: 렌더링 엔진이 분석한 Render Tree를 브라우저에 그리는 역할

    • Command Line Interface (CLI): 명령어 라인 인터페이스
      • mac→터미널, Window→명령 프롬프르 문자로만 명령어 입력해서 처리해야 하는 인터페이스
    • Batch Interface: 일괄 처리 인터페이스
      • 사용자가 배치 작업의 모든 세부 사항을 지정하고, 모든 처리 완료시 출력을 수신하는 비대화형 사용자 인터페이스
      • 대규모 시스템의 대량 데이터 처리시 자주 사용
    • Graphic User Interface (GUI): 마우스, 키보드, 모니터 등으로 직관적인 입력이 가능한 인터페이스
  7. 자료 저장소(Web Storage): 자료를 저장하는 계층

    • LocalStorage: 보관 기한 없는 데이터 저장

      • 객체 - window.localStorage: 만료 날짜가 없는 데이터 저장시 사용
      • 브라우저 탭이 닫히거나, 컴퓨터 재부팅해도 저장소에 저장된 데이터는 사라지지 않음
      • windows 전역 객체의 localStorage 컬렉션을 통해 저장 & 조회 가능
      • 도메인마다 별도 localStorage 생성 ⇒ 같은 도메인이면 전역으로 데이터 공유 가능

    • SessionStorage: 하나의 세션만을 위한 데이터 저장

      • 객체 - window.sessionStorage: 세션이 있는 데이터 저장시 사용 (브라우저 탭 닫으면 손실되는 것을 의도한 데이터 저장시 사용)
      • 사용자가 브라우저 탭/창을 닫으면, 객체에 저장된 데이터 사라짐
      • 브라우저가 다르면 브라우저 컨텍스트가 서로 달라 sessionStorage는 각 별개의 영역으로 인지 → 서로 데이터 공유 불가능 ❌

      ✋ Browsing: 브라우저 프로그램을 실행해서 필요한 정보를 찾는 행위
      ✋ 브라우저 컨텍스트: 브라우저가 문서를 표시하는 환경 (특정 출처, 표시했던 모든 문서의 방문기록 …)



☑️ 브라우저 렌더링

✨ Rendering: 개발자가 작성한 문서가 브라우저에서 출력되는 과정

📎 렌더링 과정

  1. 사용자가 브라우저를 통해 웹 사이트에 접속
  2. 브라우저는 서버로부터 웹사이트에 필요한 리소스 다운
  3. 렌더링 엔진은 전달받은 HTML 문서를 파싱(parsing)해서 DOM Tree 생성
  4. 포함된 스타일 요소를 파싱해 CSSOM(CSS Object Model, CSS 객체 모델) Tree 생성
  5. 생성한 DOM Tree & CSSOM Tree를 결합하여 Render Tree 구축
  6. 레이아웃 과정을 통해 각 요소를 어디에 배치할지 결정
  7. UI 백엔드에서 Render Tree를 화면에 그림 👈 Paint

📎 파싱(Parsing)

: 프로그래밍 언어로 작성된 파일을 실행시키기 위한 구문 분석 단계

✨ Parser: 인터프리터 / 컴파일러 구성 요소 중 하나

HTML 파일 코드
Token(문법적 의미를 갖는 최소 단위)으로 1번 분해
→ 문법적 의미&구조에 따라 Node 요소로 바꿈
→ 상하 관계에 따라 하나의 Tree 형성 👉 Parse Tree / Syntax Tree

✋ 위에서 생성된 HTML Token에는 시작태그, 마침태그, 속성 이름&값이 포함됨

✨ Document Parsing: 브라우저가 코드를 이해하고 사용할 수 있는 구조로 변환하는 것


🌵 DOM Tree

✨ DOM(Document Object Model): HTML 문서 요소들의 중첩 관계를 기반으로 노드들을 트리 구조로 구성

브라우저는 JS 언어만 알아듣기 때문에 HTML 태그/속성 이해 X → 이해할 수 있는 형태인 객체로 변환해야 함 👉 DOM Tree

🌵 CSSOM Tree

: 브라우저가 HTML 파일 → DOM Tree로 파싱하다가 <link>, <style> 태그를 만나면 파싱을 잠시 멈추고, 해당 리소스 파일을 서버로 요청 → 요청한 파일을 파싱하여 만든 트리 👉 CSSOM Tree
→ 트리 구축 후, 다시 HTML 파일 파싱 중단 부분으로 돌아가 마저 DOM Tree 파싱 go!

✋ CSS는 부모 속성을 자식이 상속 받음!

🌵 Render Tree

: 렌더링 목적으로 만들어진 트리로, DOM Tree & CSSOM Tree를 합쳐줌

✋ 렌더링은 사용자에게 보여주고자 하는 화면을 그리는 과정이므로 보이지 않을 요소들은 렌더 트리에 포함 ❌

✨ Layout
: 렌더트리 기반으로 HTML 요소의 레이아웃을 계산하여 브라우저 화면 어디에 배치할지 결정하는 과정
- 모든 값은 절대적인 단위인 px 값으로 변환

🎨 Painting
: 계산된 pixel 정보를 바탕으로 pixel을 채워나가는 과정

📎 Reflow & Repaint

➰ Reflow: 어떠한 웹 인터렉션을 통해 렌더링 과정의 레이아웃을 반복해 수행하는 것
➰ Repaint: 페인트 과정을 반복해 수행하는 것

✋ DOM이 변경되면 렌더 트리를 다시 구축하기 때문에, 변경될 때 마다 리플로우 & 리페인트를 다시 해야 함!

✨ Frame Drop: 초당 60프레임으로 유지시키던 프레임 수가 브라우저 과부하로 인해 줄어드는 현상
👉 화면 멈춤 / 버벅임 현상 발생 → 최적화 고민 🤔

  1. 불필요한 레이아웃 줄이기
    • 리플로우보다 리페인트만 발생하는 속성 사용하는게 좋음 👍
    • 리플로우의 left 속성은 레이아웃 발생 → 위치 변경 → 프레임 유지 보장 어려움
    • 리페인트의 opacity 속성 사용시 visibility / display 보다 성능 개선에 도움!
  2. 영향을 주는 노드 줄이기
    • positionabsolute / fixed 사용 → 주변 노드 줄여줄 수 있음


☑️ 반응형 웹

: 여러 장치의 다양한 특성에 대응하는 하나의 웹 문서 / 사이트로써,
브라우저 크기에 실시간으로 반응하여 크기에 따라 레이아웃이 변하는 웹 사이트
👉 하나의 소스 코드로 모든 스크린에 최적화된 웹 사이트를 구축할 수 있는 방법론
(디바이스 종류에 따라 웹페이지 크기 자동으로 재조정)

✨ Mobile First: 사용자 경험(UX)을 디자인할 때 모바일일 경우에 최우선으로 초점을 맞춰 디자인하는 것

👍 반응형 웹 장점

  • 효율적인 유지보수: 하나의 콘텐츠에 하나의 HTML 소스만 있기 때문에 하나의 소스만 수정하면 되므로!
  • 검색엔진(SEO) 최적화 유리

👎 반응형 웹 단점

  • 사이트 속도 저하: 읽어들어야 할 소스가 많아 불필요하게 많은 데이터 소비..
  • 웹브라우저 호환성 문제

📎 미디어 쿼리

✨ 사용 방법

<!-- 1. HTML 파일의 <head> 내에 <link> 태그로 작성 -->
<link href="css파일이름.css" media="screen and (min-width: 400px) and (max-width: 1000px)" rel="stylesheet">

<!-- 2. HTML 파일의 <head> 내에 <style> 태그로 작성 -->
<style type="text/css" media="screen and (min-width: 400px) and (max-width: 1000px)">
	<!-- 여기에 css 작성 -->
</style>
/* 3. 미디어 쿼리 구문 */
@media 미디어 타입 (조건-너비/높이) {
    (CSS 입력 부분)
}

/* example */
@media screen (max-width: 400px) {
    body {
			color: red;
		}
}
  • 미디어 타입: 코드가 어떤 미디얼르 위한 것인지 브라우저에 알림
    • all: 모든 미디어 타입
    • print: 프린터
    • screen: 컴퓨터 화면
    • speech: 스크린 리더
  • 조건-너비/높이: 지정한 창의 너비나 높이를 기준으로 기준 만족시 스타일 적용, 아니면 적용 X
    • 뷰포트 너비 기능을 가장 많이 사용
    • max-width, min-width
  • CSS 입력 부분: 조건문 통과 & 미디어 타입이 올바른 경우 스타일 적용
  • 방향성: 세로 / 가로 모드인지 검사 → orientation 속성

✨ 복잡 미디어 쿼리

  • 논리곱(and): and로 미디어 기능 합치기! 모든 조건을 만족해야 스타일 적용!
  • 논리합(or): 콤마(,)로 분리하여 해당 조건 중 하나만 만족해서 스타일 적용!
  • 부정(not): not으로 반대로 적용


☑️ [pair] 반응형 웹 구현

미디어 쿼리로 반응형 웹 구현해보기 🙌

✨ 페어님과 나누어서 작업을 진행한 후, 합치는 방향으로 진행했다. 나는 Main 부분을 구현했고, 페어님은 Nav 바를 구현하셨다!
✨ 창 크기가 줄어들면 영어 글자크기가 줄어들고, 버튼 크기와 위치도 변경되며, 오른쪽 년도 숫자도 2줄에서 1줄로 변하도록 구현!!
✨ 어떤 사이트를 모티브로 구현할까 찾아보다가 반응형을 잘 보여줄 수 있는 사이트로 페어님이 선정하신 사이트를 참고하여 구현 진행!

https://kiac.kr/main 사이트 참고

// Main Component

import styled from "styled-components";
import Button from "./Button";

const BREAK_POINT_TABLET = 768;
const BREAK_POINT_PC = 1200;

const MainArea = styled.div`
  flex-direction: column;
  max-height: 864px;
  height: 100vh;
  width: 100vw;
  overflow: hidden;
  padding: 128px 0px 0 0px;
  box-sizing: border-box;
  overflow: auto;

  div.text {
    margin: 0 2rem;
    display: flex;
    flex-direction: column;

    strong {
      width: 100%;
      height: auto;
      color: black;
      font-weight: 900;
      font-size: 100px;
      line-height: 1.3;
    }

    h3 {
      line-height: 1;
      text-align: right;
    }

    span {
      text-align: right;
      letter-spacing: 20px;
      font-size: 60px;
    }

    .buttonContainer {
      text-align: right;
    }
  }

  // Mobile : 0px ~ 768px 이상
  @media only screen and (max-width: ${BREAK_POINT_TABLET}px) {
    div.text {
      strong {
        font-size: 32px;
      }

      span {
        font-size: 25px;
      }

      span::after {
        content: "22";
      }

      .buttonContainer {
        text-align: center;
      }
    }

    div.text h3:first-child {
      display: none;
    }
  }

  // 태블릿 : 768px ~ 1200px
  @media only screen and (min-width: ${BREAK_POINT_TABLET}px) and (max-width: ${BREAK_POINT_PC}px) {
    div.text {
      strong {
        font-size: 70px;
      }

      span {
        font-size: 40px;
      }

	    div.text h3:first-child { // 20 22 이 두줄로 나오는데 이 중에 22 안 보이도록!
	      display: none;
	    }

      span::after { // 위의 코드로 22 안 보이도록 처리한 후, 20 뒤에 22를 붙여 한 줄에 2022 보이도록 설정
        content: "22";
      }

      .buttonContainer {
        text-align: center;
      }
    }

  }
`;

const Render = () => {

  return (
    <>
      <MainArea>
        <div className="text">
          <div>
            <h3>
              <span>22</span>
            </h3>
            <h3>
              <span>20</span>
            </h3>
          </div>

          <div>
            <h1>
              <strong>KOREA</strong>
            </h1>
            <h1>
              <strong>INTERNATIONAL</strong>
            </h1>
            <h1>
              <strong>AQUASCAPING</strong>
            </h1>
            <h1>
              <strong>CONTEST</strong>
            </h1>
            <div className="buttonContainer">
              <Button text="Application" />
            </div>
          </div>
        </div>
      </MainArea>
    </>
  );
};

export default Render;
// Button Component

import React from "react";
import styled from "styled-components";

const BREAK_POINT_TABLET = 768;
const BREAK_POINT_PC = 1200;

const ButtonStyle = styled.button`
  font-size: 25px;
  padding-left: 44px;
  padding-right: 44px;
  padding-top: 25px;
  padding-bottom: 25px;
  letter-spacing: 0px;
  background-color: #b71327;
  color: #ffffff;
  opacity: 1;
  transition-duration: 0.7s;
  visibility: visible;
  border: none;

  &:hover {
    background-color: #0054ff;
  }

  // Mobile : 0px ~ 768px 이상
  @media only screen and (max-width: ${BREAK_POINT_TABLET}px) {
    font-size: 18px;
    padding-left: 30px;
    padding-right: 30px;
    padding-top: 15px;
    padding-bottom: 15px;
    letter-spacing: 0px;
  }

  // Tablet : 768px ~ 1200px
  @media only screen and (min-width: ${BREAK_POINT_TABLET}px) and (max-width: ${BREAK_POINT_PC}px) {
    font-size: 18px;
    padding-left: 30px;
    padding-right: 30px;
    padding-top: 15px;
    padding-bottom: 15px;
    letter-spacing: 0px;
  }
`;

const Button = (props) => {
  return <ButtonStyle>{props.text}</ButtonStyle>;
};

export default Button;
profile
FE developer

0개의 댓글