metro样式 XAML 应用程序的性能提示(翻译)

 

英文原班下载:http://vdisk.weibo.com/s/89_8I

提高对用户最重要的性能指标

2012 年 5 月 21 日

摘要

本白皮书提供地铁样式 XAML 的应用程序的性能提示。它提供了指导方针为开发商提高他们在最重要的用户方案中的应用程序的性能。它假定你知道 C#、 c + + 或 Visual Basic 中的基本 XAML 编程。

此信息适用于这些操作系统: Windows ® 8 发布预览

 

本文末尾列出引用和此处讨论的资源。

免责声明: 本文档提供"为的是"。信息和在本文档中,包括 URL 和其他 Internet 网站引用、 表达的意见可能会更改恕不另行通知。一些信息,关乎预发行产品,它商业发布之前就可能会被大幅的修改。微软没有作明示或暗示的担保,此处提供的信息。您承担风险的使用它。

此处所描述的一些示例只用于说明提供,都是虚构的。没有真正的协会或连接的目的是或不应推断。

本文档并不为您提供任何 Microsoft 产品中的任何知识产权的任何法定权利。您可以复制和使用本文档为您的内部引用的目的。

© 2012年微软。保留的所有权利。

 

内容

介绍 3

其余的响应 3

UI 线程 3

使用工作线程 3

异步模式 4 的程序

取消请求时可能 4

互操作问题 6

C# 和 Visual Basic 6 的代码执行优化配置

帧速率计数器 7

确保流畅的动画 7

独立与相关动画 7

最小化透支 8

缓存静态内容 10

避免动画 web 视图 11

小心的无限动画 11

动画库 12

瞬时激活 12

提高启动感知 12

减少 XAML 解析时间 16

优化元素计数 18

最小化启动路径 18 中的托管程序集

使智能 web 请求 18

优化应用程序进程的生存期内 19

避免不必要终止 19

19 在终止之前暂停

减少内存占用量 19

恢复快 20

优雅地载入、 存储和显示数据 21

用户界面虚拟化 21

项模板 23

项目模板选择器 23

数据虚拟化 23

资源友好媒体 24

视频 24

使用全屏视频播放时可能 24

避免为嵌入式视频 25 叠加

将源设置为 MediaElement 25 的延迟

使用 MediaElement.PosterSource 26

平滑擦洗 26

尝试匹配与设备第 26 号决议的视频分辨率

推荐的格式 26

图像 27

缩放图像 27

避免无意解码 28

DirectX 28 Interop

 

简介

本白皮书将帮助您优化传统性能指标对您的最终用户有影响最大的。在过去,性能已经简单地谈的度量标准以优化而不会阻碍返回到最终用户体验的改善。通常的优化这些度量标准对用户的影响并不明显。而不是只技术来优化传统 perf 度量标准提供意见时,我们认为您按最终用户体验的一些提示这纸给使大地铁样式应用程序。

要获得正确的性能,把它作为一项功能和它计划往往设计您的应用程序用户注意不到,当你得到正确的但可能犯错是非常明显和可以降低你已经投入到辛勤工作的其他功能的所有经验时。XAML 框架已设计与性能方面的考虑,便于您为用户提供快速和流体的经验。我希望你正在读这写你的应用程序,以便您可以轻松地使用 XAML 结构在您的应用程序设计之前。如果没有,就永远不会太晚回去,并设法使你发光的应用程序。

 

剩余响应

随着应用程序的发展,用户通常期望他们能够处理更多计算的机器类型时保持响应。不同的应用程序,这意味着不同的东西。一些此转换为提供更切合实际的物理、 更快地从磁盘或 web 上加载数据、 快速呈现复杂的场景和页之间导航,在管理单元中寻找方向或迅速处理数据。正在执行的计算的类型,用户想要他们的应用程序,对他们的意见行事,消除的实例出现暂停时它"认为。"本节重点介绍了您可以使用保持一个应用程序响应用户输入时应用程序做先进的计算的 XAML 框架体系结构。

 

UI 线程

XAML 的应用程序是由事件驱动和所有组件都共享相同的线程。事件驱动的意味着,您的代码只执行一个事件后,才会发生。如果没有任何事件,您的应用程序将完成任何工作,处理过去的事件,然后坐火的事件越多的空闲等待。用户界面的框架代码 (eg。 运行布局,处理输入、 触发事件,等等) 和 app'

在同一线程执行所有的 UI 代码。只有一块的代码可以执行一次,因此如果您的应用程序代码的时间太长,无法运行,框架无法运行布局或通知其他触发的事件的应用程序。

使用后台线程

一般情况下,它是一个好的做法,以编写事件处理程序,以便他们完成快,但也有许多合法的情况,在复杂的计算,需要执行。如果您的代码需要很长的时间来执行,请尝试将其移动到后台线程异步运行。应用程序可以使用后台线程从 UI 线程执行单独的代码。这两个线程可以彼此独立地计划和 UI 线程可以返回到其他工作。

可以委托的线程执行的一个示例是工作的电脑 AI 在游戏中的计算。通常情况下,计算计算机的下一步的代码要花费大量的时间来执行。如果的主线程上执行此代码,这款应用程序不能响应额外的交互从用户代码完成执行之前。若要使您的应用程序响应速度更快,可以将该逻辑移动到要在不同的线程上执行,然后告知主线程完成计算后的委托。

异步模式的程序

为了帮助保持您的应用程序的响应,平台,提供了很多它的 Api 的异步版本。异步 API 在后台执行并返回到调用线程的一个结果。当从 UI 线程调用 API,使用异步版本,如果可用的话。使用异步模式编程的详细信息,请参阅快速入门: 使用 await 运算符用于异步编程的开发中心。

不要使无效布局传递中的布局

来精确定位的 UI 元素,彼此之间的相对屏幕上,XAML 框架布局引擎不会同步布局通过两个: 第一次来衡量每个元素,然后在屏幕坐标上对它们进行排列。避免不必要的刀,作为测量和排列在一个场景中的所有对象需要大量的计算能力。编写自定义控件时,可能失效为止铺设控制的进展,并迫使它启动另一个通行证。请确保您不是:

• 修改 MeasureOverride 中的当前控件以外的可视化树的部分

• 更改元素在 ArrangeOverride 中的尺寸

• 布局的通行证的任何部分内调用 UpdateLayout

