티스토리 뷰

회고

회사 홈페이지 리뉴얼 회고

이지홍 2024. 9. 10. 02:21
반응형

마이데이터 접수 + 제휴사들과의 계약을 앞두고 있는 시점 우리 회사를 소개할 페이지가 필요했다. 하지만 회사의 홈페이지가 검색 결과에서 낮은 순위에 노출되고 있어서 인지도가 떨어진다는 평가가있었고 우리 회사의 가치를 잘 나타낼 수 있는 공간인 홈페이지를 회의끝에 리뉴얼 하기로 결정이 났다. 현시점 홈페이지 리뉴얼 작업이 1차(?)적으로 마무리 되어 회고를 진행해보려 한다. 바닐라 자바스크립트에서 next로 ssg 환경의 정적페이지로 변경하면서 겪은 배포 이슈들을 중점적으로 다룰 예정이다.

💣 기존 프로젝트의 문제

검색 노출 이슈

첫번째로는 우리의 사이트가 검색이 되지 않는 문제가 있었다. 우리는 대출 금리 비교를 해주는 서비스 회사이고, 여러 금융사들과 제휴를 하기 위해서는 우리의 회사를 소개해야 하는 입장이였다. 하지만 우리 회사를 검색 했을 때 검색 순위에서 밀려서 검색 노출이 되지 않아 회사를 소개하는 데 어려움이 있었다. 이는 잠재 고객들을 확보하는데에도 문제가 있을 수 있지만, 제휴사를 늘려야하는 회사의 입장에서는 꽤나 크리티컬한 문제였다.

꼬일대로 꼬여버린 코드

처음 프로젝트를 전달 받았을때에 가장 놀랐던 부분이 무려 버전별로 다운로드 되어있던 jQuery였다. 다양한 버전의 jQuery가 혼재되어 코드 간 충돌과 간섭이 발생했고, 유지보수를 할라치면 불필요한 시간을 할애해야했다. 또한 css도 여러개로 관리되고 있었는데,이것 또한 겹치는 css코드들이 있어서 특정 CSS를 수정하면 어떤 부분에서 참조되고 있는지 파악하기 어려웠다. 결국, 하나의 CSS 수정이 전체 사이트에 영향을 미쳐 모든 부분에 일일이 적용해야 하는 상황이 빈번히 발생했다. 이러한 복잡한 구조는 개발 속도를 저하시켰고, 코드의 가독성과 유지보수성을 해쳤다.

불친절한 UI

기존의 UI는 사용자 친화적이지 못했고, 이로 인해 회사 내에서 다른 서비스들에 비해 신뢰도가 떨어진다는 평가를 받았다. 디자인과 사용자 경험이 일관되지 않아 사용자가 원하는 정보를 찾기 어려웠고, 이는 우리 서비스의 유입 전환율 저하로 이어졌다. 직관적이지 않은 인터페이스는 사용자에게 혼란을 주었고, 결국 서비스의 전체적인 신뢰도와 만족도를 낮추는 결과를 초래한것이다.

느린 페이지 로딩 속도(Feat.어마어마한 번들 사이즈)

버전별로 다운로드 된 jquery들과, 이제는 사용하지 않는 javascript 코드 뭉치 잔해들이 남아있어, 꽤나 무겁게 번들 사이즈를 차지하고 있었다. 그리하여 페이지를 접근했을때 흰 화면으로 회사의 첫 페이지를 마주할 수 있었다.

페이지가 2초 이내에 로딩되는 페이지의 평균 이탈률이 9 %를 보이지만, 페이지 로딩 시간이 3초를 넘기자마자 이탈률이 치 솟아 5초가 되면 38% 에 달한다. 이처럼 웹사이트의 로딩 속도는 고객획득에 영향을 크게 주게 된다.

toss-slash21

