이 글의 원래 의도는 몇 가지 간단한 코딩 팁을 사용하여 JavaScript를 개선하는 방법을 소개하는 것입니다. 컴파일러 최적화 프로세스는 코드 실행 효율성을 향상시킵니다. 특히 가비지 수집 속도가 빠른 게임에서는 성능이 약간 떨어지면 사용자에게 흰색 화면이 표시됩니다.
JavaScript에서는 함수를 호출할 때 동적 매개변수가 전달되도록 허용하지만 간단한 2개 매개변수 함수를 예로 들면 매개변수 유형, 매개변수 개수 및 반환 유형이 동적으로 호출되는 경우에만 확인할 수 있으며 컴파일러는 구문 분석하는 데 더 많은 시간이 필요합니다. 컴파일러는 당연히 단형적으로 예측 가능한 데이터 구조, 매개변수 통계 등을 처리할 수 있기를 원합니다.
function example(a, b) { // we expect a, b to be numeric console.log(++a * ++b); }; example(); // bad example(1); // still bad example("1", 2); // dammit meg example(1, 2); // good
상수를 사용하면 컴파일러가 컴파일 중에 변수 값 대체를 완료할 수 있습니다.
const a = 42; // we can easily unfold this const b = 1337 * 2; // we can resolve this expression const c = a + b; // still can be resolved const d = Math.random() * c; // we can only unfold 'c' // before unfolding a; b; c; d; // after unfolding // we can do this at compile time! 42; 2674; 2716; Math.random() * 2716;
JIT 컴파일러는 다음을 찾을 수 있습니다. 가장 자주 실행되는 코드 부분. 코드를 작은 코드 블록으로 분할하면 컴파일러가 컴파일 타임에 이러한 코드 블록을 인라인 형식으로 변환하고 실행 속도를 높이는 데 도움이 됩니다.
숫자와 부울은 문자열과 같은 다른 기본 유형보다 더 나은 성능을 발휘하므로 가능한 자주 사용하십시오. 문자열 유형을 사용하면 추가 가비지 수집 비용이 발생할 수 있습니다.
const ROBOT = 0; const HUMAN = 1; const SPIDER = 2; let E_TYPE = { Robot: ROBOT, Human: HUMAN, Spider: SPIDER }; // bad // avoid uncached strings in heavy tasks (or better in general) if (entity.type === "Robot") { } // good // the compiler can resolve member expressions // without much deepness pretty fast if (entity.type === E_TYPE.Robot) { } // perfect // right side of binary expression can even get unfold if (entity.type === ROBOT) { }
가능하면 == 연산자 대신 === 엄격한 비교 연산자를 사용하세요. 엄격한 비교 연산자를 사용하면 컴파일러가 유형 추론 및 변환을 수행하는 것을 방지하여 특정 성능을 향상시킬 수 있습니다.
JavaScript의 if 문도 매우 유연합니다. if(a) then bla 유형의 조건 선택 문에서 유사한 값을 직접 전달할 수 있습니다. 하지만 이 경우도 위에서 언급한 엄격한 비교 연산자와 느슨한 비교 연산자와 마찬가지로 비교를 위해 컴파일러가 이를 여러 데이터 형식으로 변환해야 하며 결과를 즉시 얻을 수는 없습니다. 물론 약어 사용에 대한 맹목적인 반대는 아니지만, 성능이 크게 강조되는 시나리오에서는 모든 세부 사항을 최적화하는 것이 좋습니다.
let a = 2; // bad // abstracts to check in the worst case: // - is value equal to true // - is value greater than zero // - is value not null // - is value not NaN // .. if (a) { // if a is true, do something } // good if (a === 2) { // do sth } // same goes for functions function b() { return (!false); }; if (b()) { // get in here slow } if (b() === true) { // get in here fast // the compiler knows a specific value to compare with }
인수 사용을 피하세요. 가능한 한 [index] 방법을 사용하여 매개변수를 얻고, 들어오는 매개변수 변수를 수정하지 않도록 하세요:
function mul(a, b) { return (arguments[0]*arguments[1]); // bad, very slow return (a*b); // good }; function test(a, b) { a = 5; // bad, dont modify argument identifiers let tmp = a; // good tmp *= 2; // we can now modify our fake 'a' };
여러 구문 아래 나열된 기능은 최적화 프로세스에 영향을 미칩니다.
평가
with
try/catch
동시에 함수 선언이나 함수 내 클로저 선언을 피하세요. 이로 인해 다수의 작업에서 너무 많은 가비지 수집 작업이 발생할 수 있습니다.
객체 인스턴스는 일반적으로 암시적 클래스를 공유하므로 인스턴스의 정의되지 않은 변수에 액세스하거나 값을 설정하면 암시적 클래스가 생성됩니다.
// our hidden class 'hc_0' class Vector { constructor(x, y) { // compiler finds and expects member declarations here this.x = x; this.y = y; } }; // both vector objects share hidden class 'hc_0' let vec1 = new Vector(0, 0); let vec2 = new Vector(2, 2); // bad, vec2 got hidden class 'hc_1' now vec2.z = 0; // good, compiler knows this member vec2.x = 1;
계산된 배열 길이 값을 최대한 캐시하고 단일 유형을 최대한 동일한 배열에 저장합니다. for-in 구문을 사용하여 배열을 반복하는 것은 매우 느리기 때문에 피하세요. 또한, 루프 내에서 continue 및 break 문의 성능도 좋기 때문에 사용 시에는 이에 대해 걱정하지 않으셔도 됩니다. 또한 짧은 논리 부분을 가능한 한 독립적인 기능으로 분할하면 컴파일러 최적화에 더 도움이 됩니다. 또한 접두사 자동 증가 표현식을 사용하면 성능이 약간 향상될 수도 있습니다. (i++ 대신 ++i)
let badarray = [1, true, 0]; // bad, dont mix types let array = [1, 0, 1]; // happy compiler // bad choice for (let key in array) { }; // better // but always try to cache the array size let i = 0; for (; i < array.length; ++i) { key = array[i]; }; // good let i = 0; let key = null; let length = array.length; for (; i < length; ++i) { key = array[i]; };
draeImage 함수는 가장 빠른 2D 캔버스 API 중 하나이지만 편의상 모든 매개변수가 생략되었는지 주의해야 합니다. . , 성능 손실도 증가합니다:
// bad ctx.drawImage( img, x, y ); // good ctx.drawImage( img, // clipping sx, sy, sw, sh, // actual stuff x, y, w, h ); // much hax // no subpixel rendering by passing integers ctx.drawImage( img, sx|0, sy|0, sw|0, sh|0, x|0, y|0, w|0, h|0 );
위 내용은 고성능 JavaScript 작성 내용이며, 더 많은 관련 내용은 PHP 중국어 홈페이지(www.php)를 참고해주세요. .cn)!