ABOUT ME

Today
Yesterday
Total
  • [트러블 슈팅] qr코드 다운로드 시 화면이 멈추는 문제
    카테고리 없음 2024. 2. 6. 23:16

    현 magic pos 프로젝트를 진행하던중 QR code를 이미지파일로 다운로드하는 기능을 담당하였다

    근데 QR code를 개별다운로드일때는 괜찮지만 전체다운로드를 하면 화면이 멈추는 문제가 발생했다.

     

    화면이 멈추는 문제를 어떻게 해결했는지 작성해 보도록 하겠다. 

     

    QR code를 다운로드를 하는 과정은 다음과 같다

     

    QR code를 화면에 출력(qrcode.react 라이브러리 사용) -> 화면에 보여진 QR code를 이미지로 변환(domtoimage 리이브러리 사용) -> QR code 다운로드(file-server, jsZip 라이브러리 사용)

     

    기존코드

    import { QRdataType } from '@/shared/store/management';
    import { saveAs } from 'file-saver';
    import html2canvas from 'html2canvas';
    
    export const QRDownload = async (qrData: QRdataType[]) => {
      if (qrData) {
      	// qrcode를 이미지로 변환 후 다운로드 하는 await를 배열이 담기
        const qrDowndLoadDataList = qrData.map((qrcode)=>
          // 화면에 보여지는 QR code를 이미지로 변환 
          html2canvas(qrcode.qrRef, { scale: 2 })
          .then((img)=>{
          	// 이미지로 변환 한 파일을 다운로드
            img.toBlob(blob => {
              if (blob !== null) {
                saveAs(blob, `${qrcode.orderType}.jpg`);
              }
            })
          })
        )
        try {
        	하나하나담은 await코드들을 Promise.all으로 병렬적으로 처리
            await Promise.all(qrDowndLoadDataList)
        } catch (error) {
          console.error(error);
        }
      }
    };

     

     

    원인 

    QR code를 이미지로 변환 후 바로 다운로드하는것이 문제가 되었다.

     

    해결 

    QR code를 이미지로 변환하는 코드와 다운로드 하는 코드를 분리

    import { QRdataType } from '@/shared/store/management';
    import { saveAs } from 'file-saver';
    import html2canvas from 'html2canvas';
    
    export const QRDownload = async (qrData: QRdataType[]) => {
      if (qrData) {
        const qrDowndLoadDataList = qrData.map((qrcode)=>
          html2canvas(qrcode.qrRef, { scale: 2 })
        )
        try {
            await Promise.all(qrDowndLoadDataList) 
            .then((data)=>{
            data.forEatch((img)=>{
                img.toBlob(blob => {
                  if (blob !== null) {
                    saveAs(blob, `${img.orderType}.jpg`);
                  }
                })
              })
        	})
        } catch (error) {
          console.error(error);
        }
      }
    };

      

    이부분도 문제가 있다

     

    문제 

    이미지로 변환 후 다운로드를 하나하나하기 때문에 모든 파일이 다운로드하는데 거의 10초정도가 걸린다. 

     

    그래서 jsZip이라는 라이브러리를 사용하여 zip 파일로 한번에 다운로드 하였다. 

     

    최종코드

    export const QRDownloadAll = async (qrData: QRdataType[]) => {
      if (qrData) {
        try {
          // JSZip 객체 생성
          const zip = new JSZip();
          // QR code를 이미지로 변환 후 JSZip에 저장
          const qrCodeImg = qrData.map(async qrCode => {
            const file = await domtoimage.toBlob(qrCode.qrRef);
            return zip.file(`${qrCode.orderType}.jpg`, file);
          });
          // 압축파일로 다운로드
          await Promise.all(qrCodeImg).then(() => {
            zip.generateAsync({ type: 'blob' }).then(content => {
              saveAs(content, 'QRCode');
            });
          });
        } catch (error) {
          console.error(error);
        }
      }
    };

     

    이런식으로 이미지로 변환하여 압축파일로 다운로드 하니 다운로드 속도가 15초 정도에서 3~5초정도로 줄었다. 

Designed by Tistory.