위의 문제들과 현재 상황을 고려해 봤을때 제휴사 계약으로 인해 리뉴얼이 최대한 빠른 시일내로 이루어져야한다는 점을 고려했다. 기존의 프로젝트를 고치는 것 보다 아예 새로운 프로젝트를 만드는게 더 시간적, 비용적인 측면에서 낫다는 판단이 나왔다. 그리하여 나는 개발 환경 중에서 가장 익숙한 리액트와 SEO 호환성이 뛰어난 프레임워크에 대해 생각했고, 이에 적합한 Next.js를 선택하게 되었다. 물론 React로도 성능 최적화를 할 수 있지만, Next.js는 이러한 최적화 작업을 더 쉽게 해주고, 특히 SSG를 통해 정적 페이지를 생성하여,빠른 로딩 속도와 SEO 성능을 크게 향상시킬 수 있다는 점이 매력적이었다.

웹 렌더링 방식 (SSR, CSR, SSG) 비교
https://im-developer.tistory.com/227

 

💎 개선 & 결과

SEO 성능 개선

회사 홈페이지가 검색 순위에 노출되지 않는 문제를 웹사이트 취약성 분석을 통해 보안 점수를 D에서 B로 올려 SEO 성능을 개선했다.

또한 페이지 로딩 시간을 최적화하여 사용자 체감 속도를 평균 20% 향상시켰으며, 이로 인해 전환율을 20% 증가시키고 총 노출을 33.8% 증가시켰다.

결과적으로, 네이버 검색창 등에서 회사명 검색 순위가 38위에서 2위로 상승하는데 성공!! 

 

코드 중복 최소화

이전의 프로젝트에서는 대출 상품들의 일일이 페이지가 생성이 되어있었다. 즉 재사용되는 코드들임에도 불구하고 데이터만 다른 같은 모양의 10개씩 만들어져있는 상황이었다.

이는 꽤나 여러가지의 문제들을 야기했는데 우선 유지보수의 어려움이다. 만약 UI가 추가되거나 수정한다고 치면 모든 페이지를 일일이 업데이트 해주어야해서 시간과 노력 부분에 있어 효율적이지 않다.

또한 똑같이 수정한다고 해도 실수로 인해 오류가 생길 확률이 더 커진다. 새로운 대출 상품이 추가 되었을때 매번 HTML 파일을 생성하고 연결해야하는 확장성의 제한 문제, 서버 자원 낭비 등의 문제가 있다. 그리하여 재사용하는 컴포넌트들을 구조화하여 이를 해결했다.

 

위에는 개선된 컴포넌트의 모양이다. 상세페이지를 동적라우팅해주어 상품의 id값이 일치하는 데이터를 상세페이지에 뿌려주었다.

또한 상세페이지 내에서도 중복되거나 다른 홈페이지들과 중복되는 코드들을 컴포넌트로 모듈화하여 하나의 컴포넌트로 만들고 변경되는 데이터들만 바인딩이 되도록 하여 중복 코드를 최소화 하였다.

export default function ServicesPage() { 
 <Head> <title>이지픽 - 나에게 유리한 대출 조건 추천, 저금리 금융상품 추천</title> </Head> 
 <PageBanner title="신용대출상품" content="쉽고 빠른 나만의 대출상품 찾기" /> 
 <Services /> 
}
export default function Services() { 
 <section> 
  <div> 
   <h3>상품 알아보기</h3> 
   {serviceLists.map((service) => ( 
    <div key={service.id}> 
     <SingleService service={service} /> 
    </div> 
   ))} 
  </div> 
 </section> 
}
export default function SingleService({ service }) { 
 const id = service.id; 
 <div> 
  <div> 
   <img src={service.img} alt="아이콘" /> 
  </div> 
  <div> 
   {service.tag.map((item, index) => ( 
    <span key={index}>{item}</span> 
   ))} 
   <Link href={`/services-details/${id}`}> 
    <a> 
     자세히보기 <BsArrowRight /> 
    </a> 
   </Link> 
  </div> 
 </div> 
}

직관적인 UI로 개선

리뉴얼 작업을 진행하면서, 주된 목적은 UI/UX를 개선하여 사용자 경험을 향상시키는 것이었다. 이 리뉴얼은 위에서도 말했듯 제휴사들과의 계약을 앞두고 있기 때문에, 우리 회사의 홈페이지를 접하면서, 사용자의 입장에서 보다 편리하고 유용한 경험을 제공하려는 노력을 반영하려 했다. 회사 내에는 전문 디자이너가 부재해서 직접 디자인했다.

