! 제품 버전을 정확하게 입력해 주세요.
제품 버전이 정확하게 기재되어 있지 않은 경우,
최신 버전을 기준으로 안내 드리므로
더욱 빠르고 명확한 안내를 위해
제품 버전을 정확하게 입력해 주세요!

SpreadJS 성능을 최적화하는 방법 > 블로그 & Tips

본문 바로가기

SpreadJS

블로그 & Tips

SpreadJS 성능을 최적화하는 방법

페이지 정보

작성자 GrapeCity 작성일 2022-05-19 11:49 조회 1,473회 댓글 0건

본문

SpreadJS는 가장 일반적인 환경에서 까다로운 데이터 및 스프레드시트 파일을 로드하고 계산할 수 있는 높은 성능의 스프레드시트가 되도록 디자인되었습니다.

다양한 양의 수식 및 데이터를 로드하고, 계산하고, 상호 작용하는 데 더욱 빠른 성능을 얻기 위해 SpreadJS를 추가적으로 최적화할 수 있는 방법에는 여러 가지가 있습니다. 이 블로그에서는 SpreadJS 성능을 더욱 최적화할 수 있도록 팁을 공유하겠습니다.




1. Suspend/Resume Paint 메서드 사용


SpreadJS에 변경이 생길 때마다 변경 사항을 표시하기 위해 새로 고침이 수행됩니다. 한 번에 많은 사항을 변경 중이라면 이는 성능에 큰 영향을 끼칠 수 있습니다.

아래 예시는 먼저 코드에서 스프레드시트를 초기화하고 설정하는 경우입니다. 한 번에 많은 사항이 변경되고 있으므로 suspendPaint 및 resumePaint는 대부분의 경우 이 프로세스의 속도를 대폭 높일 수 있습니다.

suspendPaint 메서드를 사용하면 수정하는 동안 다시 칠하기 프로세스를 중지할 수 있습니다. 모든 변경 사항을 통합한 후에는 스프레드시트를 다시 칠하도록 resumePaint 메서드를 호출할 수 있습니다.


예시

다음 함수는 일부 샘플 값을 모든 행으로 설정합니다.

let setSampleData = (sheet,rowCount, colCount) => {
   for (let row = 0; row < rowCount; row++) {
       for (let col = 0; col < colCount; col++) {
           sheet.setValue(row, col, "data( " + row + ", " + col + " )");
      }
  }
};


아래 샘플은 542ms를 소요하여 10개의 행과 10개의 열을 업데이트합니다.

setSampleData(spread.getActiveSheet(),10,10);


하지만 suspend/resumePaint로 동일한 함수를 사용하는 경우에는 완성하는 데 19ms밖에 소요되지 않습니다.

sheet.suspendPaint();
setSampleData(sheet,10, 10);
sheet.resumePaint();


이는 기본적인 샘플이지만 더 나은 성능을 얻기 위해 날짜를 초기화하는 경우 paint 메서드를 사용하는 이점을 빠르게 확인할 수 있습니다.




2. Suspend 및 Resume CalcService 메서드 사용


수식을 변경하거나 새 수식을 시트에 추가할 때마다 SpreadJS는 변경 사항을 반영하도록 모든 수식을 다시 계산합니다.

시트 또는 파일에 많은 수식이 있거나 셀에 여러 수식을 설정하거나 로드한다고 가정하겠습니다. 이러한 경우 성능을 대폭 높이는 데 도움을 줄 수 있으므로 suspendCalcService 및 resumeCalcService 메서드를 사용할 수 있습니다.

suspendCalcService 메서드는 모든 계산을 일시 중단합니다. 모든 수식이 추가되면 resumeCalcService를 사용하여 계산을 수행합니다.

다음 코드 스니펫은 행 1부터 제공된 행 수 및 열 수까지 Sum Formula 수식을 적용합니다.

let setFormulaData = (sheet,rowCount, colCount) => {
   for (let row = 1; row < rowCount; row++) {
       for (let col = 0; col < colCount; col++) {
           sheet.setFormula(row, col, "=SUM($A$1:$J$1)");
      }
  }
};


아래 샘플은 110ms를 소요하여 10개의 행과 10개의 열의 수식을 업데이트합니다.

sheet.suspendPaint()
setDummyFormula(시트,10,10);
sheet.resumePaint()


