JS 기본 (오) - 프런트 엔드 성능 최적화 요약

프런트 엔드 성능 최적화 요약

리소스 최적화

캐시

가장 좋은 자원 최적화 리소스를로드되지 않습니다. 최적화 캐싱의 가장 효과적인 수단이다. 클라이언트 캐시 브라우저에서 발생하지만 캐시 서버가 주로 제어 할 수 있지만, 솔직히 말해서, 프론트 엔드와의 관계는 크지 않다. 하지만 여전히 우리는 알 필요가있다.

캐시는 캐시 서버와 클라이언트 측 캐싱, 우리는 클라이언트 캐시에 대해 이야기가 포함되어 있습니다. 소위 클라이언트 측 캐싱 주로 HTTP 캐시. HTTP 캐시와 캐시는 필수 상담 캐시로 나누어 져 있습니다.

강제 캐시

  • 만료 (HTTP1.0)

사용 HTTP1.0에서 캐시에하도록 강요 만료. Exprires 서버 만료 시간에서 반환 된 데이터의 값입니다. 이 시간이 다시 요청하면 요청 시간에 직접 사용되는 캐시 된 데이터의 반환보다 작은 경우. 그러나 시간 서버와 클라이언트 시간으로 인해 또한 캐시 히트 오류가 발생합니다 오류가있을 수 있습니다.

  • 캐시 제어

캐시 제어는 다른 속성이 서로 다른 표현 즉, 많은 특성을가집니다.

  1. 개인 : 클라이언트 캔 캐시
  2. 공공 : 클라이언트와 프록시 서버 캔 캐시
  3. 최대 사용 기간 = t : 캐시 내용은 T 초에 만료됩니다
  4. 노 캐시 : 캐시 상담 데이터 캐시를 확인하기 위해 필요
  5. 노 가기 : 모든 내용이 캐시되지 않습니다.

캐시 상담

먼저 브라우저 요청 데이터, 서버가 클라이언트로 식별 데이터 캐시로 응답, 클라이언트는 그들 캐시에 백업합니다. 또, 서버는이 식별에 기초하여 결정되고, 클라이언트가 서버에 식별자 캐시 할 요청할. 더 실패하면, 상태 코드 (304)는 ​​데이터 캐시로 사용할 수 있습니다이 상태 코드를 얻을 수있는 브라우저를 반환합니다.

  • - 마지막으로 수정

요청에 응답하여 서버가 마지막으로 수정 된 브라우저의 자원을 알려드립니다

  • IF-변성 때문에

서버에 브라우저 요청을 다시 요청 헤더는 캐시 (마지막 수정 시간)에서 얻은 마지막으로 수정 한 다음이 필드를 포함합니다. 서버는 수정 된 IF--때문에 요청한 리소스의 최종 수정 시간과 비교하여 요청 된 리소스가 마지막으로 수정 된 시간은 304 리턴보다 큰 경우 상기 요청 머리 앞서, 브라우저 캐시에서 자원을 취득하고 수신한다. 요청 된 리소스보다가 마지막으로 수정 된 경우, 최신 서버에서 자원 및 캐시의 브라우저를 최신 자원을 200을 반환하고 돌아갑니다.

  • ETAG

리소스 서버에 의해 생성 된 각각의 고유 식별 문자열

  • 만약 - 없음 - 경기

서버에 요청을 다시 브라우저 요청 패킷 헤더는 캐시 ID에서 얻은 값 뒤에이 필드를 포함합니다. 서버가 상기 메시지를 수신하면 뷰 FOUND가 요청한 자원의 고유 식별자와 비교하면 일치 - 없음. 같은 경우, 자원이 다른 자원의 설명이 수정 된 경우, 다음 200로 복귀, 복귀 (304), 캐시에서 자원에 대한 브라우저 액세스를 수정, 최신 자료, 최신 서버에서 자원 및 캐시의 브라우저를 반환되지 않았 음을 나타냅니다.

