효율적인 파일 시스템 액세스(HTML)

Applies to Windows and Windows Phone

파일 시스템과 미디어 파일은 대부분의 앱에서 중요한 부분이며 가장 대표적인 성능 문제의 원인이기도 합니다. 미디어 파일에 액세스하는 데 큰 부담이 따를 수 있습니다. 미디어를 저장하고 디코딩하거나 표시하는 데 메모리 및 CPU 주기가 소모되기 때문입니다. 미디어 파일을 사용할 때 앱의 성능을 개선하는 방법을 알아봅니다.

빠른 렌더링을 위해 미리 보기 사용

미리 보기로 표시하기 위해 큰 버전의 이미지를 축소하기보다는 Windows 런타임 미리 보기 API를 사용합니다. 전체 크기의 이미지를 축소하는 것은 비효율적입니다. 앱에서 전체 크기 이미지를 읽고 디코딩한 다음 이를 확대하느라 또 시간이 소요되기 때문입니다. Windows 런타임은 효율적인 캐시가 뒷받침하는 API의 집합을 제공하여 앱에서 미리 보기에 사용할 더 작은 버전의 이미지를 신속하게 얻을 수 있게 합니다. 이러한 API를 사용하면 코드 실행 시간이 수 초 단축되고 미리 보기의 시각적 품질이 향상될 수 있습니다. 이러한 API가 미리 보기를 캐시하여 다음에 앱을 실행할 때 속도가 빨라지기 때문입니다.

이 예제에서는 사용자에게 이미지 프롬프트를 표시한 다음 이미지를 표시합니다.


// Pick an image file
picker.pickSingleFileAsync()
.then(function (file) {
  var imgTag = document.getElementById("imageTag");
  imgTag.src = URL.createObjectURL(file, false);
});


이전의 예제는 전체 크기 또는 그와 비슷한 크기의 이미지를 렌더링할 경우 문제 없지만, 이미지의 미리 보기를 표시할 때는 비효율적입니다. 미리 보기 API는 미리 보기 버전의 이미지를 반환하며, 이 버전은 앱에서 전체 크기 이미지보다 훨씬 빠르게 디코드하고 표시할 수 있습니다. 다음 예제는 getThumbnailAsync 메서드를 사용하여 이미지를 검색하고 그에 따라 미리 보기를 만듭니다.


// Pick an image file
picker.pickSingleFileAsync()
.then(function (file) {
  var properties = Windows.Storage.FileProperties.ThumbnailMode;
  return file.getThumbnailAsync(properties.singleItem, 1024);
})
.then(function (thumb) {
  var imgTag = document.getElementById("imageTag");
  imgTag.src = URL.createObjectURL(thumb, false);
});



올바른 미리 보기 크기 사용

미리 보기는 다양한 크기로 캐시됩니다. 성능과 이미지 품질을 개선하려면 앱에서 미리 보기 크기를 조정할 필요가 없도록 캐시된 크기 중 하나로 미리 보기를 표시합니다. 다음은 SingleItemPicturesView 미리 보기 모드에 대한 미리 보기 크기(픽셀)입니다.

여러 파일 속성 읽기에 대한 배치 요청

대규모 파일 모음에 액세스할 때 일반적인 name, fileTypepath 속성이 아닌 속성 값에 액세스하려는 경우 Windows.Storage.BulkAccess API를 통해 액세스합니다. Windows.Storage.BulkAccess는 다수의 파일을 처리할 때 수백 밀리초의 읽기 시간을 줄일 수 있습니다.

Windows.Storage.BulkAccess API는 여러 파일 작업을 하나의 작업으로 통합하여 더 빠르게 여러 파일과 파일 속성에 액세스할 수 있게 합니다. Windows.Storage.BulkAccess API를 사용하면 파일 시스템에서 가져온 항목의 모음(예: 이미지의 모음)을 표시하는 앱의 성능을 크게 개선할 수 있습니다.