하지만 suspendCalcService 및 resumeCalcService 메서드를 사용하는 경우에는 50-60ms밖에 소요되지 않습니다.

sheet.suspendPaint();
sheet.suspendCalcService();
setDummyFormula(sheet, 10, 10);
sheet.resumeCalcService(false);
sheet.resumePaint();


이를 통해 suspendCalcService 및 resumeCalcService 메서드를 사용하는 것의 이점을 확인하실 수 있습니다.




3. CalcOnDemand, DoNotRecalculateAfterLoad 플래그 사용

파일이 SpreadJS에 로드되면 스프레드 인스턴스는 통합 문서의 수식을 재계산하여 파일에 많은 수식이 있는 경우 성능에 영향을 줍니다. 이를 방지하기 위해 SpreadJS는 doNotRecalculateAfterLoad 플래그를 지원합니다.

SpreadJS는 셀에 변경이 생긴 후 즉시 시트를 재계산하며 calcOnDemand 플래그를 사용하여 이를 방지할 수 있습니다.

로드하는 동안 doNotRecalculateAfterLoad가 true로 설정되면 SpreadJS는 파일을 로드한 후 통합 문서를 재계산하지 않습니다.

반면에 calcOnDemand는 시트에 대한 불필요한 재계산을 방지하며 시트의 변경 사항으로 인해 셀이 영향을 받는 경우에만 계산합니다.

이러한 플래그를 사용하는 구문은 아래에 설명되어 있습니다.

workbook.fromJSON(jsonData,{
   doNotRecalculateAfterLoad:true
});
workbook.options.calcOnDemand=true;




4. 순환 종속성 감소

순환 참조라고도 하는 반복 계산을 통해 이전 계산 결과를 반복적으로 사용하여 계산을 실행할 수 있습니다. 이는 고객의 향후 투자 가치를 계산하거나 타임스탬프를 셀에 추가하는 데 유용합니다. 이러한 계산은 단일 스레드되었기 때문에 어떤 경우에는 순환 참조를 광범위하게 사용하면 성능에 영향을 줄 수 있습니다.

또다른 성능 문제는 여러 워크시트를 확장하는 순환 참조 사용이 될 수 있습니다. 시트에서 시트로의 SpreadJS 계산 엔진 이동을 만드는 대신 순환 참조를 단일 워크시트로 축소해 보면 프로세스를 최적화하고 필요하지 않은 추가 계산을 피하는 데 도움이 될 수 있습니다.

SpreadJS에서는 iterativeCalculation 속성을 사용하여 워크시트에서 반복 계산을 활성화할 수 있습니다. iterativeCalculationMaximumIterations 속성을 설정하여 수식에서 재계산해야 하는 횟수를 지정할 수도 있습니다.

또한 iterativeCalculationMaximumChange 속성을 설정하여 두 개의 계산 값 사이에 최대 변경 양을 제한할 수도 있습니다.

workbook.fromJSON(jsonData,{
   doNotRecalculateAfterLoad:true
});
workbook.options.calcOnDemand=true;




5. 대용량 Excel/JSON 파일을 가져오기 위한 증분 로드 사용

기본적으로 파일이 SpreadJS에 로드될 때마다 전체 JSON 파일은 한 번에 로드됩니다. 하지만 대량 파일을 로드하는 데는 더 오랜 시간이 걸려 성능과 사용자 환경에 영향을 줄 수 있습니다.

바로 이 때 SpreadJS 증분 로드 기능이 사용되어야 하며 증분 단계에서 통합 문서를 가져와 로드가 더욱 빨라지고 고객의 환경은 더욱 좋아집니다.

다음은 증분 로드를 사용하는 구문입니다.

function fromJSON(json) {
   spread.fromJSON(json,{
       incrementalLoading:
      {
           loading: function (progress, args) {
               console.log(progress, args.sheet.name());
          },
           loaded: function () {
               console.log("file loaded");
          }
      }
  });
}




6. SJS 표 및 명명된 범위

일상에서 이름은 사람, 개체, 지리적 위치를 참조하는 데 광범위하게 사용됩니다. 예를 들어 "위도 40.7128° N 및 경도 74.0059° W의 도시"라고 말하는 대신 간단하게 "뉴욕시"라고 말할 수 있습니다.

