간단히 말하면 기능 스로틀은 매우 짧은 시간 간격 내에 기능을 지속적으로 호출 할 수 없게 만듭니다. 마지막 함수가 지정된 시간 간격 후에 실행 된 경우에만 기능에 대한 다음 호출을 만들 수 있습니다.
기능 조절의 원리는 매우 간단합니다. 나는 모든 사람들이 그것을 생각했다고 생각합니다. 그것이 타이머라고 생각합니다. 시간을 트리거 할 때, 첫 번째 settimout에서 실행하기 전에 이벤트를 잠시 지연시킵니다. 이 시간 간격 내에 이벤트가 다시 트리거되면 원래 타이머를 지우고 새 타이머를 설정하여 실행을 잠시 지연시킵니다.
다음 시나리오에서, 다음 시나리오는 종종 DOM 운영 및 자원로드와 같은 큰 동작을 수행하여 UI가 일시 중지되거나 브라우저 충돌을 일으킨다.
1. 창 객체의 이벤트 크기를 조정하고 스크롤합니다
2. 드래그하는 동안 MouseMove 이벤트
3. 촬영 게임에서 마우스 다우와 키 다운 이벤트
4. 텍스트 입력에 의해 자동으로 완료된 KeyUp 이벤트
실제로, 창 크기 이벤트의 경우, 실제 요구 사항은 크기 N 밀리 초의 크기 변경을 중단하고 후속 처리를 수행하는 것입니다. 대부분의 다른 이벤트는 특정 주파수에서 후속 처리가 필요합니다. 이 두 가지 요구에 대한 두 가지 솔루션의 솔루션이 있습니다.
스로틀과 분해는 요청 및 응답 속도 불일치 문제를 해결하기위한 두 가지 솔루션입니다. 두 가지의 차이점은 다른 전략을 선택하는 데 있습니다.
스로틀과 같은 간격으로 함수를 실행합니다.
이벤트가 분동 간격 T 내에서 다시 트리거되면, 정지 시간이 t보다 크거나 동일 할 때까지 타이머가 다시 타이머로 연결됩니다.
1. 스로틀 함수의 간단한 구현
함수 스로틀 (fn, treshhold, scope) {threshold || (Threshhold = 250); 마지막으로, 타이머; return function () {var context = scope || 이것; var now = +new date (), args = argument; if (last && now -last + treshhold <0) {// helt timeout (defertimer); TIMER = settimeout (function () {last = now; fn.apply (Context, Args);}, Threshhold); } else {마지막 = 지금; fn.apply (컨텍스트, args); }};}호출 방법
$ ( 'body'). on ( 'mousemove', 스로틀 (함수 (event) {console.log ( 'tick');}, 1000);2. 간단한 분동 함수 구현
함수 분비 (fn, 지연) {var timer = null; return function () {var context = this, args = argument; 클리어 타임 아웃 (타이머); timer = settimeout (function () {fn.apply (context, args);}, 지연); };}호출 방법
$ ( 'input.username'). keypress (debounce (function (event) {// ajax request}, 250));3. 간단한 포장 구현
/** * 스로틀 * @param fn, 대기, debounce */var 스로틀 = function (fn, wait, debounce) {var timer = null, // timer t_last = null, // 마지막 시간 세트, // context args, // 매개 변수 diff; // 시차 반환 funciton () {var curr = + new date (); var context = this, args = argument; 클리어 타임 아웃 (타이머); if (debounce) {// debounce timer = settimeout (function () {fn.apply (context, args);}, 대기); } else {// 스로틀 if (! t_last) t_last = curr; if (curr -t_last> = 대기) {fn.apply (컨텍스트, 대기); 컨텍스트 = 대기 = null; }}}}}/** * debounce * @param fn, 대기 */var debounce = function (fn, 대기) {return 스로틀 (fn, wait, true);}요약 :이 두 가지 방법은 MouseMove, KeyDown, KeyUp, Keypress, Scroll 등과 같은 일부 이벤트에 반복적으로 트리거됩니다.
기본 이벤트 만 묶고 제어하지 않으면 브라우저가 말더듬이되고 사용자 경험이 열악합니다. JS 성능을 향상시키기 위해서는 위의 이벤트 및 유사한 이벤트를 사용할 때 기능 스로틀 또는 기능 분노를 사용하는 것이 좋습니다.
4. 밑줄 v1.7.0과 관련된 소스 코드 분석
1. _. 스로틀 함수
_.throttle = function (func, 대기, 옵션) {var context, args, result; var timeout = null; // 타이머 var previous = 0; // 시간 마지막 트리거 (! 옵션) 옵션 = {}; var later = function () {previous = Options.Leading === false? 0 : _.now (); 시간 초과 = null; 결과 = func.Apply (컨텍스트, args); if (! timeout) context = args = null; }; return function () {var now = _.now (); // if (! previous && 옵션 .leading === false) 이전 = 지금; // 여기에 나머지 개념이 있습니다. 이벤트 var var var를 실행하는 데 시간이 얼마나 걸립니까 = 대기 - (지금 - 이전); 문맥 = 이것; args = 인수; // 이벤트가 중지 된 후 또는 // 대기가 정확히 다를 때 이벤트가 reding을 고려하면 <= 0 남은 <= 0 남은 상태로 남은 <= 0 남은 <= 0은 대기가 정확히 다를 때, 이벤트가 즉시 트리거됩니다. // 대기는 해당 시나리오를 고려하지 않습니다. 나머지> 대기) {if (timeout) {cleartimeout (timeout); 시간 초과 = null; } previous = 지금; 결과 = func.Apply (컨텍스트, args); if (! timeout) context = args = null; // 추적 할 것인지} else if (! timeout && 옵션 .trailing! == false) {timeout = settimeout (나중에 나머지); } 반환 결과; };};위에서 볼 수 있듯이 밑줄은 더 많은 상황을 고려했습니다. 옵션.
처음으로 실행되면 기본값은 사실입니다. 이는 처음으로 실행됩니다. 최초의 실행 옵션. 트레일이 비활성화되었습니다 : 마지막으로 실행되면 기본값은 참이므로 마지막 시간이 실행됩니다. 마지막으로 통과되면 {후로 : false}는 마지막 시간이 실행되지 않았 음을 의미합니다. 소위 처음으로 이벤트가 먼저 실행되는지 여부입니다. 이벤트가 방금 시작되면 이벤트가 먼저 트리거되어야하는지 여부. 원한다면 이전 = 0이고 나머지는 음수 인 경우, 이벤트가 끝난 후에 기능이 실행되는지 여부에 관계없이 소위 마지막으로 호출됩니다. 이 방법은 마지막으로 트리거됩니다. 실행하려면 타이머가 설정되면 이벤트가 끝나면 한 번 실행해야합니다. Remianing> 대기는 클라이언트 시간이 수정되었음을 의미합니다.
2. _.debounce 함수
_.debounce = function (func, 대기, 즉시) {// 즉시 기본값은 False var timeout, args, 컨텍스트, 타임 스탬프, 결과입니다. var emter = function () {// _.debounce가 대기에 의해 지정된 시간 간격 동안 여러 번 호출되면 타임 스탬프의 값은 지속적으로 업데이트되어 마지막 <WAIT && last> = 0이 항상 사실이므로 지연 실행 func에 대한 새 타이머를 지속적으로 시작합니다. if (last <WAIT && last> = 0) {timeout = settimeout (나중에 기다려 - 마지막); } else {timeout = null; if (! 즉시) {result = func.apply (컨텍스트, args); if (! timeout) context = args = null; }}}; return function () {context = this; args = 인수; timestamp = _.now (); // 메소드가 처음으로 호출되고 대기에 의해 지정된 시간 간격 직후에 타이머가 func function을 호출하기 시작하면 (! timeout) timeout = settimeout (나중에 대기); if (callnow) {result = func.apply (컨텍스트, args); 컨텍스트 = args = null; } 반환 결과; };};_.debounce 구현에 대한 놀라운 점은 Cleartimeout을 호출하여 호출 기능의 지연 실행을 조정하는 대신 타이머를 재귀 적으로 시작하는 것입니다.
위의 것은 편집자가 소개 한 JavaScript 성능 최적화 기능 스로틀 및 디케이운스 기능입니다. 나는 그것이 당신에게 도움이되기를 바랍니다. 궁금한 점이 있으면 메시지를 남겨 주시면 편집자가 제 시간에 답장을 드리겠습니다. Wulin.com 웹 사이트를 지원해 주셔서 대단히 감사합니다!