프런트엔드 성능 최적화 소개 및 일반적인 방법(2)

루틴이 없는 프론트엔드 블로거입니다. 온갖 프론트엔드 지향 작업에 관심이 많습니다. 생각나는 대로 글을 자주 씁니다. 기술과 프론트엔드 효과에 관심이 있으시면 메시지를 남겨주세요~ 블로거 그것을 본 후에 모두를 위해 구덩이를 밟을 것입니다 ~

홈페이지 : 올리버 인 홈페이지

좌우명 : 넘어지면 일어나라~

목차

I. 소개

2. 이 글의 내용 개요

3. 성능 최적화

3.1 로딩 성능 최적화

3.2 빌드 최적화

3.2.1 자바스크립트 압축

3.2.2 CSS 압축

3.3 렌더링 최적화

3.3.1 역류 감소

3.3.2 레이아웃 수 줄이기

3.3.3 흔들림 방지 및 조절

3.4 캐시 성능 최적화

3.4.1 브라우저 캐시

V. 요약


I. 소개

최근 저희 회사의 소규모 파트너들이 프로젝트에서 성능과 관련된 몇 가지 문제에 부딪혔기 때문에 프런트엔드 성능 최적화 방법에 대해 논의하고 일일 학습 노트도 일부 정리하여 정리한 후 이런 글을 갖게 되었습니다~

인내심을 갖고 읽어보시면 뭔가 얻으실 수 있을 거예요~

2. 이 글의 내용 개요

이 문서에서는 먼저 일상적인 개발에서 발생할 수 있는 몇 가지 성능 최적화 지점이나 방법을 구체적으로 공유합니다. 난이도: 중급 ;

3. 성능 최적화

3.1 로딩 성능 최적화

가장 일반적인 로딩 성능 최적화는 첫 번째 화면의 로딩 시간을 최적화하는 것인데, Vue/React 프로젝트와 같은 단일 페이지 프로젝트인 경우 사이트를 처음 로딩할 때 속도가 느려질 수 있습니다. 전체 프론트엔드 프로젝트가 한번에 브라우저로 전송됩니다...

과도한 대기 시간은 사용자의 인내심을 지치게 하고, 대기 과정에서 바로 사이트를 떠날 수도 있으므로 첫 화면의 최적화가 특히 중요한 경우가 많습니다!

스테이션 B를 예로 들면, 아래 그림과 같이 스테이션 B의 홈페이지가 열리면 83개의 항목이 요청되고 총 리소스 크기는 2.1M임을 알 수 있습니다.

하지만 화면이 스크롤됨에 따라 다음과 같이 점점 더 많은 리소스가 로드됩니다.

레이지 로딩(Lazy Loading) 기술 입니다 .

직설적으로 말하면 보이는 영역의 내용만 표시되고, 표시되지 않는 경우에는 보이는 영역 밖의 내용은 로드되지 않습니다. 페이지 로딩이 좀 늦어질거고 처음에 보고싶은 내용을 못볼수도 있어서 미리 금액을 만들어놨는데, 요소가 오프셋 영역에 도달하면 그때는 되는거라고 생각합니다. 사용자는 즉시 볼 수 있고 적극적으로 로드되어야 합니다~

구현 방법은 복잡하지 않습니다. 이미지 리소스를 예로 들면, 이미지 주소는 기본적으로 custom 속성에 배치됩니다. 이미지가 오프셋 영역에 들어갈 때만 이미지의 data-src 값이 적극적으로 할당됩니다. src;

// 代码层面
<img data-src="图片地址" src="" />

또한 Vue/React와 같은 단일 페이지 애플리케이션의 경우 다음과 같이 작동할 수 있습니다.

<!DOCTYPE html>
<html lang="en" id="htmlRoot">
  <head>
    <title><%= title %></title>
    <link rel="icon" href="/favicon.ico" />
  </head>
  <body>
    <div id="app">
    	// lodaing动画效果
      <div class="app-loading">
        <div class="app-loading-wrap">
          <img src="/resource/img/logo.png" class="app-loading-logo" alt="Logo" />
          <div class="app-loading-dots">
            <span class="dot dot-spin"><i></i><i></i><i></i><i></i></span>
          </div>
          <div class="app-loading-title"><%= title %></div>
        </div>
      </div>
    </div>
  </body>