이와 유사하게 SpreadJS에서는 단일 셀 또는 셀 범위에 사람이 읽을 수 있는 이름을 지정하고 참조가 아닌 이름별로 이러한 셀을 참조할 수 있습니다.

SpreadJS에서 명명된 범위 및 표는 셀 참조를 훨씬 쉽게 해주는 두 가지의 고유한 기능입니다. 익숙해지는 데 다소 시간이 걸릴 수 있지만 이 기능을 사용하기 시작하면 스프레드시트 작업과 유지를 간단한 작업으로 만들 수 있다는 것을 빠르게 알 수 있습니다.

데이터 중심 대시보드 또는 피벗 테이블을 만드는 것은 데이터를 SpreadJS 표로 변환하기에 언제나 좋은 방법입니다. 구조화된 참조를 사용한다는 것은 데이터가 표에 추가될 때 수식 참조가 자동으로 조정됨을 의미합니다.

가장 큰 이점 중 하나는 표가 자동으로 명명된 범위를 추가하여 다음과 같은 수식을 이해하기 더욱 쉬울 수 있다는 점입니다.

=SUM(MyTable[Sales])


표준 명명 범위는 데이터를 더욱 쉽게 읽을 수 있도록 표 외부에서 사용될 수도 있습니다. 예를 들면 다음 구문은

=Sales Price-Cost Price


아래 구문보다 더 이해하기가 쉽습니다.

=SUM(A1:A10)-SUM(G1:G10)




7. 미사용 수식을 정적 값으로 변환

필요하지 않은 경우에는 미사용 수식을 포함하지 않는 것이 좋습니다.

많은 수식으로 인해 SpreadJS 통합 문서가 느려질 수 있으며 사용 중이 아닌 수식이 있으면 이렇게 느려지는 원인이 될 수 있습니다. 경험상 수식이 필요하지 않으면 (수식 결과를 값으로 붙여서) 정적 값으로 변환하는 것이 더 좋습니다.




8. 배열 수식 사용

배열 수식을 사용하면 여러 계산을 한 번에 수행하거나 선택한 셀 범위 내에서 하나 이상의 계산을 여러 번 수행할 수 있습니다.

이러한 수식은 유사한 많은 수식을 바꾸는 데 유용할 수 있습니다. 간단한 예시로 fn(A1, B1), fn(A2, B2), fn(A3, B3), 등부터 최대 fn(A1000, B1000)까지와 같은 여러 셀에 반복되는 함수가 있을 수 있습니다. 이것은 fn(A1:A1000, B1:B1000)으로 간소화할 수 있습니다.

같은 함수에 대한 수천 개의 호출 대신 배열 수식을 통해 단일 함수 호출로 만들면 됩니다. 아마도 짐작하셨겠지만 이는 더 적은 수식을 구문 분석하고 평가하여 로드 시간이 더욱 빨라짐을 의미합니다.

많은 배열 수식의 계산 속도를 최적화하는 핵심은 배열 수식에서 평가된 셀 및 식의 수를 가능한 한 최소화하는 것입니다.

배열 수식은 휘발성 함수와 같습니다. 휘발성인 참조되는 셀 중 하나가 변경되거나 재계산되면 배열 수식이 수식에 있는 모든 셀을 계산하고 계산이 필요한 모든 가상 셀을 평가합니다.

여러 배열 수식 내에서 동일한 함수를 반복적으로 사용해야 하는 경우 배열 수식 외부에서 계산해본 다음 결과를 참조하십시오.




9. 조건부 서식을 주의해서 사용하기

조건부 서식은 특정 기준을 충족하는 셀에 특정 서식 지정을 적용할 수 있는 기능입니다. 종종 스프레드시트에 저장된 데이터 및 정보 간에 강조 표시, 강조 또는 차별화하기 위해 색상 기반 서식 지정으로 사용됩니다.

조건부 서식은 값의 범위 외부에서 셀을 플래그 지정하기 쉽게 해주며 서식 지정은 휘발성이 매우 높을 수 있습니다. 워크시트가 재계산될 때마다 조건부 서식 규칙은 재평가됩니다. 여기에 많은 셀이 포함되면 워크시트는 매우 느려지고 반응이 없어질 수 있습니다.