제휴 문의 페이지

리뉴얼을 통해 사용자 경험을 개선했던 중 가장 주목할 만한 부분 중 하나는 제휴 문의 페이지의 변화다.해당 화면은 제휴 문의 페이지는 제휴업체들의 문의가 들어올 중요한 페이지이다.

제휴 문의 페이지는 중요한 페이지로, 이전에는 문의하기버튼 클릭 →모달창 열림 → 이메일을 복사 버튼 클릭 → 이메일 보낼 사이트로 이동 → 이메일을 붙여넣기 → 문의 등의 사용자가 여러 단계를 거쳐야 하는 비효율적인 UI 구조였다. 이를 개선하여 이메일 복사 기능을 이메일 보내기로 변경해 클릭 한 번으로 이메일을 보낼 수 있도록 했고, 회사의 위치 정보도 직관적으로 제공하여 사용자 편의를 높였다.

회사 소개 페이지 & 대출 상식 페이지

회사 소개 페이지는 단순한 텍스트 나열에서 벗어나, 주요 서비스들을 슬라이드 형식으로 시각적으로 표현했다. 대출 상식 페이지는 썸네일과 글 요약을 추가하여 사용자들이 빠르게 내용을 파악할 수 있도록 개선했다.

상품 소개 페이지

대출 상품 소개 페이지에서 사용자들이 우리의 서비스를 어디에서나 쉽게 이용할 수 있도록, 모든 페이지에 서비스로 이동할 수 있는 버튼을 추가했다. 사용자가 페이지 스크롤을 따로 할 필요 없이, 한 번의 클릭으로 서비스로 이동할 수 있도록 하여 사용자 경험을 개선했다.

대출 상품 소개 페이지는 우리와 제휴하고 있는 금융사들에서 제공하는 대출 목록들을 설명하고 있는 페이지 이다. 이는 사용자들에게 우리가 제공하는 대출의 종류를 설명하고, 알맞은 상품을 선택하도록 도와드리는 페이지 이기 때문에 이 또한 중요한 사안 중 하나였다. 이전 버전과의 비교를 통해 주요 개선 사항을 자세히 살펴보자.

이전 버전 (기존 페이지)

이전 버전의 대출 상품 소개 페이지는 대출 상품 소개와 대출 계산기가 하나의 페이지에 혼합되어 있었다. 이는 모바일 웹으로 보았을때에는 계산기가 먼저 보이는 식이라 대출 상품을 보기위해서는 스크롤을 내리는 동작을 해야만 사용자들이 원하는 정보를 찾을 수 있어,사용자들에게 어려움을 겪을 수 있게 했다. 또한 페이지 상단에는 우리 서비스를 이용할 수 있는 경로가가 부재했으며, 대출 상품 정보가 명확하게 제시되지 않았다. 그리고 대출 상품을 선택한 후에는 상세 정보 페이지로 어떻게 이동해야 하는지에 대한 명확한 안내가 부족했다.

개선된 버전 (새로운 페이지)

새로운 버전에서는 대출 상품 소개와 대출 계산기를 별도의 페이지로 분리하여 제공하도록 개선했다. 이로써 사용자들은 이 두 가지 핵심 정보를 더 명확하게 이해하고 탐색할 수 있도록 했다. 또한, 상단에 우리 서비스를 이용할 수 있는 버튼을 추가하여 사용자들이 원하는 대출 상품을확인하고 바로 대출 서비스로 빠르게 이동할 수 있도록 개선했다. 그리고 최저금리를 강조함으로써 사용자들은 한눈에 대출 상품을 비교할 수 있도록 하고, "더보기" 화살표를 통해 사용자가 대출 상품에 대한 자세한 정보를 확인하고 선택할 수 있도록 했다.

