본문 바로가기
내일배움캠프 TIL

2023-11-03 본 캠프 22일차 / 41일차 TIL (background-attachment 문제해결)

by KMS_99 2023. 11. 4.

2023-11-03 본 캠프 22일차 / 41일차 TIL

주요진행사항

- 리액트 강의 수강 (유데미)

- 알고리즘 강의 수강 및 풀이 (인프런)

- 리액트 개인프로젝트 validtation check 및 vercel 배포


1. 알고리즘 반복문 탈출 시 label 이용

 

알고리즘 문제를 풀면서 중첩된 반복분을 탈출해야하는 경우가 생겼다.

이 때 1차적으로 내부 반복문에서 break를 하고 조건을 주어 2차적으로 외부 반복문에서 break를 해줬어야 했다.

let flag = 0;

for (let i =0; i<n; i++){
	for (let j=0; j<n; j++){
    	if(조건){
        	flag++;
        	break;
        } 
    }
    if (flag===1) break;
}

물론 이런 방식으로 조건문을 탈출해도 된다.

하지만 조건문을 탈출하기 위해 flag라는 변수를 사용하고, 두번에 break를 사용하게 되었다.

만약 좀더 복잡한 로직이라면 코드의 가독성이 떨어질 수도 있다.

 

이 방식을 조금더 개선하고자 검색을 진행하였고 label 개념을 확인하였다.

label은 스코프에 이름을 지정하는 것으로 외부 스코프에 이름을 지정한다면 내부 반복문에서도 외부 반복문을 종료시킬 수 있다.

 

outer:for (let i =0; i<n; i++){
	for (let j=0; j<n; j++){
    	if(조건){
        	outer break;
        } 
    }
}

같은 용도의 코드지만 훨씬 가독성이나 효율성이 올라 간 것을 볼 수 있다.

물론 알고리즘을 풀이하면서 최대한 중첩반복문을 피해야겠지만, 사용했을 시에는 label을 이용하여 반복문을 종료하는 것도 좋은 방법인 것 같다.



2. 알고리즘 RegExp, string.match()

 

String.prototype.math() 메서드는 문자열이 정규식과 매치되는 부분을 검색하는 역할을 한다.

 

여기서 정규식이란,

프로그래밍에서 문자열을 다룰 때, 문자열의 일정한 패턴을 표현하는 일종의 형식언어를 뜻한다.

 

프로그래밍을 하면서 정규식은 자주 사용하는 개념중 하나이다.

 

RegExp 생성자 함수는 이 정규식 인스턴스를 만드는 역할을 한다.

사용법은 다음과 같다.

let reg = new RegExp(패턴, 플래그);

 

정규표현식의 패턴은 다음 사이트에서 검색하여 사용하면 되겠다.

 

정규 표현식 - 나무위키

자바스크립트의 문자열에서 URL을 찾는 정규표현식의 예제는 다음과 같다. /(http|https|ftp|telnet|news|mms):\/\/[^\"'\s()]+/i 위 정규식은 아래와 같이 구분이 된다. /(http|https|ftp|telnet|news|mms):\/\/[^\"'\s()]+/i

namu.wiki

 

추가로 플래그이다.

플래그는 검색에 영향을 주는 요소로 총 6개의 플래그가 존재한다

 

g (global, 전역 판별) : 문자열 전체를 검색하여 모든 일치를 반환

i (ignore case, 대소문자 무시) : 대소문자 구분없이 검색

m (multiline, 여러줄) : 다중 행을 검색

s (dotAll) : (.)이 \n도 포함하도록 활성화

u (unicode) : 유니코드 전체를 지원

y (sticky) : 문자열 내 특정 위치에서 검색을 진행

 

원하는 플래그를 함께 사용한다면, 원하는 결과값을 얻는데 큰 도움이 될 것이다.

 

이렇게 선언한 정규식 인스턴스는 string.match와 연계하여 string 내부에서 원하는 결과값을 반환 받을 수 있다.

const reg = new RegExp(`[A-Z]`,'g');

const result = 'AbcDEFFg'.match(reg);
console.log(result); // ['A', 'D', 'E', 'F', 'F']

 


3. 개인프로젝트 background-attachment 개선

 

문제 발생

프로젝트의 백그라운드 이미지를 고정하기 위해서 

background-attachiment : fixed 속성을 활용하였다.

이 속성을 사용했을 때 스크롤이나 내부 요소들의 이벤트에 딜레이가 생기는 것을 확인하였다.

 

가장 큰 문제는 내부요소의 위치 변경이다.

backgound-attachiment : fixed를 사용시 스크롤 이벤트를 할 때 background가 고정된 모습으로 보여야한다.

이렇게 동작하기 위해서 내부 콘텐츠들의 위치를 계속 변경시켜 다시그린다.

background-attachiment : fixed를 사용하지 않을 시
backrgound-attachiment : fixed를 사용할 시

background-attachiment:fixed 속성을 테스트하기 위해 각각의 상태에서 10초간 스크롤이벤트를 실행하여 크롬 개발자 도구의 성능테스트를 진행 한 결과 다음과 같은 유의미한 결과가 나왔다.

background-attachiment: fixed의 동작을 위해서 내부 요소들의 페인팅이 계속 일어나는 것을 확인 할 수 있다.

 

추가로 오류 테스트 시 windows 환경에서는 위와 같은 문제가 발생하였고 mac에서는 괜찮은 모습을 보였는데, 

그 이유는 iOS에서 이 기능의 성능 문제로 속성을 무시했기 때문이다.

 

문제 해결

문제를 해결하기 위해서 background-attachiment 속성을 대체하여, body에 ::before를 통해 가상요소를 추가하였다.

해당 가상요소에 positon : fixed 속성을 주어 background-attachiment : fixed 처럼 동작하게 구성하였다.

body::before {
  content: "";
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  z-index: -1;
  background: url("/public/image/background.png");
  background-position: center;
  background-size: cover;
}

/* body {
  background: url("/public/image/background.png");
  background-position: center;
  background-size: cover;
  background-attachment: fixed;
} */

 

느낀점

사실 문제가 발생하였을 때 CSS 의 문제라고 생각하지 못했다. 리액트를 처음 사용하면서 구조상 문제를 일으켰구나 생각을 했었다. 이 문제를 해결하고나서 CSS 요소도 페이지에 엄청난 영향을 미친다는 것을 깨달았다.

앞으로는 CSS를 작성할 때도 좀더 효율적인 코드를 찾도록 계속해서 고민하고 연구해봐야겠다.

 

참고 문헌

https://www.fourkitchens.com/blog/article/fix-scrolling-performance-css-will-change-property/

 

Fix scrolling performance with CSS will-change property - Four Kitchens

I recently saw Paul Lewis' screencast demonstrating how trivial it can be to fix a particular kind of performance issue caused by scrolling. I knew the problem looked familiar and I realized it was happening right in my front yard, on the Four Kitchens hom

www.fourkitchens.com