예를 들어, 조건부 서식에서 ISBLANK(K1:Q200)를 사용하는 경우 범위 내 각 셀을 이동하며 이는 ISBLANK가 1200*1200 = 1,440,000회 평가됨을 의미합니다.

조건부 서식 ISBLANK(K1)로 위의 수식을 바꿀 수 있으며 조건부 서식은 기본 열 및 기본 행을 조건부 범위 내 각 셀에 맞게 조정합니다.

 



10. 명명된 스타일 사용

명명된 스타일은 시트에서 다양한 범위와 공유할 수 있는 스타일 개체입니다. 일반적으로 스타일을 적용해야 하는 다양한 셀 범위가 있는 경우 각 범위에 새 스타일 개체를 만들 수 있습니다.

하지만 이렇게 하면 메모리 문제가 발생하고 성능에 영향을 끼칠 수 있습니다. setStyle 메서드를 사용하면 호출될 때마다 새 스타일 개체가 만들어지며 수백 개의 범위에 이를 수행한 경우 일부 성능 저하를 확인할 수 있습니다.

통합 문서에 중요하게 동일한 많은 스타일이 있는 경우 먼저 스타일 개체를 만들고 원하는 스타일 속성을 적용하여 이름을 지정한 다음 명명된 스타일로 추가하는 것이 더 좋습니다. setStyle 대신 setStyleName을 사용하여 이전에 정의된 스타일 개체를 사용할 수 있습니다.

즉, 이렇게 하면 수백 개의 다양한 셀 범위에 수백 개의 다양한 스타일 개체를 보유하는 대신 공유된 몇 개의 스타일 개체만 보유하며 메모리 및 성능을 현저하게 개선할 수 있습니다.

// Example code for setting backcolor style from row 0 to row 10
let style = new GC.Spread.Sheets.Style();
style.backColor = "red"
for (let row = 0; row <= 100; row++) {
   for (let col = 0; col < sheet.getColumnCount(); col++) {
       sheet.setStyle(row, col, style.clone())
  }
}

// Using setStyleName it is more efficient
let style = new GC.Spread.Sheets.Style1();
style.name = "backColorStyle";
style.backColor = "red";
sheet.addNamedStyle("backColorStyle");
for (let row = 0; row<= 100;row++) {
   for (let col =0; col<sheet.getColumnCount(); col++) {
       sheet.setStyleName(row, col, "backColorStyle");
  }
}




11. SetValue 대신 SetArray 사용

SpreadJS에서 setValue 메서드를 사용하면 개별 셀에서 값을 설정할 수 있습니다. 이것이 정확하게 찾고 있던 것일 수 있지만 둘 이상의 셀에 값을 설정하는 경우에는 setArray 메서드를 사용하는 것이 더 낫습니다.

이 메서드를 통해 개체의 지정된 이차원 배열 값을 워크시트의 특정 셀 범위에 설정할 수 있습니다. 셀 범위의 각 셀에 setValue를 사용하는 것과 비교하여 필요한 메모리 양을 제한하여 성능을 개선하는 데 도움이 될 수 있습니다.


성능 차이를 설명하는 다음의 첨부된 샘플을 참조할 수도 있습니다.

spreadjs-performance-demo.zip


SpreadJS 최적화에 대한 더 많은 도움이 필요한 경우 문서에서 모범 사례 섹션을 확인하시기 바랍니다.




지금 바로 SpreadJS를 다운로드하여 직접 테스트해보세요!

 
  • 페이스북으로 공유
  • 트위터로  공유
  • 링크 복사
  • 카카오톡으로 보내기

댓글목록

등록된 댓글이 없습니다.

메시어스 홈페이지를 통해 제품에 대해서 더 자세히 알아 보세요!
홈페이지 바로가기

태그1

인기글

더보기
  • 인기 게시물이 없습니다.
메시어스 홈페이지를 통해 제품에 대해서 더 자세히 알아 보세요!
홈페이지 바로가기
이메일 : sales-kor@mescius.com | 전화 : 1670-0583 | 경기도 과천시 과천대로 7길 33, 디테크타워 B동 1107호 메시어스(주) 대표자 : 허경명 | 사업자등록번호 : 123-84-00981 | 통신판매업신고번호 : 2013-경기안양-00331 ⓒ 2024 MESCIUS inc. All rights reserved.