• 更改布局影响属性如高度、 宽度、 边距、 填充、 对齐方式、 能见度等从内布局事件 (如 FrameworkElement.SizeChanged 或 FrameworkElement.LayoutUpdated。

 

文件系统

文件系统是常见的性能问题的来源。访问的文件可以是昂贵由于磁盘延迟时间和内存/CPU 周期来存储数据。当您想要访问属性值的 filesaccess 大集合的典型名称、 文件类型,以及路径属性比其他他们通过 Windows.Storage.BulkAccess 的 Api。

Windows.Storage.BulkAccess Api 组合成单个操作中,多个文件操作使它更快地访问多个文件和文件属性。这些 Api 可以显著提高性能的应用程序显示从文件系统中,如图像集合获取的项的集合。接下来的例子显示了几种方法可以访问多个文件。第一个示例使用 Windows.Storage.StorageFolder.GetFilesAsync 来检索一组文件的名称信息。这种方法提供良好的性能,因为示例访问仅名称属性。

 

StorageFolder library = Windows.Storage.KnownFolders.PicturesLibrary;

IReadOnlyList<StorageFile> files = await library.GetFilesAsync(Windows.Storage.Search.CommonFileQuery.OrderByDate);

for (int i = 0; i < files.Count; i++)

{  

    // do something with the name of each file

    files[i].Name

}

StorageFolder library = Windows.Storage.KnownFolders.PicturesLibrary;

IReadOnlyList<StorageFile> files = await library.GetFilesAsync(Windows.Storage.Search.CommonFileQuery.OrderByDate);

for (int i = 0; i < files.Count; i++)

{  

    // do something with the name of each file

    files[i].Name

}

The second example uses Windows.Storage.StorageFolder.GetFilesAsync and then retrieves the image properties for each file. This approach provides poor performance.

StorageFolder library = Windows.Storage.KnownFolders.PicturesLibrary;

IReadOnlyList<StorageFile> files = await library.GetFilesAsync(Windows.Storage.Search.CommonFileQuery.OrderByDate);

for (int i = 0; i < files.Count; i++)

{               

    ImageProperties imgProps = await files[i].Properties.GetImagePropertiesAsync();

    // do something with the date the image was taken

    imgProps.DateTaken

}

The third example uses Windows.Storage.BulkAccess.FileInformationFactory.GetFilesAsync to obtain image property info about a set of files. This approach provides much better performance than the previous example.

StorageFolder library = Windows.Storage.KnownFolders.PicturesLibrary;

StorageFileQueryResult fileQuery = library.CreateFileQuery(Windows.Storage.Search.CommonFileQuery.OrderByDate);

uint itemSize = 100; // determine an item size

bool delayLoad = true; // depends on if/when/how fast you want your thumbnails

FileInformationFactory fileInfoFactory = new FileInformationFactory(fileQuery, Windows.Storage.FileProperties.ThumbnailMode.PicturesView, itemSize, Windows.Storage.FileProperties.ThumbnailOptions.ReturnOnlyIfCached, delayLoad);

IReadOnlyList<FileInformation> files = await fileInfoFactory.GetFilesAsync() ;

for (int i = 0; i < files.Count; i++)

{

    // do something with the date the image was taken

    files[i].ImageProperties.DateTaken;

    // perf gains increase with the number of extra properties that are accessed

}

 

如果您正在执行的 Windows.Storage 对象,如 Windows.Storage.ApplicationData.Current.LocalFolder 的多个操作,创建一个本地变量来引用该存储源,以便您不要中间对象每次重新创建您访问它。

互操作问题

Windows 运行库允许开发人员在他们经过的每个语言中可用的 WinRT Api 预测选择的语言中编写 XAML 的应用程序。当编写 C# 或 Visual Basic 应用程序,这种便利之际,费用由本机代码,因为 Windows 运行时 Api 通常执行在本机代码中,并从 C# 或 Visual Basic 任何 WinRT 调用要求从托管到本机的 CLR 过渡堆栈帧和元帅函数参数表示访问的互操作性。这一开销是对于大多数应用程序可以忽略不计。但当您许多调用 (数十万到数以百万计) WinRT Api 应用程序的关键路径中,这种成本可以变得明显。时正在使用从 C# 或 Visual Basic.net 上列出地铁样式应用程序的类型不要承担这种互操作成本。

如果您的应用程序速度慢,这是互操作开销的你可以通过减少对 WinRT Api 热代码路径上的调用来提高其性能。例如,通过不断地查询的位置和尺寸的 UIElements 做吨的物理计算的游戏引擎可以通过存储从 UIElements 到局部变量的必要信息,做这些缓存的值,计算和最终结果分配回 UIElements,计算都完成后保存了很多时间。另一个例子: 如果集合频繁访问由 C# 或 Visual Basic 代码,然后它会更有效地使用 System.Collections 的命名空间,从集合中的内容,而不是从 Windows.Foundation.Collections 命名空间的集合。

C# 和 Visual Basic 执行优化的代码

C# 或 Visual Basic 编写的应用程序会有不同的启动性能,首次安装和在稳定状态。当第一次到用户的计算机上安装您的应用程序,则它执行使用 CLR 的实时 (JIT) 编译器。这意味着第一次执行方法时要等待要编译。后来,一个 pre-compilation 的服务 (NGEN) 预编译所有用户的机器已加载的模块。这通常运行的安装,24 小时之内,但也可能需要更长时间,具体取决于计算机的使用模式。此服务运行后大多数方法不再需要 JIT 编译和您的应用程序受益于改进的启动性能。还能有几种方法需要 JIT 编译在运行时,但会有较少 NGEN 服务已运行之后。

如果您想要测量你的应用程序的启动性能,然后测量 JIT 与 NGEN。您可以强制 NGEN 的第一次运行应用程序,然后调用 pre-compilation 任务使用此命令行:

c:\Windows\Microsoft.Net\framework\v4.0.30319\ngentask.exe /runtimewide

此任务将预编译任何应用程序使用了和缺少 NGEN 映像,并可能需要很长时间运行的第一次。

帧速率计数器

XAML 框架附带的帧速率计数器,您可以启用通过 DebugSettings.EnableFrameRateCounter 属性。但是,此计数器生成的数字是准确的仅在 UI 线程创建帧时。帧速率仍在上次测量值后应用程序进入视觉空闲状态。例如,如果您的应用程序具有 25 帧/秒的帧速率,它执行复杂的计算,以创建一些 UI 时,它仍在这一数字如果它立即停止生产或更改任何的视觉效果。

确保流畅的动画

Windows 8 的应用程序的一个关键方面是光滑的相互作用。这包括你手指触摸、 平稳过渡和动画和提供输入的反馈的小运动坚持。在 XAML 框架中有一个线程专用的组成及动画的应用程序的视觉效果 (组成线程)。组成的线程分离 UI 线程 (框架和开发人员代码) 允许 XAML 的应用程序,以实现一致的帧速率和平滑的动画,而不考虑复杂布局传递或扩展计算。

本节说明如何使用组成的线程来保持应用程序的动画黄油顺利。请参阅上一节,了解在执行密集型计算时增加应用程序的响应能力。

独立与相关的动画

动画可以计算从开始在其创作的时间结束。有时对正在进行动画处理的属性的更改不会影响一个场景中的对象的其余部分。这些称为独立动画和他们组成线程而不是在 UI 线程上运行。这可以保证他们保持平稳,因为组成的线程在一致的节奏中更新。所有这些都能保证是独立。

• 对象动画使用关键帧

• 零工期动画

Canvas.Left/Top •

UIElement.Opacity •

• SolidColorBrush.Color 应用于许多属性时

• 子属性的

UIElement.RenderTransform o

UIElement.Projection o

o UIElement.Clip RectangleGeometry

依赖动画影响布局,并不能没有额外输入从 UI 线程计算。这些动画包括对像的宽度和高度属性进行修改。默认情况下依赖动画将不会运行,需要从应用程序开发人员选择加入。当启用时,它们运行顺利如果在 UI 线程保持畅通 ;但他们开始口吃如果框架或应用程序做了大量的其他工作。

XAML 框架已努力使几乎所有的动画独立,默认情况下 ;但有一些您可以禁用此优化的操作。可更改警告时:

• 将 EnableDependentAnimation 属性设置将允许一个相关的动画在 UI 线程上运行。这些动画转换为一个独立的版本。例如动画 ScaleTransform。ScaleX/ScaleTransform。ScaleY 而不是对象的宽度/高度。不要害怕要缩放对象 (如图像和文本。框架适用于双线性缩放仅在 ScaleTransform 正在进行动画处理。图像/文本将会在最后的大小,以确保它始终是脆的 rerasterized。

• 每帧更新,这些都有效地依赖动画的制作。一个例子应用转换在 CompositonTarget.Rendering 事件的处理程序。

· 运行的任何动画被视为独立的 CacheMode 元素中 = BitmapCache。这被认为依赖,因为缓存必须将每个帧的 rerasterized。

 

最小化透支

让每个形状绘制到屏幕缓冲区,比挑选闭塞的部分对象的图形硬件快得多。可以减少的图形硬件所做的工作总量不绘图完全遮蔽的元素。当然你不能跟踪的所有对象的可见性,但有几个方便的规则防止相同的像素被不必要地吸引多倍。

• 完全被别人遮盖的折叠元素。

• 创建复合元素而不是分层对象来创建一种效果

<!--Bad: XAML that creates a two toned background for the Grid element.

    The top half is black and the bottom half is gray. This is created by

    placing a semi transparent white Rectangle in the bottom half of the

    grid and letting the black background of the Grid blend with the with

    Rectangle. This design causes the graphics card to write all pixels

    on the screen black when it draws the Grid and then write all of the

    pixels for the white Rectangle (half the size of the screen). The total

    number of pixels filled is 1.5x screen resolution. -->

<Grid Background="Black">

    <Grid.RowDefinitions>

        <RowDefinition Height="*"/>

        <RowDefinition Height="*"/>

    </Grid.RowDefinitions>

    <Rectangle Grid.Row="1" Fill="White" Opacity=".5"/>

</Grid>

<!--Good: XAML that creates the same two toned background for the Grid

    element, but with 33% less pixel fills. The only things that are drawn

    are the top Rectangle (half the screen) and the bottom Rectangle

    (half the screen). The total number of pixels filled is 1 x screen

    resolution. The background for the grid is never drawn because it’s

    transparent. -->

<Grid>

    <Grid.RowDefinitions>

        <RowDefinition Height="*"/>

        <RowDefinition Height="*"/>

    </Grid.RowDefinitions>

    <Rectangle Grid.Row="1" Fill="Black"/>

    <Rectangle Grid.Row="1" Fill="#FF7F7F7F"/>

</Grid>

  • Don’t use the same color for foreground and background elements. Instead don’t set color of the foreground elements and let the background color bleed through.

<!--Bad: This XAML creates a GridView with a blue background and sets the

    background of the DataTemplate for each item to be blue too. Setting

    the background (to anything except for transparent) on the DataTemplate

    causes pixels to be filled for the background of each item. In this

    case it is unnecessary because the background of the Gridview and the

    background of the items is the same color. -->

<GridView Background="Blue">

    <GridView.ItemTemplate>

        <DataTemplate>

            <!--This background is unnecessary and can be removed. -->

            <Grid Background="Blue"/>

        </DataTemplate>

    </GridView.ItemTemplate>

</GridView>

  • Use a Border element when drawing a border around an object instead of using other objects to impersonate a border.

<!--Bad: Pixels for both the Grid and the TextBox are filled, most of

    which overlap. -->

<Grid Background="Blue" Width="300" Height="45">

    <Grid.RowDefinitions>

        <RowDefinition Height="5"/>

        <RowDefinition/>

        <RowDefinition Height="5"/>

    </Grid.RowDefinitions>

    <Grid.ColumnDefinitions>

        <ColumnDefinition Width="5"/>

        <ColumnDefinition/>

        <ColumnDefinition Width="5"/>

    </Grid.ColumnDefinitions>

    <TextBox Grid.Row="1" Grid.Column="1"></TextBox>

</Grid>

<!--Good: The XAML framework draws the border around the TextBox without

    creating an overlapping pixels to fill. -->

<Border BorderBrush="Blue" BorderThickness="5" Width="300" Height="45">

    <TextBox/>

</Border>

• 要注意你的边距大小。如果他们的利润将扩展到其他人的渲染边界造成的相同的像素来绘制两次,两个相邻元素可能会意外地重叠。

 

DebugSettings.IsOverdrawHeatMapEnabled 属性可以帮助您确定何时何地 app 绘图在另一个对象。不是不寻常的找对象进行绘制你不知道,甚至在场景中 !

缓存静态内容

经常从概念上讲离散元是由许多重叠子形状组成。每个地点原因透支的元素重叠。您可以通过设置 CacheMode 消除这对父级包含整个概念元素的 UIElement = BitmapCache。这样做允许的框架,以呈现为位图元一次,然后使用该位图对象的位置,而不是 rerendering 每一帧的子对象。

表示您正在创建一个看起来像一个三个圆圈维恩图的徽标。您可以使用一些简单的 XAML 快速创建此对象。

<Canvas Background="White">

    <Ellipse Height="40" Width="40" Fill="Blue"/>

    <Ellipse Canvas.Left="21" Height="40" Width="40" Fill="Blue"/>

    <Ellipse Canvas.Top="13" Canvas.Left="10" Height="40" Width="40" Fill="Blue"/>

</Canvas>

很明显标志的重叠的子元素。每次它绘制的图形硬件花灌装的像素每圈的时间。下一个图像显示区在透支发生。暗红色表示较高数量的 overdraw。

因为该徽标是一个完整的对象是总是得出相同的方式,我们可以消除额外的透支一次创建元素、 缓存,然后使用缓存的版本,而不绘制每个圆圈。将 CacheMode 属性设置在画布上没有正是这样。

<Canvas Background="White" CacheMode="BitmapCache">

    <Ellipse Height="40" Width="40" Fill="Blue"/>

    <Ellipse Canvas.Left="21" Height="40" Width="40" Fill="Blue"/>

    <Ellipse Canvas.Top="13" Canvas.Left="10" Height="40" Width="40" Fill="Blue"/>

</Canvas>

 

如果任何子形状的动画因为每次这些元素之一更改,需要重新生成位图缓存,不要使用这种技术。

避免动画 web 视图

由 XAML 框架不直接呈现在 web 视图控件内的 web 内容,它需要额外的工作将由组成与现场的其余部分。这种额外的工作相加时动画在屏幕周围的控制和潜在可以引入同步问题 (eg。 html 内容可能不移动与其余的 XAML 内容同步在页面上)。当您需要进行动画处理 web 视图控件时,它用交换 WebViewBrush 动画的持续时间。

小心的无限动画

大多数动画时执行指定的时间量但将 Timeline.Duration 属性设置为永远允许无限期地运行动画。我们建议尽量避免使用无限的动画,因为他们不断占用的 CPU 资源,并可以防止 CPU 走进一个低功率或空闲状态,使其更快地耗尽。

添加 CompositionTarget.Rendering 的处理程序是类似于运行一个无限的动画。通常在 UI 线程处于活动状态,仅当有工作要做,但此事件添加处理程序强制它运行每个帧。有没有工作做时不需要再, 重新注册时,请移除处理程序。

动画库

PVL 提供了动画库,它提供了高性能、 平滑的动画,并具有一致的外观与其他 Windows 动画。此库支持许多常见的动画方案,如动画应用程序的第一个视图和创建状态和内容转换。我们建议使用此动画库尽可能提高性能和与 Windows 8 平台的一致性。

瞬时激活

激活期间是之间的时间,当用户选择要启动的应用程序,并时刻 app 是功能的用户。这是一个关键时刻,因为它是对您的应用程序的用户的第一印象。他们期望从系统和应用程序的即时和连续的反馈。系统和/或应用程序被认为是折断或差设计时应用程序快速做不启动。更糟的是,如果一个应用程序的时间太长,无法激活,它可能会被打死流程生命周期管理器 (PLM) 或由用户卸载。

但最简单的应用程序都需要时间来加载资源、 分析 XAML、 设置数据结构,和在激活运行逻辑的可量。这一节分析激活的过程由闯入分三个阶段。它还提供提示减少所花费的每个阶段和技术对用户进行每个阶段更可口的时间。

提高启动感知

让我们使用一个简单的在线游戏来标识每个阶段的启动和不同的技术,在整个过程中为用户反馈。对于游戏或任何其他应用程序,激活的第一阶段的一个示例是,用户应用程序的瓷砖和游戏开始的运行应用程序的代码点上攻丝之间的时间。在这段时间的系统不会向用户指示正确的应用程序开始显示的任何内容。提供初始屏幕给系统此非常的内容。这场比赛然后通知用户激活的第一阶段已完成使用自己的 UI 替换静态初始屏幕,当它开始时运行的代码。

激活的第二阶段包括创建和初始化结构应用程序的关键。如果一个应用程序可以快速创建其初始 UI 的可用的数据后激活的第一阶段,第二阶段是微不足道,应显示在用户界面。否则我们推荐这款应用程序显示加载页,虽然它初始化。

正在加载页的复杂性由开发人员和可能非常简单,显示进度栏/环。最重要的行动是 app 指示它预成为响应之前的任务。在这场比赛,它想要显示其初始屏幕,但用户界面需要一些图像和声音可从磁盘加载到内存中。这项任务需要几秒钟,所以 app 放心,它已不挂使用加载页显示一个简单的动画游戏的主题有关的替换该初始屏幕的用户。

这个游戏有少量的信息来创建交互式 UI 的替换正在加载页后,将开始第三阶段。此时可用的在线游戏的唯一信息是从磁盘加载的应用程序的内容。这场比赛可以配备足够的内容来创建交互式用户界面 ;但是,因为它是一个在线游戏不会功能直到它连接到互联网,并下载一些额外的信息。直到它有所有信息需要功能,用户可以进行交互的用户界面,但需要从 web 的额外数据的功能应该某种形式的内容仍在加载的反馈。

它可能需要一些时间为一个应用程序,所以是很重要的功能可尽快成为功能齐全。

现在,我们已经确定了活化在在线游戏中的三个阶段,让我们将其绑定到实际的代码。

第 1 阶段

应用程序启动之前,它需要告诉系统它想要作为初始屏幕显示。它是通过提供闪屏中的一个元素将应用程序的清单,如示例图像和背景的颜色。这款应用程序开始激活后,Windows 将显示此。

Package.appxmanifest

<Package …>

  …

  <Applications>

    <Application …>

      <VisualElements …>

        …

        <SplashScreen Image="Images\splashscreen.png" BackgroundColor="#000000" />

        …

      </VisualElements>

    </Application>

  </Applications>

</Package>

仅用于初始化是关键应用程序的数据结构,请使用应用程序的构造函数。只有第一次运行应用程序时,并不一定每次应用程序处于激活状态,被称为构造函数。例如,该构造函数不会呼吁已运行,放在背景,并通过搜索合同然后激活的应用程序。

第 2 阶段

有很多理由要激活的应用程序的每个您可能希望以不同的方式处理。您可以重写 OnActivated、 OnCachedFileUpdaterActivated、 OnFileActivated、 OnFileOpenPickerActivated、 OnFileSavePickerActivated、 OnLaunched、 OnSearchActivated、 和 OnShareTargetActivated 的方法来处理每个激活的原因。应用程序在这些方法中应该做的事情之一就是创建一个用户界面,将它分配给 Window.Content,,然后调用 Window.Activate。此时的闪屏将替换为应用程序创建的视觉。此用户界面可能也会加载屏幕或应用程序的实际用户界面如果足够信息可用在创建它的激活。

 

public partial class App

{

    …

    // one handler for regular activation

    async protected override void OnLaunched(LaunchActivatedEventArgs args)

    {

        base.OnLaunched(args);

        // Do an asynchronous restore based on generic launch

        // create the ExtendedSplash screen which serves as a loading page while the

        // reader downloads the section information

        ExtendedSplash eSplash = new ExtendedSplash();

        // set the content of the window to the extended splash screen

        Window.Current.Content = eSplash;

        // notify the Window that the process of activation is completed

        Window.Current.Activate();

    }

    // a different handler for activation via the search contract

    async protected override void OnSearchActivated(SearchActivatedEventArgs args)

    {

        base.OnSearchActivated(args);

        // Do an asynchronous restore based on Search activation

        // the rest of the code is the same as the OnLaunched method

    }

    …

}

    ----

    partial class ExtendedSplash

    {       

        public ExtendedSplash()

        {

            InitializeComponent();

             // start downloading the data necessary for the initial UI on a background thread.

             Task.Run(() => DownloadData());

        }

        void DownloadData()

        {

            // download data to populate the initial UI with

            // create the first page

            MainPage firstPage = new MainPage();

            // add the data just downloaded to the first page

            // replace the loading page, which is currently set as the window’s content, with the initial UI for the app

            Window.Current.Content = firstPage;

        }

    }

显示加载页在处理程序中激活的应用程序开始工作,在后台创建用户界面。已创建该元素之后将替换窗口内容,这是目前在加载屏幕。这是关键的应用软件,扩展的初始化期间显示加载页。除了提供有关激活过程的确定反馈,如果在激活过程的开始 15 秒内不调用 Window.Activate 过程将被终止。使用扩展的闪屏的示例,请参见初始屏幕示例。

第 3 阶段

已显示的初始用户界面并不意味着这款应用程序是完全准备好使用。在我们的游戏,初始用户界面显示的功能,需要从互联网数据的占位符。此时游戏下载使应用程序功能齐全和逐步启用功能,如数据获取所需的额外数据。

有时的大部分内容所需的激活可以与应用程序一起打包。这就是一个简单的游戏的情况。这使得激活过程很简单。但许多程序 (例如新闻读者、 照片观众等) 必须拉成为功能的网络信息。此数据可以很大,并需要相当长的时间来下载。此数据在激活过程中收购了如何对感知性能的应用程序能产生巨大的影响。

可以显示加载页,或更糟的是,闪屏时,如果应用程序试图下载它需要的功能,在整个数据集的分钟阶段一个或两个激活。这使得应用程序看起来像被挂起或导致它被终止系统。我们建议最少的数据,以显示占位符元素交互式 UI 中第 2 阶段,然后逐步加载数据,在第 3 阶段中替换占位符元素应用程序下载。处理数据的详细信息,请参阅一节上有效载荷、 存储和显示数据。

如何准确的应用程序启动时的每个阶段的反应是完全取决于您,但提供用户尽可能多反馈 (闪屏,加载屏幕上,数据加载时 UI) 尽可能让用户感觉像一个应用程序,并作为一个整体,系统超快的速度。

XAML 解析时间缩短

分析 XAML 和在内存中创建相应的对象可能具有深元素树的复杂用户界面,非常耗费时间。这就是为什么我们推荐您加载只有过去的启动过程中获取所需的 XAML。加载页显示第一视觉所需所要做的最简单的事情。仔细检查你的第一页的 XAML,以确保它包含它所需要的一切。如果您引用的控件或样式的定义是什么地方其他框架将分析该文件太。

<!--This is the first page an app displays. A resource used by this page,

TextColor, is defined in AppStyles.xaml which means that file must be parsed

when this page is loaded. Because AppStyles.xaml contains many app wide

resources, it takes time to parse all of those resources that are not

necessary to start the app. -->

<Page ...>

    <Grid>

        <TextBox Foreground="{StaticResource TextColor}" />

    </Grid>

</Page>

Contents of AppStyles.xaml

<ResourceDictionary …>

    <SolidColorBrush x:Key="TextColor" Color="#FF3F42CC"/>

    <!--many other resources used across the app and not necessarily for startup.-->

</ResourceDictionary>

 

修剪资源字典。将应用程序范围的资源存储在应用程序对象,以避免重复。但是,将特定的资源移动到单个页面,不需要在启动时对该页面的资源字典。这会减少 XAML 时解析应用程序启动和招致解析该 XAML,仅当特定的页导航到的成本。

<!--Bad: Don’t include XAML that is specific to a page in the app’s

resource dictionary. The app incurs the cost of parsing resources that

are not immediately necessary at startup instead of on demand. Move

these page specific resources to the resource dictionary for that page.-->

<Application …>

    <Application.Resources>

        <SolidColorBrush x:Key="DefaultAppTextColor" Color="#FF3F42CC"/>

        <SolidColorBrush x:Key="HomePageTextColor" Color="#FF3F42CC"/>

        <SolidColorBrush x:Key="SecondPageTextColor" Color="#FF3F42CC"/>

        <SolidColorBrush x:Key="ThirdPageTextColor" Color="#FF3F42CC"/>

    </Application.Resources>

</Application>

XAML for the home page of the app

<Page ...>   

    <StackPanel>

        <TextBox Foreground="{StaticResource HomePageTextColor}" />

    </StackPanel>

</Page>

XAML for the second page of the app

<Page ...>

    <StackPanel>

        <Button Content="Submit" Foreground="{StaticResource SecondPageColor}" />

    </StackPanel>

</Page>

<!--Good: All page specific XAML has been moved to the resource dictionary

for the page on which it’s used. The home page specific XAML was not moved

because it must be parsed at start up anyway. Moving it to the resource

dictionary of the home page wouldn’t be bad either. -->

<Application …>

    <Application.Resources>

        <SolidColorBrush x:Key="DefaultAppTextColor" Color="#FF3F42CC"/>

        <SolidColorBrush x:Key="HomePageTextColor" Color="#FF3F42CC"/>

    </Application.Resources>

</Application>

XAML for the home page of the app

<Page ...>   

    <StackPanel>

        <TextBox Foreground="{StaticResource HomePageTextColor}" />

    </StackPanel>

</Page>

XAML for the second page of the app

<Page ...>

    <Page.Resources>

        <SolidColorBrush x:Key="SecondPageTextColor" Color="#FF3F42CC"/>

    </Page.Resources>

   

    <StackPanel>

        <Button Content="Submit" Foreground="{StaticResource SecondPageTextColor}" />

    </StackPanel>

</Page>

 

检查自动生成 XAML 总是一个好主意。有时由设计器工具创建的标记包含未使用的元素一样呈现变换。使你有较少的 XAML 要进行语法分析,您可以删除这些元素。一件事要看是设置为其默认值的属性。解析器已经做到这一点上创建该对象。显式设置属性诱使不必要的属性赋值。如果发生一些事情要绑定到该属性,然后更改通知的气泡通过产权制度。

优化元素计数

XAML 框架旨在显示数以千计的对象,但减少页面上的元素的数量始终使您的应用程序的布局和更快地呈现的场景。有几个技巧,您可以使用相同级别的视觉复杂性的同时减少一个场景元素计数。

· 避免不必要的元素。例如,小组提供而不是将各元素的后面的有色的矩形放在该面板的背景颜色设置背景属性。

<!--bad XAML uses an unnecessary Rectangle to give the Grid a black background. -->

    <Grid>

        <Rectangle Fill="Black"/>

    </Grid>

<!--good XAML uses the Grid’s background property, -->

    <Grid Background="Black" />

· 删除,因为它们隐藏 / 透明,不可见的元素或折叠它们,如果他们需要采取其他可视状态。

• 如果您重复使用相同的基于矢量元素多次,使它的图像。基于向量的元素是可能会更昂贵,因为 CPU 需要单独创建每个单独的元素。图像需要进行解码只有一次。

 

最小化启动路径中的托管程序集

重用的代码往往来自中包括在项目中的模块 (dll) 的形式。加载这些模块需要访问该磁盘,以及你可以想象,这样做的成本因此可以加起来。这已影响最大的冷启动时,但它能太温暖启动时产生影响。在 C# 和 Visual Basic,CLR 尝试由加载程序集对需求的成本尽可能多的延迟。那就是,CLR 并不加载模块,直到执行的方法引用它。引用只是所必需的启动代码在应用程序启动,这样,CLR 并不加载这些模块的程序集。如果您有不必要的引用您启动路径中的未使用的代码路径,您可以重构出这些代码路径的其它方法,以避免不必要的负荷。

另一种方法,以减少模块加载是结合您的应用程序的模块。加载一个大型组件通常需要更少的时间比加载两个小的。这并不总是可能的和你应该合并模块,只有当它不会有实质性的区别于开发人员的效率或代码可重用性。你可以使用 PerfView 或 Windows 性能分析器 (WPA) 工具,找出哪些模块在启动时加载。

使智能 web 请求

如 XAML、 图像和重要的应用程序的磁盘操作的任何其他文件也比网络操作更快,你可以大大提高包装本地,其内容由应用程序的加载时间。如果应用程序需要在初始化时的特定文件,您可以减少总体启动时间从磁盘而不是从远程服务器中检索它加载它。

优化应用程序进程的生存期内

Windows 8 过程生存期系统可以暂停或终止应用程序的各种原因。此过程被为了快速返回到它被暂停或终止之前的状态的应用程序。当以最佳方式完成,用户不会意识到这款应用程序永远停止运行。本节讨论了几个技巧,应用程序可以用来帮助简化应用程序的生存期转换的系统。

避免不必要的终止

在终止之前暂停

在将应用程序的生命周期中的一件大事是被停牌。当用户将其移动到背景或系统进入低功耗状态,可以暂停应用程序。这款应用程序被暂停时,它引发悬浮事件,并已达 5 秒钟,以保存其数据。如果应用程序的悬浮事件处理程序不会在 5 秒内完成,系统将假定应用程序已停止响应,并终止它。终止应用程序都必须经过长时间启动过程中再次而不是当用户切换到它时立即加载到内存。

如有必要将序列化

许多应用程序 re-serialize 所有的数据,即使未更改的数据。这将需要额外的时间来进行序列化和保存数据,再加上额外的时间来阅读和反序列化它,当再次激活应用程序。相反,我们建议这款应用程序确定是否实际更改其状态,并若然,只进行序列化和反序列化数据的更改。确保发生这种情况在要序列化的数据,因为它改变了一个好方法。当您使用此方法时需要悬挂在序列化的一切已经保存因此没有工作要做,并且应用程序挂起迅速。

减少内存占用量

系统会尝试尽可能在内存中保留尽可能多的暂停应用程序,以便用户可以快速、 可靠地它们之间切换。当一个应用程序暂停,并停留在该系统的内存中时,可以快速将其到前台为用户进行交互,而无需显示初始屏幕或执行冗长加载操作。如果没有足够的资源来在内存中保留一个应用程序,应用程序将终止。这两个原因使内存管理重要:

• 尽可能多的内存释放悬挂在尽可能最大限度减少机会您的应用程序由于缺乏资源而终止,虽然它暂停。

• 总体减少您的应用程序使用的内存减少机会,其他应用程序终止时,他们都暂时停止。

 

一般清理

某些对象例如文件和设备,占用大量的内存。我们建议期间暂停,一个应用程序释放这些对象的句柄,然后重新创建时所需的句柄。这也是清除任何恢复应用程序时,不会有效的缓存的好时机。C# 应用程序以您的名义的 XAML 框架运行附加步骤是垃圾回收。这可以确保不再在应用程序代码中引用的任何对象被释放。

巧妙使用画笔

XAML 框架试图对常用的缓存对象,以便他们可以尽可能经常重复使用。这样做可以防止 XAML 的一个行动声明多个模板中相同的画笔。相反,创建常用的刷子作为根 ResourceDictionary 元素,然后引用该模板中的对象。XAML 可以跨不同的模板使用相同的对象和内存消耗将会减少。这种伎俩是特别重要的 GradientBrushes,哪些比定期刷更贵。

<!--Bad XAML defines the same brush in multiple controls.-->

<Page ...>

    <StackPanel>

        <TextBox>

            <TextBox.Foreground>

                <SolidColorBrush Color="#FF3F42CC"/>

            </TextBox.Foreground>

        </TextBox>

        <Button Content="Submit">

            <Button.Foreground>

                <SolidColorBrush Color="#FF3F42CC"/>

            </Button.Foreground>

        </Button>

    </StackPanel>

</Page>

<!--Good XAML defines the common brush once and references it as needed. If

controls in other pages used this brush, it should be moved to the app resources

so it is not duplicated across multiple pages. -->

<Page ...>

    <Page.Resources>

        <SolidColorBrush x:Key="TextColor" Color="#FF3F42CC"/>

    </Page.Resources>

   

    <StackPanel>

        <TextBox Foreground="{StaticResource TextColor}" />

        <Button Content="Submit" Foreground="{StaticResource TextColor}" />

    </StackPanel>

</Page>

快速恢复

当用户将其移动到前台或脱离低功耗状态,系统的时候就可以恢复暂停的应用程序。当一个应用程序从暂停状态恢复的时它会继续从那里当它被暂停。没有应用程序数据丢失因为它存储在内存中,即使是这款应用程序被暂停一长段时间。

大多数应用程序不需要恢复的事件处理程序。您的应用程序恢复时,变量和对象具有完全相同的状态时应用程序被暂停。注册一个恢复的处理程序,如果您需要更新数据或可能已更改之间的时间你的应用程序的对象暂停只,当它被恢复如: 内容 (例如,更新饲料的数据),网络连接,这可能已经过时,或者如果您需要重新获得对一个设备 (如网络摄像机) 的访问。

优雅地载入、 存储和显示数据

操作列表和其他信息的集合是几乎所有的应用程序的主要方案: 照片视图具有收藏的照片 ;读者有收藏的文章、 书籍、 故事 ;购物应用程序有集合的产品 ;游戏有收藏的成绩 ;消息传递应用程序有消息的集合。

集合是无处不在有两个关键性能因素,你必须考虑。第一是时间的创建项目在 UI 线程上花费量。更快的项目可以实例化,数据绑定,并奠定了出来,用户可以更快潘在瞬间看到屏幕上显示的项集合。

第二个 perf 考虑是内存的集合使用和存储数据集所需的空间中的呈现的项目显示量。暂停应用程序获取的机会终止的活动应用程序所使用的内存量上升。这也是真正为获取终止它暂停时的活动应用程序的机会。一般情况下,高内存的使用会降低系统上的所有应用程序的体验。

本节讨论中可以被利用的应用程序,以减少资源致力于操纵收藏量的 XAML 平台的功能。

用户界面虚拟化

用户界面虚拟化是最重要的改进,您可以对收藏的性能进行。虚拟化用户界面创建表示对需求的集合中的每个项的 UI 元素。想象一下在列表控件中显示 1000年项的应用程序。没有任何理由要创建的每个项目的用户界面,并保留在内存中。永远不会一次显示所有 1000年项并很有可能,用户将快速找到他在找什么在列表的顶部附近,并永远不会想要看到的所有项目的其余部分。它本来废物的处理能力,列表中被实例化时创建的所有项目和浪费内存列表中的生存期内保持周围的所有项目的用户界面。

标准 ItemsControls 预制棒 UI 虚拟化您的名义。项目都远未可见 (几个项目之前和之后的可见的项目进行高速缓存,以提高性能),XAML 生成该项目的用户界面,并保留在内存中。当不再就时可能会显示该项目时,XAML 重复使用的内存,用来显示另一个项目,这就是正在显示的项目。有时应用程序设计需要 ItemsControl 用来组织项目的默认面板为另一个开关。只要新的面板支持虚拟化用户界面,该控件将继续免费执行此优化。标准的虚拟化面板包括 WrapGrid 和 VirtualizingStackPanel。用非虚拟化面板 (VariableSizedWrapGrid 和 StackPanel) 替换在 ItemsControl 中的默认面板将禁用该控件的用户界面虚拟化。

<!--This ListView doesn’t perform UI virtualization because the default items panel

has been replaced with a panel that doesn’t support UI virtualization. -->

<ListView>

    <ListView.ItemsPanel>

        <ItemsPanelTemplate>

             <StackPanel/>

        </ItemsPanelTemplate>

    </ListView.ItemsPanel>

</ListView>

<!--This ListView performs UI virtualization because the default items panel has

Been replaced with a panel that does support UI virtualization -->

<ListView>

    <ListView.ItemsPanel>

        <ItemsPanelTemplate>

            <VirtualizingStackPanel/>

        </ItemsPanelTemplate>

    </ListView.ItemsPanel>

</ListView>

因为框架必须创建的元素有可能会显示用户界面虚拟化的关键概念的视区。一般情况下,ItemsControl 的视区是逻辑控制的程度。例如,ListView 视区是 ListView 元素的高度与宽度。某些面板告诉他们的孩子他们可以使用尽可能多的房间可显示其内容,如他们喜欢。当虚拟化的 ItemsControl 放在这些对象中的一个时,它认为它有足够的空间来显示所有的项目。每个项目将 UI 是即使关闭屏幕呈现某个地方。

Scrollviewers 和网格,自动调整大小的行列是给孩子们无限的空间的面板的好例子。开发人员可以通过显式设置 ItemsControl 的宽度或高度保留在这些方案中用户界面虚拟化。

<!--This ListView won’t perform UI virtualization because the parent ScrollViewer

gives the ListView as much vertical space as it needs. Thus the ListView shows all

of its elements even though they may get rendered off screen. -->

<ScrollViewer VerticalScrollMode="Enabled">

    <ListView/>

</ScrollViewer>

<!--This ListView performs UI virtualization because even though its parent

ScrollViewer gives the ListView as much vertical space as it needs, the ListView

uses only 400 pixels. It fits as many items as it can into that space and then

virtualizes the rest. -->

<ScrollViewer VerticalScrollMode="Enabled">

    <ListView Height="400" />

</ScrollViewer>

当前 UI 虚拟化不是支持的组中。如果性能是一个问题,将您的组的大小限制,或如果您有大量项目在组中,使用另一种显示策略对于组详细信息视图,像语义放大。

项模板

除了只创建的对象是接近视区 (ie。用户界面虚拟化),确保实际创建的对象不是不必要的复杂。降低 XAML 复杂性强调在启动时部分,而且适用于滚动和太平移。随着项目移动全景到视图中,框架必须与正在移动全景到屏幕上的项目的数据更新缓存的项模板中的字段。降低这些 XAML 树的复杂性可以还清两个存储元素所需的内存量和数据所需的时间量绑定和传播模板内的各个属性。这减少了在 UI 线程必须做,这有助于确保项目出现立即集合中用户可快速沿的工时量。

这是一个类似的概念,"优化元素计数"一节中所讨论的所以那里看看代码示例。

项目模板选择器

项目模板选择器介绍中的项目呈现两个额外的步骤。第一,XAML 框架实例化只足够项目模板,以显示已接近正在显示的项目。缓存弥补这些模板的各个元素并将其当他们靠近正在显示更新数据的其他项目。这可以节省时间的实例化项目模板。当您使用项目模板选择器时,没有更长时间的高速缓存项模板因为它根本不知道哪种类型的模板需要直到项目模板选择器的框架可以运行。

这将我们带入第二步,实际上确定要使用的项目模板。在您的项目模板选择器中的代码必须为每个项目,这就是正在显示运行。这是很有帮助时所显示的数据是本质上是不同的 ;但这额外的步骤非常相似的数据时不需要。请确保数据模板选择器是实际需要,而不是一个统一的数据模板应用到集合中的所有项目的每个元素提供有意义的视觉。

数据虚拟化

有时一个应用程序必须使用的数据集是如此之大以致不能或不应存储在内存中。在这些情况下,您必须实现虚拟化的数据的一种方法。这种类型的虚拟化,初始部分的完整的数据集被加载到内存 (从磁盘读取了或从 web 抽取) 和用户界面虚拟化应用到此部分的数据集。增量或从随机点上需求的主数据集,您以后可以下载数据。

增量数据虚拟化按顺序下载数据。例如,ListView 使用增量数据虚拟化并包含 1,000,000 的项目可能只下第 20。然后接下来 20 项下载作为用户锅对列表的末尾。每次下载的更多项目列表的滚动栏变得小一点。对于此类型的数据虚拟化,您必须使用一个实现 ISupportIncrementalLoading 的数据源。

随机存取数据虚拟化允许下载从任意点数据集的数据的控件。例如,使用随机存取数据虚拟化的 ListView 可以下载 100,000 — — 100,020 的项目。如果用户然后跳转到列表的顶部,该控件将下载项目 1 — — 20。整个时间滚动条到 1,000,000 的集合的大小并只移动视图端口中的项都位于该收藏集的数据集与拇指。要启用这种类型的数据虚拟化,您需要使用实现 INotifyCollectionChanged 和 IObservableVector 的数据源。

无论您需要虚拟化的数据取决于许多因素: 大小的数据集、 单个项目的大小、 源的数据集 (本地磁盘或网络位置)、 总体内存消耗的应用程序,等等。如果您确定您需要数据虚拟化您的应用程序中,请确保您的应用程序可以处理数据的缺乏。它是非常容易陷入集合的控件已准备好要呈现的项目,但没有数据是可用的情况。

我们建议您提供占位符元素正在加载的数据。这些占位符元素可以操纵就像是实际的项目,在收集控件内,但他们不显示最终内容。这表明用户 app 是仍然响应,需要更多的时间来下载数据。占位符元素可以逐步替换为实际用户界面,如下载数据。在照片中查看应用程序经常看见这种类型的虚拟化数据的示例。而不是让用户等待下载所有相册中的照片,这款应用程序显示的占位符图像。

为检索每个图像,该图像的占位符元素将替换为实际照片的渲染。即使的所有图像已经不被下载并显示,用户仍可以潘和交互使用的集合。

资源友好型媒体

媒体文件是一些应用程序通常使用的最常见和最昂贵的资源。因为媒体文件资源可以大大增加您的应用程序的内存占用量的大小,你必须记住释放到媒体的句柄,尽快完成应用程序使用它。

例如,如果您的应用程序使用的 RandomAccessStream 或 IInputStream 对象,一定要对对象调用 close 方法,当您的应用程序完成后使用它,以释放的基础对象。

视频

使用全屏视频播放时可能

XAML 框架可以优化的视频内容显示,当它是唯一的东西正在呈现时,造成一种体验,使用较少的电源和收益率较高的帧速率。最有效的媒体回放设置大小的 MediaElement 是宽度和高度的屏幕并不显示其他 XAML 元素。

有正当的理由,覆盖 MediaElement 所占用的完整宽度和高度的屏幕上,例如关闭的字幕或瞬间传输控件上的 XAML 元素。确保要隐藏这些元素 (eg。 设置可见性 ="折叠") 不需要他们的时候会弹出媒体回放回其效率最高的国家。

不要覆盖嵌入的视频

通常应用提供嵌入式的视图视频播放页面内的位置。现在你显然失去的全屏显示优化因为 MediaElement 不是页的大小而有其它绘制的 XAML 对象。当心无意中进入此模式通过绘制 MediaElement 周围的边框。

在嵌入模式下时,不要画画 XAML 元素在视频。如果您这样做,框架被被迫做一些额外的工作,撰写现场。放置传输控件而不是在视频嵌入的媒体元素的下面是优化这种情况的一个好例子。

这里的图片,在红色条指示一组传输控件 (播放、 暂停、 停止、 等等。 … …)。不要将这些控件不是全屏的媒体上。而放置传输控件某处地方媒体正在呈现的区域之外。在接下来的图像中,以下媒体已放到控件。

将源设置为 MediaElement 的延迟

媒体引擎是昂贵的对象和 XAML 框架延迟加载的 dll 和尽可能长时间创建大型对象。MediaElement 被被迫做这项工作,其源设置通过源属性或 SetSource API 之后。设置这些用户真的准备好要播放的媒体时延迟,大部分与尽可能久 MediaElement 相关的成本。

设置 MediaElement.PosterSource

设置 MediaElement.PosterSource 使 XAML 来释放一些 GPU 资源,它们会以其它方式使用。此 API 允许应用程序在使用作为内存尽可能小。

平滑洗涤

洗涤总是媒体平台,使真正回应的艰巨任务。一般人完成此更改滑块的值。下面是关于如何使这尽可能高效地几个提示:

• 可以将滑块的值绑定到 MediaElement.Position 或更新它基于一个计时器。不要做两个。如果您选择后者,请确保为您的计时器使用合理的更新频率。XAML 框架在回放期间仅每 250 毫秒更新 MediaElement.Position。

• 滑块的步频率的大小必须使用的视频长度规模。

• 钩了 PointerPressed,PointerMoved,PointerReleased 事件对滑块来设置 PlaybackRate = 0,获取拖动滑块时。

• 在 PointerReleased 事件中的手动设置媒体位置为滑块位置值,以达到最优拇指同时擦洗对齐。

 

匹配设备分辨率的视频分辨率

解码视频是内存和 GPU 密集所以选择接近它将显示在该决议的视频格式。没有点中使用资源来解码 1080年视频,如果它想要得到缩小到很小的大小。许多应用程序不具有相同的视频编码在不同的决议 ;但如果这是可用的使用编码这就是该决议,它将显示在其中。

推荐的格式

媒体格式选择可以是一个敏感的话题,并经常驱动的业务决策。从 Windows 8 的性能的角度来看,我们建议作为主要的视频格式和 AAC H.264 视频和 MP3 作为首选的音频格式。对于本地文件播放、 MP4 是视频内容的首选的文件容器。正如我们在上一节中提到,H.264 解码是通过最新的图形硬件加速。此外,虽然大致可用,图形硬件市场上一大套的 VC 1 解码硬件加速,加速有限的在很多情况下向部分加速级别 (或 IDCT 级别),而不是全蒸汽级硬件卸载 (即 VLD 模式)。在音频方面,我们预期将在即将到来的 Windows 8 SoC 设备上可用 AAC 和 MP3 硬件卸载解决方案。

如果您有视频内容生成过程的完全控制,你必须想出如何保持压缩效率和共和党结构之间良好的平衡。B 图片相对较小的共和党大小可以提高在寻求或欺骗的模式性能。

当包括短、 低延迟的音频效果,例如在游戏中,使用 WAV 文件未压缩的 PCM 数据来减少处理开销,这是典型的压缩的音频格式。

图像

缩放图像

现在捕获到非常高分辨率的图像。这是伟大捕捉鲜亮的颜色和小细节,但要求应用程序使用更多的 CPU 解码后从磁盘加载的图像数据和更多的内存。没有感觉解码和高分辨率图像保存在内存中,如果它永远不会显示在其本机大小。相反,通过创建的图像的显示大小接近低 res 版本减少 CPU 使用率和内存的占用空间。使用 DecodePixelWidth 和 DecodePixelHeight 产生即将要在应用程序中显示的大小的图像对象。

v<!--Bad: XAML loads a high res image and then scales it to a much

smaller size. -->

<Image Source="ms-appx:///Assets/highresCar.jpg" Width="300" Height="200"/>

<!--Good: XAML decodes a high res image at the size it will be displayed. -->

<Image>

    <Image.Source>

    <BitmapImage UriSource="ms-appx:///Assets/highresCar.jpg" DecodePixelWidth="300" DecodePixelHeight="200"/>

    </Image.Source>

</Image>

缩放图像的更多特定实例创建的缩略图。虽然您可以使用 DecodePixelWidth 和 DecodePixelHeight 提供的图像的小版本,Windows 运行库会提供更加高效的 Api,用于检索缩略图。GetThumbnailAsync 提供缩略图图像,有的已缓存的文件系统。这提供了更好的性能比 XAML Api,因为图像不需要打开或解码。

FileOpenPicker picker = new FileOpenPicker();

picker.FileTypeFilter.Add(".bmp");

picker.FileTypeFilter.Add(".jpg");

picker.FileTypeFilter.Add(".jpeg");

picker.FileTypeFilter.Add(".png");

picker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;

StorageFile file = await picker.PickSingleFileAsync();

StorageItemThumbnail fileThumbnail = await file.GetThumbnailAsync(Windows.Storage.FileProperties.ThumbnailMode.SingleItem, 64);

BitmapImage bmp = new BitmapImage();

bmp.SetSource(fileThumbnail);

 Image img = new Image();

 img.Source = bmp;

一次解码的图像

若要防止图像进行解码不止一次,从 Uri,而不是使用内存流分配的 Image.Source 属性。XAML 框架可以在多个位置相同的 Uri 关联一个解码后的图像,但它不能做相同的多个包含相同的数据的内存流。框架创建一个不同的解码的图像的每个内存流。

DirectX 互操作

从一个 XAML 应用程序访问 DirectX 是本文档的范围之内。这更多的信息,请参阅 DirectX 和 XAML 的互操作性。

创建一个框架,可以轻松地创建性能的应用程序的开发是 XAML 团队的最高优先事项之一。我们希望这篇文章可以帮助您提高性能的关键的最终用户方案。我们将继续扩大我们在 MSDN 上的性能文档,当我们接近 Windows 8 的最终发行。提防更多技巧和工具,帮助查明问题件的代码有关的详细信息。

原文地址:https://www.cnblogs.com/fxiaoquan/p/2578633.html