마지막으로 수정하고있는 ETag는 같은 상황에서, (304)를 반환할지 여부를 결정하기 전에, 마지막으로 수정 비교 계속 서버가있는 ETag를 확인하기 위해 우선 순위를 제공합니다 함께 사용할 수 있습니다.

당신이 도구를 포장 프런트 엔드를 사용하는 경우, 파일이 버전 번호 또는 해시 값에 추가되는 파일로 패키지 할 수 있습니다, 그것은 또한 자원이 만료 여부를 구분할 수 있습니다.

HTTP 요청을 감소

  • 사용 CDN 정적 리소스를 호스팅
  • 병합 파일 JS, CSS 및 기타 압축 꿀꺽, 웹팩 및 기타 패키징 도구를 도울 수
  • 로드 사진을 가기 전에 지역을 볼 때 사진 게으른 로딩, 수요로드, 사진으로 스크롤
  • 작은 사진과 인코딩과 전송 base64로를 사용하여 기본 사진을 변경되지 않습니다. base64로는 남용 base64로하면 역효과가 될 것입니다, 긴 문자열을 생성합니다 심지어 작은 사진 base64 인코딩 후, 남용하지 않는다
  • 사진 변경하는 경우, 전체지도 스프라이트 중생의 원인이되므로 무분별한 사용은 역효과 될 경우 그림 스프라이트, 스프라이트 그림이는 만 변경되지 않는 기본 사진에 사용됩니다.

자원 HTTP 요청의 볼륨을 감소

  • 웹팩로, 꿀꺽 압축 도구 등 자원
  • 서비스 (압축률은 일반적으로 30 % 이상, 매우 인상적 임) GZIP 압축을 활성화
  • 유용한 도구가 포장하면 할 수있는 최적화 포장, 공공 자원, 타사 코드, 아니 패키지 라이브러리를 추출 ...

렌더링 최적화

(범위가 해결되지 TCP 핸드 셰이크, DNS 등), 화면의 페이지가 나타납니다, 일어난 어떤 일들 브라우저에서 URL을 입력 것을 알아야한다 메커니즘을 작동 전면 JS를 읽어보십시오.
  • FPS 최고의 구글 devtool보기를 완료하기 위해 적은 10ms의 프레임 속도보다 16ms

브라우저가 60 FPS에 도달하는 경우, 상대적으로 나타날 부드러운 것, 대부분의 모니터 새로 고침 속도가 60Hz의이 브라우저이 주파수에 따라 자동으로 새로 고침 애니메이션 것.
FPS에 따르면,이 시간보다 더 많은 프레임 Caton 현상 삭제 될 경우마다 있도록 렌더링 시간은 16ms를 초과 할 수 1000MS / 60 = 16.7ms의 평균 시간을 계산하기 위해 60과 동일.

타임 라인은 재생 빈도를 볼 수있는 크롬 브라우저 개발자 도구에서, 당신은 모든 프레임 속도뿐만 아니라 시간이 많이 걸리는 프레임의 구현을 볼 수 있습니다. 튜토리얼의 타임 라인 :HTTPS : //segmentfault.com/a/11 ...

일반 FPS를 보장하기 위해, 일부 렌더링 성능 최적화가 필요하다. 다음 전략은 렌더링 최적화에 관한 설명되어 있습니다.

  • CSS3를 사용하여 애니메이션을 봅니다

우리가 알다시피, JS보다는 CSS 빠른 성능, 그들이 사용할 수 있습니다 CSS는, JS를 달성하기 위해 노력하지 않아요

  • 의 setTimeout 또는 setInterval을 사용하지 마십시오, 또는 돔 동작을 애니메이션 고주파 requestAnimationFrame을 사용하도록.

