CSS로 브라우저 성능을 최적화 시킬 수 있는 방법에 적어볼건데,
animation 최적화 와 미디어쿼리 최적화에 대해서 알아보려한다.
먼저 animation 최적화에 대해서 알아보자.
animation 최적화는 왜 해야하는 걸까?
애니메이션은 브라우저에서 많은 리소스를 사용하므로 최적화가 필요하다.
특히, 복잡한 애니메이션이나 많은 엘리먼트를 애니메이션으로 처리하면
브라우저 성능에 부정적인 영향을 미칠 수 있다.
따라서, 애니메이션을 최적화하여 브라우저의 성능을 향상시키는 것이 좋다.
그러면 animation 최적화 하는 방법은?
애니메이션을 최적화하는 방법에는 여러 가지가 있다.
첫째로, animation 사용 시에 CSS로 최적화하는 방법이 있다.
먼저 GPU 를 활용해볼건데,
GPU(Graphic Processing Unit)는 그래픽 처리를 전담하는 하드웨어이다.
따라서, GPU를 활용하면 브라우저에서 애니메이션이 더 부드럽게 동작할 수 있다.
만약 GPU를 활용하지 않는다면,
브라우저가 애니메이션을 처리하기 위해서는 CPU를 사용해야 하는데,
CPU를 사용하는 것이 문제가 되는 것은 아니지만
애니메이션 처리에는 CPU가 아닌 GPU를 사용하는 것이 더 효율적이다.
그러므로, 브라우저에서 애니메이션이 더 부드럽게 동작하게 하려면 GPU를 활용해야 한다.
GPU를 활용하는 방법으로는 다음과 같은 것들이 있다.
1. GPU 가속 활용하기 (특정 속성들 사용)
-
- transform
- opacity
- filter
- will-change
will-change는 애니메이션 되기 전에 해당 엘리먼트가 어떤 속성을 변경할 것인지 브라우저에 미리 알리는 역할을 한다.
이를 통해 브라우저는 해당 속성을 GPU에서 처리할 수 있도록 최적화한다.
will-change를 사용하는 예시는 다음과 같다.
.element {
will-change: transform;
transition: transform 0.3s ease;
}
.element:hover {
transform: translateX(10px);
}
위 예시에서는 .element 엘리먼트에 will-change 속성을 사용해서
transform 속성을 변경할 것임을 브라우저에 미리 알리고 있다.
또한, transition 속성을 사용하여 애니메이션의 지속 시간과 타이밍 함수를 설정하고 있다.
이를 통해 브라우저가 해당 속성을 GPU에서 처리할 수 있도록 최적화하고 있다.
2. 리플로우 최소화하기
리플로우에 관한 건 https://oreeyo00.tistory.com/7 를 참고하면 좋다.
애니메이션 엘리먼트가 추가될 때, 브라우저는 리플로우(reflow)를 수행하여 레이아웃을 다시 계산한다.
이 때문에 브라우저의 부하가 증가하게 된다.
이를 최소화하기 위해서는 다음과 같은 방법들을 사용할 수 있다.
- position: absolute 또는 fixed를 사용하여 엘리먼트를 배치
- transform을 사용하여 엘리먼트의 위치를 변경
- will-change를 사용하여 리플로우가 발생할 엘리먼트를 GPU에서 처리
3. requestAnimationFrame 함수 활용하기
requestAnimationFrame 함수는 브라우저가 애니메이션 업데이트를 수행할 때,
가능한 최대의 프레임 속도로 처리합니다. 이를 통해 애니메이션의 부드러운 동작을 보장할 수 있다.
function update() {
// 애니메이션 업데이트 처리
setTimeout(anotherFunction, 0);
requestAnimationFrame(update);
}
requestAnimationFrame(update);
requestAnimationFrame 함수를 사용할 때 주의해야 할 점은, 이 함수 내에서 다른 함수를 호출하면 안 된다는 것 이다. requestAnimationFrame 함수는 브라우저가 업데이트를 수행하기 전에 호출되기 때문에,
이 함수 내에서 다른 함수를 호출하면 브라우저가 업데이트를 수행하기 전에 이 함수가 실행될 수도 있다.
따라서, requestAnimationFrame 함수 내에서 다른 함수를 호출하려면,
이를 setTimeout 함수 내에서 처리하는 것도 좋은 방법이다.
anotherFunction 함수는 setTimeout 함수 내에서 호출되며, 0ms 이후에 실행된다.
이를 통해 브라우저가 업데이트를 수행하기 전에 anotherFunction 함수가 실행되는 것을 방지할 수 있으며,
requestAnimationFrame 함수를 사용하면서, 브라우저의 성능을 최적화하면서 애니메이션을 구현할 수 있다.
두번째로, transform 사용 시에 3D를 사용하는 것이 애니메이션 최적화를 시켜준다.
transform 속성에 rotateX, rotateY, rotateZ 등을 사용하면 3D 효과를 적용할 수 있다. 이를 사용하는 이유는 다음과 같다.
- 3D 효과를 적용할 수 있어서 보다 다양한 표현이 가능해진다.
- 3D 효과를 적용하면 브라우저가 GPU를 활용하여 처리할 수 있기 때문에 성능이 향상된다.
예를 들어, 다음과 같은 CSS 코드에서 .box 엘리먼트에 transform: rotateY(45deg)를 적용하면 3D 효과를 적용할 수 있다.
이를 통해 브라우저가 GPU를 활용하여 성능을 최적화한다.
.box {
transform: rotateY(45deg);
}
그 다음에는 미디어쿼리 최적화에 대해서 알아보겠다.
미디어쿼리 최적화 또한 왜 필요할까?
미디어쿼리는 뷰포트의 크기에 따라 CSS를 변경하는 방식으로 동작한다.
이 때, 브라우저는 뷰포트의 크기가 변경될 때마다 미디어쿼리를 해석하고, 해당하는 CSS 규칙을 적용한다.
이 때문에, 미디어쿼리를 많이 사용하면 브라우저의 성능이 저하될 수 있다.
따라서, 미디어쿼리를 최소화하여 사용하는 것이 좋다.
예를 들어,
모바일 환경에서는 모바일 전용 CSS를,
데스크탑 환경에서는 데스크탑 전용 CSS를 사용하는 등
필요한 최소한의 미디어쿼리만 사용하도록 하자.
반응형 작업 시에 미디어쿼리를 최소화로 쓰는 방법
반응형 작업 시에 미디어쿼리를 최소화하려면 다음과 같은 방법들을 사용할 수 있다.
- rem 등 상대적인 단위 사용하기
rem은 상대적인 단위로, 브라우저의 기본 폰트 크기를 기준으로 크기를 조절한다.
이를 사용하면 브라우저의 폰트 크기 변경에도 자동으로 대응할 수 있다.
다음은 rem을 사용하여 미디어쿼리를 최소화하는 예시이다.
/* 기본 폰트 크기를 16px로 설정 */
html {
font-size: 16px;
}
/* 768px 이상의 화면에서는 컨테이너의 너비를 960px로 설정 */
@media (min-width: 768px) {
.container {
width: 60rem; /* 60rem = 960px */
}
}
/* 480px 이상 768px 미만의 화면에서는 컨테이너의 너비를 100%로 설정 */
@media (min-width: 480px) and (max-width: 767px) {
.container {
width: 100%; /* 100% */
}
}
/* 480px 미만의 화면에서는 컨테이너의 너비를 100%로 설정하고, 아이템을 세로로 배치 */
@media (max-width: 479px) {
.container {
width: 100%; /* 100% */
flex-direction: column;
}
}
위 예시에서는
html 요소의 font-size를 16px로 설정하고,
rem을 사용하여 미디어쿼리를 구현하고 있다.
rem은 기본 폰트 크기를 기준으로 크기를 조절하기 때문에,
브라우저의 폰트 크기 변경에도 자동으로 대응할 수 있다.
- CSS 그리드 레이아웃 사용하기
CSS 그리드 레이아웃을 사용하면 미디어쿼리를 사용하지 않아도 반응형 레이아웃을 구현할 수 있다.
예를 들어,
다음과 같이 grid-template-columns 속성과 grid-template-rows 속성을 사용하여 그리드의 열과 행의 크기를 설정하고,
grid-template-areas 속성을 사용하여 그리드 영역을 지정할 수 있다.
.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 1fr);
grid-template-areas:
"header header header"
"sidebar content content"
"footer footer footer";
}
.header {
grid-area: header;
}
.sidebar {
grid-area: sidebar;
}
.content {
grid-area: content;
}
.footer {
grid-area: footer;
}
위 예시에서는
.wrapper에 display 속성을 grid로 설정하고,
grid-template-columns 속성과 grid-template-rows 속성을 사용하여 그리드의 열과 행의 크기를 설정하고 있다.
또한, grid-template-areas 속성을 사용하여 그리드 영역을 지정하고 있다.
이렇게 하면 브라우저의 크기에 따라 그리드의 크기와 배치가 자동으로 조절되므로,
미디어쿼리를 사용하지 않아도 반응형 레이아웃을 구현할 수 있다.
- flexbox 사용하기
flexbox를 사용하면 미디어쿼리 없이도 반응형 레이아웃을 구현할 수 있다.
예를 들어,
다음과 같이 flex-wrap 속성을 사용하여 브라우저의 크기에 따라 아이템이 한 줄에 표시될지,
여러 줄에 걸쳐 표시될지를 결정할 수 있다.
.container {
display: flex;
flex-wrap: wrap;
}
.item {
width: 100px;
height: 100px;
margin: 10px;
}
위 예시에서는
.container의 display 속성을 flex로 설정하고,
flex-wrap 속성을 wrap으로 설정하여,
.item이 너비를 벗어날 경우 자동으로 다음 줄로 넘어가도록 설정하고 있다.
이렇게 하면 브라우저의 크기에 따라 .item의 배치가 자동으로 조절되므로,
미디어쿼리를 사용하지 않아도 반응형 레이아웃을 구현할 수 있다.
'개발 > CSS(SCSS)' 카테고리의 다른 글
position : absolute 와 position : relative 의 차이점 (0) | 2023.03.13 |
---|---|
오늘의 TIL (float 속성과 <p> 태그의 특징) (0) | 2023.03.07 |
CSS 선택자에도 우선순위가 있다 (0) | 2023.03.02 |
개발 블로그
포스팅이 좋았다면 "좋아요❤️" 누르기 !