</html>

최상위 요소에 로딩 애니메이션 효과를 추가합니다. 리소스가 로드될 때 Vue/React가 최상위 요소의 콘텐츠를 적극적으로 커버한다는 것을 알아야 합니다. 이 기능을 사용하면 여전히 로딩 애니메이션이 있습니다. 유저님 잠시만 기다려주세요~

3.2 빌드 최적화

그 전에 질문 하나를 던져보겠습니다. 왜 건설 최적화를 통해 성능을 향상시킬 수 있습니까?

요청을 설정한 후 리소스를 요청하는 프로세스, 모든 리소스를 빠르게 요청하는 방법은 주의할 만한 프로세스라는 것을 알고 있는데, 모든 리소스를 빠르게 요청하는 방법은 무엇일까요? 실제로 두 가지 점이 있습니다.

  • 첫 번째는 리소스 압축 입니다 . 리소스 양을 줄이면 전송 시간이 자연스럽게 줄어듭니다.
  • 두 번째는 리소스 병합 , 여러 리소스를 함께 병합하는 것입니다. 한 번의 요청은 여러 리소스를 요청하는 것과 동일하므로 자연스럽게 전송 시간을 줄일 수 있습니다.

이 두 가지 점을 달성하기 위해 webpack을 예로 들어 구축 최적화입니다. (vite와 같은 새로운 구축 도구가 점점 더 대중화되고 있지만 여전히 webpack의 엄청난 사용이 주류입니다....)

3.2.1 자바스크립트 압축

웹팩에는 압축 효과를 얻을 수 있는 대략적인 몇 가지 구성이 있습니다.

(PS: 압축을 위해 terser-webpack-plugin을 사용하는 경우 이 플러그인은 압축 속도를 향상시키기 위해 기본적으로 멀티스레드 압축을 수행합니다.)

3.2.2 CSS 압축

CSS를 HTML에 직접 삽입하기 위해 스타일 로더 를 사용하지 말고 별도의 CSS 파일이어야 합니다. 이는 매우 중요합니다. 이유도 매우 간단합니다. CSS 리소스는 병렬로 로드할 수 없으므로 렌더링 성능이 저하됩니다.

따라서 min-css-extract-plugin 플러그인을 사용할 수 있습니다. 이 플러그인은 CSS 코드를 추출하고 분리합니다. 구성 후 대략 다음과 같습니다.

const CSSMinimizerPlugin = require("css-minminzer-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports={
	// 其他配置
	optimization:{
		minimize:true,
		minimizer:[new CSSMinimizerPlugin()]
	},
	plugins:[new MiniCssExtractPlugin()]
}

3.3 렌더링 최적화

처음 두 최적화의 주요 부분은 http 요청 부분에 있습니다. 이 부분은 리소스 요청이 도착한 후 브라우저 렌더링 프로세스에서 리소스를 DOM으로 렌더링하는 프로세스입니다. 이 프로세스에는 대략 다음과 같은 구체적인 세부 정보가 있습니다.

이러한 일반적인 프로세스를 통해 우리는 인터페이스 렌더링이 실제로 상당히 번거롭다는 것을 발견했습니다. 렌더링된 DOM 노드를 이동하지 않는 것이 가장 좋지만 실제로는 이동이 불가능합니다. 사용자의 일상 작업은 단지 상호 작용하는 것 아닌가요? 인터페이스에서 상호작용이 시작되면 DOM 노드는 자연스럽게 다양한 변화를 겪게 됩니다....

3.3.1 역류 감소

인터페이스 변경의 경우 다시 그리기 리플로우 두 가지 범주로 나눌 수 있습니다 . 친구들이 이 두 가지 사항에 대해 잘 알고 있어야 한다고 생각하므로 더 이상 소개하지 않겠습니다. 다시 그리기에 비해 리플로우가 더 큰 영향을 미칩니다 . 페이지에 있는 많은 노드의 기하학적 특성으로 인해 전체 페이지가 위 프로세스를 다시 거쳐야 하며 성능에 미치는 영향을 상상할 수 있습니다.