에서는 setTimeout과 setInterval을 콜백 함수의 실행시기를 보증 할 수 있기 때문에, 프레임 손실의 결과로, 시간 프레임의 끝에서 수행 할 수 있지만 requestAnimationFrame 콜백 함수를 실행 보장 할 때 애니메이션의 각 프레임의 시작
중국 MDN 어드레스 requestAnimationFrame :HTTPS : //developer.mozilla.org ...

  • 복잡한 컴퓨팅 작업은 웹 노동자를 사용하여

당신이 그런 합계를 횡단 요소의 배열과 같은 복잡한 데이터 처리를 필요로하는 경우, 쉬운 다음 웹 노동자가해야 할 일.

백그라운드 스레드는 페이지의 메인 스레드에 영향을 미치지 않습니다 동안 웹 노동자, 자바 스크립트 스크립트는 백그라운드 스레드 (자식 쓰레드를 생성 비슷 함)에서 실행할 수 있습니다. 그러나, 스레드의 사용이 만든 웹 노동자는 DOM 트리를 조작 할 수 있습니다.
더 많은 웹 노동자에 대한이 MDN 댓글을 볼 수 있습니다 :HTTPS : //developer.mozilla.org ...

  • 머리에 CSS는, 꼬리에 JS.

페이지 렌더링 과정이다 방법을 알고 있어야합니다 메커니즘을 작동 전면 JS 읽기, 그들을 반복하지. 헤드 피하기 시작 화면 현상 생성 된 HTML 트리 CSS는 다시 배치 한 후, 일반적으로 마지막 실행 꼬리 페이지에 일반적으로 더 큰 영향을 JS.

  • 이벤트 이미지 안정화 (바운스)와 스로틀 (스로틀)

체크를 해제하면 고주파 이벤트 트리거 (MouseMove 이벤트, 스크롤) 및 기타 이벤트의 경우, 짧은 시간에 많은 이벤트를 트리거합니다.

손떨림 방지 기능은 한 번 코드를 실행할 자주 트리거 만 충분한 자유 시간의 경우를 말한다. 장면 : 전자 메일 등록 입력 상자, 실시간으로 사용자의 입력과 함께 결정하는 첫 번째 이벤트 트리거 입력, 타이머를 설정 올바른 사서함 형식 여부 : 800ms 이후에 체크. 단지이 100ms 후, 타이밍이 마지막으로 실행하지 않은 경우,이 시간이 800ms를 리 타이밍, 타이밍을 취소합니다. 마지막 입력까지 입력이 바로 뒤에되지 않으며, 최근의 입력 타이밍이 시간이 완료되면, 마지막으로 확인 코드를 수행합니다.

const filter  = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;  
$("#email").on("keyup",checkEmail());  
function checkEmail(){  
    let timer=null;  
    return function (){  
        clearTimeout(timer);  
        timer=setTimeout(function(){  
            console.log('执行检查');  
        },800);  
    }  
}  

그것은 한 번만 실행 시간의 기능 확장 방법 JS 일정 기간을 의미합니다. 즉, 제 10 회 수행 한 하나가 제 100 회 수행되어야한다.
장면 : 페이지 요소 이벤트를 스크롤 할 때 실제 현장 조절 기능은 대부분의 청취자가 사용됩니다.

var canRun = true;
document.getElementById("throttle").onscroll = function(){
    if(!canRun){
        // 判断是否已空闲,如果在执行中,则直接return
        return;
    }

    canRun = false;
    setTimeout(function(){
        console.log("函数节流");
        canRun = true;
    }, 300);
};
  • 돔 작업

프런트 엔드 개발자가 동작을 인식하는 일은 매우 (* 30 (30)에 걸쳐 측정 오픈 테이블 이송 추가 스타일을 보낸) 시간이 소요됩니다. 그래서 DOM 작업의 최적화를 수행하기 위해 가능한 한 그것을 피하지 않을 경우, 자주 돔 작업을 피하려고합니다.

1.:缓存Dom查询,比如通过getElementByTagName('div')获取Dom集,而不是逐个获取。