이번 홈페이지 리뉴얼을 통해 회사 소개 페이지가 단순한 정보 제공이 넘어서서 사용자들에게 더욱 흥미로운 경험을 제공하고, 회사의 핵심 서비스에 대한 이해를 높이고자 노력했다.. 위의 변경은 사용자들의 만족도를 향상시키고, 회사에 대한 관심을 높이며, 웹사이트를 방문한 사용자들이 더 많은 서비스를 탐색하도록 격려하는 데 기여했길 바라며 미비하지만 이러한 개선으로 조금이라도 유입 수를 늘릴 수 있을것을 기대한다.

🚨 어려움 & 해결 방안 

라이브러리들간의 버전 충돌

Lockfile was successfully patched, please run "npm install" to ensure @next/swc dependencies are downloaded

Build error occurred
Error: Export encountered errors on following paths:
/news-detail/[id]
/news-details
/notice-detail/[id]
/services-details/[id]
at C:\\Users\\C\\Works\\homepage-v3\\node_modules\\next\\dist\\export\\index.js:398:19
at runMicrotasks (<anonymous>)
.....

@next/swc 는 리액트 17버전을 선호하고 있어서 다운그레이드 작업을 했다. React-tabs 는 현재 5.x버전이었는데 리액트 18버전을 선호하고 있어서 17버전과 호환이 가능한 4.x 버전으로 다운그레이드 했다.

배포 과정에서 만난 에러

next를 배포하는 방식에는 두가지가 있는데, 

vercel같은 서버리스 플랫폼에 배포하는 방법 VS 웹호스팅 서비스에 정적 빌드파일을 배포하는 방법

나는 카페24의 정적 호스팅에 배포를 해야했기때문에 next build && next export로 빌드된 next js 페이지들을 정적으로 추출하여정적 빌드파일로 만들어서 배포를하는 방식을 선택했다. 배포는 아파치 서버에서 진행했다.

. . .

개발은 완료했고 배포가 성공적으로 마무리 되었다!!

음…..??

분명 로컬에서는 잘 됐는데 서버에서 화면이 안나온다.

우선 빠르게 이전 배포 버전으로 돌리고 문제가 뭔지 살펴봤다.

1️⃣ Image loader 설정 

위의 문제들은 경로 수정이 되지 않아 몇가지의 script 파일, 이미지 파일들을 찾을수 없어 페이지 렌더시 오류가 발생했다. 찾아보니 next를 정적배포하기위해 export 시도할 경우 next.config.js에 images의 loader 설정을 해주면 된다고 한다. Custom Loader를 활용하여 설정할 수 있다고 한다.

그리하여 next.config.js에서 loader를 akamai 사용해서 로더 설정을 해주니 해결됨!

2️⃣  trailingSlash , rewrite과 redirection 설정

배포 후에 메인페이지를 제외한 하위경로로 이동했을 때 새로고침하면 페이지를 404를 반환하고 있었다. 찾아보니 서버와 next.config.js에서 rewrite 설정을 따로 해줘야 했다. 로컬로 실행했을때 해당 문제가 없었던 이유는 로컬에서는 rewrite를 자동으로 잡아주기 때문에 문제가 생기지 않았던 것뿐이라고 ,,!

우선 trailingSlash 설정을 해주었다. trailingSlash는 주소 끝에 슬래시를 붙이겠다는건데 이건 디렉토리 즉 폴더라는 의미이고, 없다면 여기가 끝, 파일이라는 것을 의미한다.

💡 서버의 동작처리 과정
1. 해당 이름의 디렉토리를 확인한다.
2. 디렉토리가 있으면, 그 안의 기본파일(index.html)을 확인한다.

서버의 동작처리 과정이 위와 같다고 했을때, 위의 설정을 함으로써 파일 확인을 하는 동작을 생략할 수 있으므로 SEO, 페이지 측면에서 약간의 이득이 있다.

3️⃣ pre-rendering 이슈

CSR인 리액트에서는 에서는 useRouter를 이용하여 path와 param 정보를 얻어내 param과 일치하는 데이터 혹은 useEffect를 통해 서버에 자원을 요청하는 방식으로 데이터를 패칭했다.