따라서 실제로 이 부분에 대한 최적화 목적은 단 하나뿐입니다. 다시 그리기는 더 많은 성능을 소비하고 리플로우 작업을 최소화합니다 . 대략 다음 속성을 수정하면 리플로우에 영향을 미칩니다.

  • 너비, 높이, 패딩, 여백, 왼쪽, 오른쪽 등과 같은 기하학적 속성의 변경 ;
  • DOM 노드 추가, 수정, 삭제 등 DOM 트리가 변경됩니다.
  • offsetTop, scrollTop 등과 같은 특정 속성 값을 가져옵니다 .

3.3.2 레이아웃 수 줄이기

다음과 같은 글쓰기를 금지한다는 점은 주목할 가치가 있습니다 .

const dom = document.querySelector(".dom");

dom.style.width="100px";
dom.style.height="100px";
dom.style.border="1px solid #000000";

이런 방식으로 작성하면 DOM의 기하학적 속성이 세 번 수정되므로 인터페이스가 세 번 다시 레이아웃됩니다. 이러한 방식은 바람직하지 않습니다. 합리적인 방법은 DOM에 클래스를 추가하는 것입니다.

const dom = document.querySelector(".dom");
dom.classList.add('new-style');

.new-style{
  width:100px;
  height:100px;
  border:1px solid #000000
}

클래스를 추가하는 이 방법은  한 번만 다시 레이아웃됩니다 .

3.3.3 흔들림 방지 및 조절

그리고 다음과 같은 일부 이벤트의 경우

이런 이벤트는 흔들림 방지 및 조절 기능이 필요합니다 . 이러한 이벤트가 자주 발생하면 필연적으로 페이지가 흔들리고 정지됩니다 . 본질적으로 이벤트 발생을 줄이는 것이 아니라 실행 횟수를 줄이는 것입니다. 콜백 함수에 의해 트리거됩니다 . 사용 시나리오도 약간 다릅니다.

  • Throttling : Throttling의 의미는 일정한 간격으로 기능을 실행하는 것인데, 예를 들어 1초 안에 키보드를 10번 눌렀는데 Throttling을 통해 요청을 초당 1회로 제한하므로 요청 빈도를 크게 줄일 수 있습니다.
  • Anti-shake : 손떨림 방지의 의미는 짧은 시간 내에 고주파 트리거가 결국 하나로 결합된다는 것입니다. 요청으로 이동하며 1초 이내에 새 텍스트가 입력되면 요청이 지워집니다. 이벤트가 발생하고 더 이상 트리거되지 않습니다.

인터넷에 손떨림 방지 및 스로틀링 코드가 많이 있는데, 로대시도 기성품으로 포장되어 있어서 소개는 않겠습니다~

3.4 캐시 성능 최적화

첫 번째는 반복된 요청을 처리하는 것입니다 . 반복된 요청은 네트워크 대역폭을 소비하여 사용자 경험에 영향을 미치기 때문에 획득한 리소스를 재사용해야 합니다.

3.4.1 브라우저 캐시

브라우저 캐싱은 필수 캐싱협상 캐싱 으로 구분됩니다 .

  • 필수 캐싱 : 요청 시 캐시 필드를 확인하고, 만료되지 않은 경우 브라우저의 로컬 캐시에서 직접 리소스를 반환합니다 .
  • 협상 캐시 : 브라우저가 로컬 캐시를 사용하기 전에 로컬 캐시가 만료되었는지 확인하기 위해 서버에 요청을 보냅니다 .

일반적으로 우리는 캐싱의 우선순위를 정하기 위해 이 프로세스를 사용합니다.

V. 요약

이 문서에서는 성능 최적화의 다양한 지점을 자세히 소개합니다.

  • 로딩 최적화의 목적 은 http 요청과 지연 로딩 기술을 줄여 첫 화면의 로딩 시간을 줄이는 것입니다.
  • 구축 최적화의 목적 은 리소스의 양과 양을 줄이고 웹팩과 같은 주류 구축 도구를 합리적으로 사용하여 리소스를 병합하고 압축하는 것입니다.
  • 캐시 최적화 의 목적 은 반복되는 요청을 피하는 것입니다. 그러나 캐시 전략은 신중하게 고려해야 합니다. 결국 장점과 단점이 있습니다.
  • 렌더링 최적화의 목적은 다시 그리기 및 리플로우 감소, 합리적인 코드 및 적시 리소스 해제와 같은 고성능 작업을 줄이는 것입니다.

추천

출처blog.csdn.net/zy21131437/article/details/132185911