2: 合并Dom操作,使用createDocumentFragment()
    var frag = document.createDocumentFragment()
    for (i<10) {
        var li = document.createElement('li')
        frag.appendChild(li)
    }
    document.body.appendChild(frag)
 3: 使用React、Vue等框架的虚拟dom(原理目前还不明白),可以更快的实现dom操作。

  • 피하기 다시 그리기 (재 페인트) 및 반환하려고 (리플 로우)

당신은 JS가 다시 그리기 트리거 할 색상이나 요소의 배경색을 변경 사용하는 경우, 비용 때문에 브라우저가 특정 DOM 요소의 시각적 효과를 변경됩니다 DOM 요소 검사의 모든 노드에 꽤 비싼 묘화합니다.

당신은 크기와 역류가 발생 요소의 위치, 더 큰 오버 헤드 역류를 변경할 경우, DOM 요소에 특정 위치가 변경 될 때 트리거, 모든 요소의 위치를 ​​계산하고이 지역은 너무 페이지에 점령 다음은 재 렌더링 전체 페이지 또는 페이지의 특정 부분의 원인이됩니다.

  • CSS3 하드웨어 가속

일반 층과 복합 층 : 브라우저가 렌더링되면, 두 개의 층으로 분할된다.

문서의 흐름은 일반적으로 복합 층으로서 이해 될 수 내 절대 고정 된 레이아웃은 보통 문서를 유출 할 수 있지만, 그러나 여전히 정상 층이고, 하드웨어 가속이 시작되지 않을 것이다. 위에서 재 묘화 (다시 칠)를 상기 창 (리플)은 말하자면 그려야 공통 층에 복귀한다.

복합 층은 하드웨어 가속을 개시한다. 요소가 복합 층 올리면 공통 층과 동일하지 층은, 상기 복합 층은, 공통 레이어에 영향을주지 않는 그 다음 요소 의지하지 공통 층 재 묘화 환류 원인 따라서 렌더링 성능을 향상시킬 수있다.

어떻게 하드웨어 가속을 시작합니다 :

1. translate3d 및 translateZ

webkit-transform: translateZ(0);
-moz-transform: translateZ(0);
-ms-transform: translateZ(0);
-o-transform: translateZ(0);
transform: translateZ(0);

webkit-transform: translate3d(0,0,0);
-moz-transform: translate3d(0,0,0);
-ms-transform: translate3d(0,0,0);
-o-transform: translate3d(0,0,0);
transform: translate3d(0,0,0);

2. 불투명도가
반환 합성 층, 시작 또는 끝 소자 후 애니메이션 전에없는 상태를 만들 것이다 애니메이션 프로세스를 수행하는 데 필요한

3. 사용-장 속성은
이 속성은, 일반적으로 많이 사용 불투명도와 함께 사용하고 번역한다

웹킷 브라우저를 들어, 자주 깜박이거나 점멸로 브라우저, 당신은 제거하기 위해 다음과 같은 방법을 사용할 수 있습니다 될 수 있습니다 경우에 따라 하드웨어 가속을 활성화합니다

-webkit-backface-visibility:hidden;
-webkit-perspective:1000;
이 요소는 하드웨어 가속을 첨가 한 경우 인덱스 레벨이 다른 요소 후자 소자 (소자보다 높은 레벨 또는 동일하고 releative 후 비교적 낮기 때문에, 하드웨어 가속하는 경우, 사용으로 Z- 색인을 사용 크게 성능에 영향을 미칩니다 제대로 처리하지 않으면 절대 속성이나) 동일한는 기본 렌더링 복합 레이어 변경
  • 강제 동기화 지터 레이아웃과 레이아웃을 피하십시오

브라우저 렌더링 프로세스는 다음과 같습니다 JS / CSS (자바 스크립트)> 컴퓨팅 스타일 (스타일)> 레이아웃 (레이아웃)> 그릴 (페인트)> 레이어 병합 렌더링 (종합)