다음 예제 집합은 여러 파일에 액세스하는 몇 가지 방법을 보여줍니다.

첫 번째 예제는 Windows.Storage.StorageFolder.getFilesAsync를 사용하여 파일 집합의 이름 정보를 검색합니다. 그러면 name 속성만 액세스하므로 우수한 성능을 얻을 수 있습니다.


var library = Windows.Storage.KnownFolders.picturesLibrary;
library.getFilesAsync(Windows.Storage.Search.CommonFileQuery.orderByDate, start, page)
.then(function (files) {
    var count = files.length;
    for (var i = 0; i < count; i++) {
        // The name property comes with every file
        console.log(files[i].name);
    }
});



두 번째 예제는 Windows.Storage.StorageFolder.getFilesAsync를 사용하고 각 파일의 이미지 속성을 검색합니다. 이 방법에서는 성능이 저하됩니다.



// Do not use: inefficient code. 
var library = Windows.Storage.KnownFolders.picturesLibrary;
library.getFilesAsync(Windows.Storage.Search.CommonFileQuery.orderByDate, start, page)
.then(function (files) {
    var count = files.length;
    for (var i = 0; i < count; i++) {
        // The dateTaken property is image specific and needs to be specially requested
        files[i].properties.getImagePropertiesAsync().then(function (props) {
            console.log(file.name + " - " + props.dateTaken);
        });
    });
});




세 번째 예제는 Windows.Storage.BulkAccess.FileInformationFactory.getFilesAsync를 사용하여 파일 집합의 이미지 속성 정보를 얻습니다. 이전의 예제보다 훨씬 우수한 성능을 얻을 수 있습니다.


var library = Windows.Storage.KnownFolders.picturesLibrary;
var query = library.createFileQuery(Windows.Storage.Search.CommonFileQuery.orderByDate);
var delayLoad = true; // Depends on if/when/how fast you want your thumbnails
var access = new Windows.Storage.BulkAccess.FileInformationFactory(
    query, Windows.Storage.FileProperties.ThumbnailMode.picturesView,
    Math.max(app.settings.itemHeight, app.settings.itemWidth),
    Windows.Storage.FileProperties.ThumbnailOptions.returnOnlyIfCached,
    delayLoad);
access.getFilesAsync(start, page).then(function (files) {
    var count = files.length;
    for (var i = 0; i < count; i++) {
        console.log(files[i].name + " - " + files[i].imageProperties.dateTaken);
        // The more 'extra' properties you're accessing, the better the perf gains
    }
});



Windows.Storage 개체(예: Windows.Storage.ApplicationData.Current.LocalFolder)에 대해 여러 작업을 수행하는 경우, 액세스할 때마다 중간 개체를 만들지 않도록 저장소 원본을 가리키는 로컬 변수를 만듭니다.

파일 읽기가 성능에 부담을 주는 경우 앱을 실행하는 동안 파일을 읽지 마세요. 대신에 앱이 실행된 후 라이브러리를 열거하고 실행할 때마다 필요한 경우 결과를 캐시합니다.

완료한 미디어 및 스트림 해제

미디어 파일은 앱에서 자주 사용하는 부담이 큰 리소스입니다. 미디어 파일 리소스 때문에 앱의 메모리 사용 공간이 크게 증가할 수 있으므로, 앱에서 더 이상 사용하지 않을 때 미디어에 대한 핸들을 해제하는 것이 중요합니다. 사용되지 않은 미디어 스트림을 해제하면 앱의 메모리 사용 공간이 크게 줄어들어 앱이 일시 중단되었을 때 종료되지 않도록 하는 데 도움이 됩니다.

예를 들어 앱에서 Blob을 사용하는 경우 URL.revokeObjectURL을 호출하여 Blob에 대한 URL을 해지해야 합니다. 그러면 기본 스트림에 대한 참조가 해제됩니다.