그러나 서버사이드에서는 특정 dynamic route로 이동했을 때의 데이터를 pre-rendering을 해야하는데 이것을 해주지 않아서 생긴 이슈였다!서버사이드에서는 param에 있는 값을 이용해서 업데이트를 해야 하는데, 이때 필요한 것이 getStaticPaths, getStaticProps이다.

getStaticProps 함수는 주로 정적 생성된 페이지에서 데이터를 가져올 때 사용되는 것이다. 여기서는 부모 컴포넌트와 자식 컴포넌트가 정적으로 내보내질 것이고, 이 컴포넌트들이 데이터를 필요로 하는 경우에 자식 컴포넌트에 getStaticProps를 사용하는 것이 일반적으로 권장된다.

아래는 두 컴포넌트에서 getStaticProps를 적용한 코드이다.

기존 방식

// Services Component
export default function Services() {
 return (
  <section>
   <div className="container">
	<h3>상품 알아보기</h3>
	<div>
	 {serviceLists.map((service) => (
	  <div key={service.id}>
	   <SingleService service={service} />
	  </div>
	 ))}
	</div>
   </div>
  </section>
 );
}
// SingleService Component
export default function SingleService({ service }) {
 return (
  <div>
   <div>
    <img src={service.img}/>
   </div>
   <div>
    <h4>{service.apple}</h4>
	<p>{service.name}</p>
	<h1>{service.min}%</h1>
	<h2>최대 {formattedPrice}만원</h2>
    <div>
	 {service.tag.map((item, index) => (
	  <span className="tag" key={index}>{item}</span>
	 ))}
	</div>
	<Link href={`/services-details/${service.id}`}>
	 <a> 자세히보기 <BsArrowRight /> </a>
	</Link>
	</div>
   </div>
  );
}

getStaticProps 적용

export default function ServicesDetails({ data, bank }) {

  return (
    <>
      <ServiceCard data={bank} />
      <ServiceDetail data={data} bank={bank} />
    </>
  );
}
export const getStaticProps = async (context) => {
  const id = context.params.id;
  const matchList = serviceLists.find((item) => item.id === id);
  const matchData = serviceDetails.find((item) => item.id === id);

  if (!matchList || !matchData) {
    return { notFound: true };
  }
  return {
    props: {
      bank: matchList,
      data: matchData,
    }
  }
}

위의 코드에서 getStaticProps 함수를 사용하여 데이터를 가져온 다음, 해당 데이터를 Services 컴포넌트의 props로 전달한다. Services 컴포넌트와 SingleService 컴포넌트가 정적 페이지로 내보내지면 이 데이터는 빌드 시에 정적으로 렌더링된다.

데이터를 가져오는 부분에서 실제 데이터를 가져오는 비동기 로직을 구현해야 한다. 위의 예제에서는 serviceLists 변수를 사용하여 목데이터를 가져왔다.

4️⃣ 프록시 설정

서버가 next경로를 못읽어와서 포트충돌로 인해 서버가 계속 다운되는 이슈가 있어 프록시 설정까지 완료!

 

🥅 마무리

홈페이지 리뉴얼을 진행하면서 NEXT.js를 공부하고 프로젝트를 진행해야 하는 어려움이 있었다. 이 과정에서 프레임워크의 사용에 미숙한 부분으로 인해 몇몇 시행착오가 있었지만, 마지막 단계에서 홈페이지를 완성하고 배포하는 과정에서 팀원분들이 큰 도움을 주셨기에 잘 마무리 할 수 있었다! 다시한번 팀원분들께 감사의 인사를 전합니다.

 

참고 
https://velog.io/@chloedev/Next.js-에러-기록-getServerSideProps-Export-Error-w-Pre-rendering
https://velog.io/@chltjdrhd777/Next.js-getStaticPaths
https://www.youtube.com/watch?v=NLMf_ex9onc&t=127s
https://rocketengine.tistory.com/entry/Next-JS-배포-방법-3가지-소개
https://wikidocs.net/197690
반응형

'회고' 카테고리의 다른 글

항해 플러스 프론트엔드 후기  (0) 2024.05.18
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함