자바 스크립트 : 자바 스크립트 애니메이션, DOM 요소 작업.
스타일 (계산 양식) 각 DOM 요소에 대한 CSS 규칙을 적용해야하는지 결정합니다.
배치 (레이아웃) : 사이즈 DOM 각 요소의 위치가 최종 화면에 표시된 계산한다.
페인트 (드로잉) : DOM 요소가 같은 텍스트 색상, 이미지, 테두리, 음영의 복수의 층으로 인출하고있다.
합성 (렌더링 합하고) : 레이어가 적절한 순서로 결합하고 화면에 표시 하였다.

당신은 JS 스타일의 특성에 읽을 경우 일부 값은 레이아웃이 계산되면 브라우저를하도록 강요하고, 같은 다음 반환 값이 될 것입니다 :

offsetTop, offsetLeft, offsetWidth, offsetHeight

scrollTop/Left/Width/Height

clientTop/Left/Width/Height

width,height

请求了getComputedStyle(), 或者 IE的 currentStyle

그래서, 당신은 젠록 레이아웃이라고합니다 자바 스크립트 스크립트를 실행하기 전에 레이아웃 프로세스를 실행하는 브라우저를 강제합니다.
예를 들어, 코드 아래 :

requestAnimationFrame(logBoxHeight);

// 先写后读,触发强制布局
function logBoxHeight() {
    // 更新box样式
    box.classList.add('super-big');

    // 为了返回box的offersetHeight值
    // 浏览器必须先应用属性修改,接着执行布局过程
    console.log(box.offsetHeight);
}

// 先读后写,避免强制布局
function logBoxHeight() {
    // 获取box.offsetHeight
    console.log(box.offsetHeight);

    // 更新box样式
    box.classList.add('super-big');
}

자바 스크립트 스크립트 실행, 그것은 요소의 스타일 속성 값을 얻을 수있을 때 사진을 모두 이전 값에 있습니다. 당신이 재산을 얻기 위해 현재 프레임 전에 요소와 노드에 변경이있는 경우 그래서, 그것은 브라우저가 속성 변경, 레이아웃 프로세스의 구현의 결과를 적용해야합니다 원인이됩니다, 그리고 마지막으로 자바 스크립트 로직을 실행합니다.

레이아웃이 반복적으로 동기화를 강제하는 경우, 지터 레이아웃으로 이어질 것입니다
, 예를 들어 다음과 같은 코드를 :

function resizeAllParagraphsToMatchBlockWidth() {
  for (var i = 0; i < paragraphs.length; i++) {
    paragraphs[i].style.width = box.offsetWidth + 'px';
  }
}

作者:SylvanasSun
链接:https://juejin.im/post/59da456951882525ed2b706d
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

우리는 브라우저가 알려져있는 레이아웃 정보의 각 프레임, 프레임에서 페이지를 새로 고침하는 것을 알고있다.
사용 JS는 아래의 코드로, 앞서 레이아웃의 브라우저를 강제로 강제 레이아웃은 다음과 같습니다

// bed  每次循环都要去获取left ,就会发生一次回流
function logBoxHeight() {
  box.style.left += 10
  console.log(box.style.left)
}

// goog 
var width = box.offsetWidth;

function resizeAllParagraphsToMatchBlockWidth() {
  for (var i = 0; i < paragraphs.length; i++) {
    // Now write.
    paragraphs[i].style.width = width + 'px';
  }
}
  • DOMContentLoaded 与로드

DOMContentLoaded 이벤트는 DOM 트리거 DOMContentLoaded, 시트, 이미지, 외부 자원의 도입이로드되지 않은이 시간 스타일을로드하는 경우에만 트리거합니다. 부하는로드되고 모든 리소스가 트리거됩니다.

1. 解析HTML结构。
2. 加载外部脚本和样式表文件。
3. 解析并执行脚本代码。
4. DOM树构建完成。//DOMContentLoaded
5. 加载图片等外部文件。
页面加载完毕。//load
  • 비주얼 최적화