앱에서 RandomAccessStream 또는 IInputStream 개체를 사용하는 경우 더 이상 그 개체를 사용하지 않을 때 close 메서드를 호출하여 기본 개체를 해제해야 합니다.

메모리 누수를 막기 위해 URL.createObjectURL을 사용하여 생성된 모든 URL 해지

audio, video 또는 img 요소에 대한 미디어를 로드하는 일반적인 방법은 URL.createObjectURL 메서드를 사용하여 요소가 사용할 수 있는 URL을 만드는 것입니다. 이 메서드를 사용하면 미디어에 대한 내부 참조(Blob, File 또는 StorageFile일 수 있음)를 유지하도록 지정됩니다. 시스템에서는 이 내부 참조를 사용하여 개체를 적절한 요소로 스트리밍합니다. 그러나 시스템에서는 데이터가 필요한 시기를 알 수 없으므로 해제하도록 지정될 때까지 내부 참조를 유지합니다. 많은 양의 메모리를 사용할 수 있는 불필요한 내부 참조를 실수로 유지하기 쉽습니다.

개체를 해제할 수 있는 두 가지 방법은 다음과 같습니다.

  • URL.revokeObjectURL 메서드를 호출하고 URL을 전달하여 명시적으로 URL을 해지할 수 있습니다.
  • 한 번 사용된 후 URL을 자동으로 해지하도록 지정할 수 있습니다.

    URL을 사용하여 미디어 요소의 src 특성을 설정하면 URL이 판독된다고 확신하는 경우 개체 읽기를 완료한 후 URL을 자동으로 해지하도록 지정하려면 URL.createObjectURL 메서드의 두 번째 매개 변수(속성 모음)의 oneTimeOnly 속성을 true로 설정합니다. 예를 들면 다음과 같습니다.

    
    var url = URL.createObjectURL(blob, {oneTimeOnly: true});
    
    

    참고  재사용 불가능 URL을 사용할 경우에는 해당 URL을 사용하여 audio, video 또는 img 요소의 src 특성을 설정해야 합니다. 그렇지 않으면 내부 참조가 해제되지 않습니다. URL이 사용되는 방식과 시기를 잘 모르는 경우에는 필요할 때 URL을 만들거나 URL.revokeObjectURL을 사용하여 URL을 명시적으로 해지합니다.

    참고  다시 사용 가능한 URL을 사용할 경우 Blob 콘텐츠는 전체 충실도로만 인쇄할 수 있습니다. 따라서 Blob의 콘텐츠를 인쇄하려면 URL.createObjectURL를 호출할 때 oneTimeOnly 속성을 true로 설정하지 마세요.

필요할 때만 미디어를 만들고 포스터 이미지 사용

비디오 요소와 같은 미디어 요소는 사용하기 직전에 만듭니다. 미디어 요소를 만들려면 상당한 CPU 및 메모리 오버헤드가 발생하므로, 대량 만들기보다는 필요할 때 만드는 것이 좋습니다.

자동으로 재생되지 않는 video 요소를 만들 경우 비디오 요소의 poster 특성을 설정합니다. poster 특성을 설정하지 않을 경우 미디어 엔진에서 포스터 이미지를 얻기 위해 첫 번째 프레임을 렌더링하고자 비디오 디코딩을 시작해야 합니다.

poster 특성을 설정하는 방법의 예제입니다.


<video src = "video.h264" poster = "poster.png"></video>

ms-appdata:// 구성을 사용하여 미디어 로드

앱의 데이터 위치에 저장된 미디어를 로드하는 두 가지 일반적인 방법은 저장소 API 사용 및 ms-appdata:// 구성 사용입니다. 저장소 API는 브로커 프로세스를 통해 앱의 데이터 위치에 있는 미디어에 액세스하므로 실행하는 데 시간이 더 오래 걸립니다. 저장소 API를 사용하는 대신 동일한 프로세스로 미디어를 로드하고 훨씬 더 빠른 ms-appdata:// 구성을 사용하세요.

 

 

표시:
© 2014 Microsoft