어느 정도의 대기 시간에 사용자에게 불안 로딩 GIF 액션 피겨의 감각을 제거 할 수로드 시간의 합리적인 사용을 위해 대기

코드 성능

코드의 성능에 미치는 영향은 성능을 향상시킬뿐만 아니라, 자신의 수준을 향상시키기 위해 미묘한 것, 매우 유연 할 수 있지만, 코드와 높은 품질의 코드를 작성의 좋은 습관을 개발. 아도, (너무 많은 지식 포인트의이 부분의, 우리는 시간 코드를 작성하는 요약을 많이 필요로하기 때문에) 내가 요약 핵심 사항에 직접 모습.

  • 글로벌 검색을 피

빠른 글로벌 변수와 지역 변수, 이제 변수 JS 발견 시간은 현지 사무소 역할을 찾을 수 있기 때문에, 단계별로 단계를 찾고 찾을 수 없습니다.

// bad
function f () {
    for (...){
        console.log(window.location.href)
    }
}

//good
function f () {
    var href = window.location.href
    for (...){
        console.log(href)
    }
}
  • 기술 루핑
// bed 
for(var i = 0; i < array.length; i++){
    ....
}
// good
for(var i = 0, len = array.length; i < len; i++){
    ....
}
// 不用每次查询长度
  • 배열을 순회에서 사용하지 마십시오

의 느린에, 다른 사람은 가장 빠른 사이클에 직접 사용되는, 유사합니다. 단에서 객체를 탐색하기 위해 적합한.

  • 문자열 변수로 사용 + ''대신 문자열 ()을
var a = 12
//bad
a = String(a)

// good
var a = 12
a = a + ''

이 같은 많은 사실, 이것은 인터넷이 테스트 수십만 번 변수 변환 만 빠른 제로를 실시 하였다 성능 크지 않다, 이러한 모든 약한 타입 JS를 사용하는 () * 1 대신으로 parseInt의 사용으로있다 몇 초.

  • 삭제 DOM

삭제 DOM 요소가 그들 사이에서 선택을 ''=로 removeChild와 innerHTML을을 선택하고, 후자의 시도 그렇지 않으면 당신은 복구되지 않습니다 메모리를 노드에 등록 이벤트를 삭제하려면, 그것은 (특정가에서 removeChild 때때로 효율적으로 노드를 해제 할 수 있다고 ) 알 수없는 이유

  • 이벤트를 사용하여 핸들 이벤트를 연기

모든 이벤트 캔 거품 자식 노드의 상황은 각 하위 노드 추가 이벤트 리스너에 따로 없을 것 같은 이벤트를 결합 할 필요가 그래서, 조상 노드에서 처리 할 수 ​​있지만 조상 노드 처리로 상승한다.

  • 객체에 의해 생성 된 돔 JS 페이지에 추가해야합니다

IE에서, 양의 DOM JS가 페이지에 추가하지 않을 경우,이 메모리는 회수되지 않는다 만든

  • 널 (null)을 비교하지 마십시오

이하의 방법 널 비교하여 교체 할 수
값이 참조 형식이면 1. instanceof는 다음 생성자를 이용한 확인
이 기본 유형의 typeof의 유형을 확인 경우 2.

  • 가능한 대신 삼항 연산자 다른 경우를 사용하는
if(a>b){num = a}
else{num = b}

// 可以替换为
num = a > b ? a : b
  • 판정 조건은 케이스 (3)보다 큰 경우, 대신에 스위치를 사용할 때

속도가 두 배에 대해 인 경우 실행 속도 스위치 빠른 경우에 비해 때문에, IE에서 안

먼저 요약하고 너무 많은 사실, 이러한 사전로드, 서버 렌더링, CSS를 선택 최적화 등 많은 성능 최적화이있다. 그래서 요약 할 수있는 기회를 갖게

추천

출처www.cnblogs.com/jlfw/p/11978477.html