다음을 통해 공유


성능 최적화: 텍스트

업데이트: 2007년 11월

WPF에서는 풍부한 기능이 포함된 UI(사용자 인터페이스) 컨트롤을 사용하여 텍스트 콘텐츠를 표시할 수 있습니다. 텍스트 렌더링은 일반적으로 다음과 같은 세 계층으로 구분할 수 있습니다.

  1. GlyphsGlyphRun 개체 직접 사용

  2. FormattedText 개체 사용

  3. TextBlockFlowDocument 개체와 같은 고급 컨트롤 사용

이 항목에서는 텍스트 렌더링과 관련된 성능 권장 사항을 제공합니다.

이 항목에는 다음 단원이 포함되어 있습니다.

  • 문자 모양 수준에서 텍스트 렌더링
  • FormattedText 개체
  • FlowDocument, TextBlock 및 Label 컨트롤
  • Hyperlink
  • 텍스트 서식 지정 기능
  • 관련 항목

문자 모양 수준에서 텍스트 렌더링

WPF(Windows Presentation Foundation)은 텍스트를 가로채 서식 지정 후에도 텍스트를 유지하려는 고객을 위해 Glyphs에 직접 액세스하는 문자 모양 수준의 태그와 같은 고급 텍스트 지원을 제공합니다. 이러한 기능은 다음과 같은 각 시나리오에서 발생하는 다양한 텍스트 렌더링 요구 사항을 만족시키는 데 큰 도움을 줍니다.

  • 고정 형식 문서의 화면 표시

  • 인쇄 시나리오

    • 장치 프린터 언어로서의 XAML(Extensible Application Markup Language)

    • Microsoft XPS 문서 작성기

    • 이전 프린터 드라이버, Win32 응용 프로그램으로부터 고정 형식으로의 출력

    • 인쇄 스풀 형식

  • 이전 버전의 Windows 및 기타 컴퓨팅 장치에 대한 클라이언트를 포함하는 고정 형식 문서 표현

참고

GlyphsGlyphRun은 고정 형식 문서 표현과 인쇄 시나리오를 위해 디자인되었습니다. WPF(Windows Presentation Foundation)은 LabelTextBlock과 같은 일반적인 레이아웃 및 UI(사용자 인터페이스) 시나리오를 위한 여러 가지 요소를 제공합니다. 레이아웃 및 UI 시나리오에 대한 자세한 내용은 Windows Presentation Foundation의 입력 체계를 참조하십시오.

다음 예제에서는 XAML(Extensible Application Markup Language)에서 Glyphs 개체의 속성을 정의하는 방법을 보여 줍니다. Glyphs 개체는 XAML에서 GlyphRun의 출력을 나타냅니다. 이 예제에서는 로컬 컴퓨터의 C:\WINDOWS\Fonts 폴더에 Arial, Courier New 및 Times New Roman 글꼴이 설치되어 있다고 가정합니다.

<!-- The example shows how to use a Glyphs object. -->
<Page
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
  >

   <StackPanel Background="PowderBlue">

      <Glyphs
         FontUri             = "C:\WINDOWS\Fonts\TIMES.TTF"
         FontRenderingEmSize = "100"
         StyleSimulations    = "BoldSimulation"
         UnicodeString       = "Hello World!"
         Fill                = "Black"
         OriginX             = "100"
         OriginY             = "200"
      />

   </StackPanel>
</Page>

DrawGlyphRun 사용

사용자 지정 컨트롤이 있는 상태에서 문자 모양을 렌더링하려면 DrawGlyphRun 메서드를 사용합니다.

WPF는 FormattedText 개체를 사용하여 사용자 지정 텍스트 서식 지정을 위한 하위 수준의 서비스도 제공합니다. WPF(Windows Presentation Foundation)에서 텍스트를 렌더링하는 가장 효율적인 방법은 GlyphsGlyphRun을 사용하여 문자 모양 수준에서 텍스트 콘텐츠를 생성하는 것입니다. 그러나 이렇게 하면 효율성이 높아지는 대신 TextBlockFlowDocument와 같은 WPF(Windows Presentation Foundation) 컨트롤의 기본 제공 기능인 사용하기 쉬운 서식 있는 텍스트 기능이 손실됩니다.

FormattedText 개체

FormattedText 개체를 사용하면 여러 줄 텍스트를 그릴 수 있으며 각 텍스트 문자의 서식을 개별적으로 지정할 수 있습니다. 자세한 내용은 서식 있는 텍스트 그리기를 참조하십시오.

서식 있는 텍스트를 만들려면 FormattedText 생성자를 호출하여 FormattedText 개체를 만듭니다. 초기 서식 있는 텍스트 문자열을 만든 다음에는 다양한 서식 스타일을 적용할 수 있습니다. 응용 프로그램에서 자체 레이아웃을 구현하려면 컨트롤을 사용하는 것보다 TextBlock과 같은 FormattedText 개체를 사용하는 것이 더 좋습니다. FormattedText 개체에 대한 자세한 내용은 서식 있는 텍스트 그리기를 참조하십시오.

FormattedText 개체는 하위 수준의 텍스트 서식 지정 기능을 제공합니다. 하나 이상의 문자에 여러 서식 스타일을 적용할 수 있습니다. 예를 들어 SetFontSizeSetForegroundBrush 메서드를 모두 호출하여 텍스트에 있는 처음 5개 문자의 서식을 변경할 수 있습니다.

다음 코드 예제에서는 FormattedText 개체를 만들고 이를 렌더링합니다.

protected override void OnRender(DrawingContext drawingContext)
{
    string testString = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor";

    // Create the initial formatted text string.
    FormattedText formattedText = new FormattedText(
        testString,
        CultureInfo.GetCultureInfo("en-us"),
        FlowDirection.LeftToRight,
        new Typeface("Verdana"),
        32,
        Brushes.Black);

    // Set a maximum width and height. If the text overflows these values, an ellipsis "..." appears.
    formattedText.MaxTextWidth = 300;
    formattedText.MaxTextHeight = 240;

    // Use a larger font size beginning at the first (zero-based) character and continuing for 5 characters.
    // The font size is calculated in terms of points -- not as device-independent pixels.
    formattedText.SetFontSize(36 * (96.0 / 72.0), 0, 5);

    // Use a Bold font weight beginning at the 6th character and continuing for 11 characters.
    formattedText.SetFontWeight(FontWeights.Bold, 6, 11);

    // Use a linear gradient brush beginning at the 6th character and continuing for 11 characters.
    formattedText.SetForegroundBrush(
                            new LinearGradientBrush(
                            Colors.Orange,
                            Colors.Teal,
                            90.0),
                            6, 11);

    // Use an Italic font style beginning at the 28th character and continuing for 28 characters.
    formattedText.SetFontStyle(FontStyles.Italic, 28, 28);

    // Draw the formatted text string to the DrawingContext of the control.
    drawingContext.DrawText(formattedText, new Point(10, 0));
}

FlowDocument, TextBlock 및 Label 컨트롤

WPF에는 화면에 텍스트를 그리기 위한 다양한 컨트롤이 포함되어 있습니다. 각 컨트롤은 서로 다른 시나리오에 사용되며 컨트롤마다 고유한 기능 및 제한 사항이 있습니다.

TextBlock 또는 Label보다 성능에 더 큰 영향을 주는 FlowDocument

UI(사용자 인터페이스)의 간단한 문장과 같이 제한된 텍스트 지원이 필요할 경우 일반적으로 TextBlock 요소를 사용해야 합니다. Label은 최소한의 텍스트 지원만 필요할 경우 사용할 수 있습니다. FlowDocument 요소는 풍부한 콘텐츠 표시를 지원하며 흐름을 바꿀 수 있는 문서를 위한 컨테이너이므로 TextBlock 또는 Label 컨트롤을 사용할 때보다 성능에 더 큰 영향을 줍니다.

FlowDocument에 대한 자세한 내용은 유동 문서 개요를 참조하십시오.

FlowDocument에서 TextBlock 사용 지양

TextBlock 요소는 UIElement에서 파생됩니다. Run 요소는 TextElement에서 파생되며 UIElement에서 파생된 개체를 사용하는 것보다 비용이 적게 소요됩니다. 가능하면 FlowDocument에서 텍스트 콘텐츠를 표시할 때 TextBlock 대신 Run을 사용하십시오.

다음 태그 샘플에서는 FlowDocument에서 텍스트 콘텐츠를 설정하는 두 가지 방법을 보여 줍니다.

<FlowDocument>

  <!-- Text content within a Run (more efficient). -->
  <Paragraph>
    <Run>Line one</Run>
  </Paragraph>

  <!-- Text content within a TextBlock (less efficient). -->
  <Paragraph>
    <TextBlock>Line two</TextBlock>
  </Paragraph>

</FlowDocument>

텍스트 속성 설정에 Run 사용 지양

일반적으로 TextBlock에서 Run을 사용하면 명시적인 Run 개체를 전혀 사용하지 않는 경우보다 성능에 더 큰 영향을 줍니다. 텍스트 속성을 설정하기 위해 Run을 사용하는 경우 대신 TextBlock에 직접 해당 속성을 설정해 보십시오.

다음 태그 샘플에서는 텍스트 속성(여기서는 FontWeight 속성)을 설정하는 이러한 두 가지 방법을 보여 줍니다.

<!-- Run is used to set text properties. -->
<TextBlock>
  <Run FontWeight="Bold">Hello, world</Run>
</TextBlock>

<!-- TextBlock is used to set text properties, which is more efficient. -->
<TextBlock FontWeight="Bold">
  Hello, world
</TextBlock>

다음 표에서는 1000개의 TextBlock 개체를 표시할 때 명시적인 Run을 사용할 경우와 사용하지 않을 경우를 비교하여 소요되는 비용을 보여 줍니다.

TextBlock 형식

만든 시간(ms)

렌더링 시간(ms)

Run으로 설정하는 텍스트 속성

146

540

TextBlock으로 설정하는 텍스트 속성

43

453

Label.Content 속성에 대한 데이터 바인딩 지양

String 소스로부터 자주 업데이트되는 Label 개체가 사용되는 시나리오를 가정할 때 Label 요소의 Content 속성을 String 소스 개체에 데이터 바인딩하면 성능이 저하될 수 있습니다. String 개체는 변경 및 수정이 불가능하기 때문에 소스 String이 업데이트될 때마다 이전 String 개체는 삭제되고 새 String이 다시 만들어집니다. 이를 통해 Label 개체의 ContentPresenter가 해당 이전 콘텐츠를 삭제하고 새 콘텐츠를 다시 생성하여 새 String을 표시하게 됩니다.

이 문제는 간단하게 해결할 수 있습니다. Label이 사용자 지정 ContentTemplate 값으로 설정되어 있지 않은 경우 LabelTextBlock으로 바꾸고 해당 Text 속성을 소스 문자열에 데이터 바인딩합니다.

데이터 바인딩된 속성

업데이트 시간(ms)

Label.Content

835

TextBlock.Text

242

Hyperlink 개체는 유동 콘텐츠 내에 하이퍼링크를 호스팅할 수 있도록 하는 인라인 수준의 유동 콘텐츠 요소입니다.

단일 TextBlock 개체에서 하이퍼링크 결합

여러 개의 Hyperlink 요소를 동일한 TextBlock에서 그룹화하여 해당 요소를 최적으로 사용할 수 있습니다. 이렇게 하면 응용 프로그램에서 만드는 개체 수를 최소화하는 데 도움이 됩니다. 예를 들어 다음과 같이 여러 개의 하이퍼링크를 표시하려는 경우가 있습니다.

MSN Home | My MSN

다음 태그 예제에서는 하이퍼링크를 표시하는 데 사용되는 여러 개의 TextBlock 요소를 보여 줍니다.

<!-- Hyperlinks in separate TextBlocks. -->
<TextBlock>
  <Hyperlink TextDecorations="None" NavigateUri="https://www.msn.com">MSN Home</Hyperlink>
</TextBlock>

<TextBlock Text=" | "/>

<TextBlock>
  <Hyperlink TextDecorations="None" NavigateUri="http://my.msn.com">My MSN</Hyperlink>
</TextBlock>

다음 태그 예제에서는 보다 효율적인 하이퍼링크 표시 방법을 보여 줍니다. 이번에는 단일 TextBlock을 사용합니다.

<!-- Hyperlinks combined in the same TextBlock. -->
<TextBlock>
  <Hyperlink TextDecorations="None" NavigateUri="https://www.msn.com">MSN Home</Hyperlink>

  <Run Text=" | " />

  <Hyperlink TextDecorations="None" NavigateUri="http://my.msn.com">My MSN</Hyperlink>
</TextBlock>

MouseEnter 이벤트에서만 하이퍼링크에 밑줄 표시

TextDecoration 개체는 텍스트에 추가할 수 있는 시각적 장식 효과이지만 이를 인스턴스화하는 경우 성능에 영향이 있을 수 있습니다. Hyperlink 요소를 광범위하게 사용하는 경우 MouseEnter 이벤트와 같은 이벤트가 트리거될 때만 밑줄이 표시되도록 할 수 있습니다. 자세한 내용은 방법: Hyperlink가 있는 텍스트 장식 사용을 참조하십시오.

MouseEnter 발생 시 나타나는 하이퍼링크

TextDecoration을 표시하는 하이퍼링크

다음 태그 샘플에서는 밑줄을 사용하거나 사용하지 않고 정의된 Hyperlink를 보여 줍니다.

<!-- Hyperlink with default underline. -->
<Hyperlink NavigateUri="https://www.msn.com">
  MSN Home
</Hyperlink>

<Run Text=" | " />

<!-- Hyperlink with no underline. -->
<Hyperlink Name="myHyperlink" TextDecorations="None"
           MouseEnter="OnMouseEnter"
           MouseLeave="OnMouseLeave"
           NavigateUri="https://www.msn.com">
  My MSN
</Hyperlink>

다음 표에서는 1000개의 Hyperlink 요소를 표시할 때 밑줄을 표시할 경우와 표시하지 않을 경우의 성능 비용을 보여 줍니다.

Hyperlink

만든 시간(ms)

렌더링 시간(ms)

밑줄 있음

289

1130

밑줄 없음

299

776

텍스트 서식 지정 기능

WPF는 자동 하이픈 넣기와 같은 풍부한 텍스트 서식 지정 서비스를 제공합니다. 이러한 서비스는 응용 프로그램 성능에 영향을 줄 수 있으므로 필요한 경우에만 사용해야 합니다.

불필요한 하이픈 넣기 사용 지양

자동 하이픈 넣기 기능은 텍스트 줄의 하이픈 중단점을 찾고 TextBlockFlowDocument 개체에 있는 줄에서 추가 중단 위치를 허용합니다. 기본적으로 자동 하이픈 넣기 기능은 이러한 개체에서 사용되지 않습니다. 이 기능은 개체의 IsHyphenationEnabled 속성을 true로 설정하여 사용할 수 있습니다. 그러나 이 기능을 사용하면 WPF가 COM(구성 요소 개체 모델) 상호 운용성을 시작하고 이에 따라 응용 프로그램 성능이 영향을 받을 수 있습니다. 필요하지 않은 한 자동 하이픈 넣기 기능은 사용하지 않는 것이 좋습니다.

신중하게 Figure 사용

Figure 요소는 콘텐츠 페이지에서 절대 위치에 배치될 수 있는 유동 콘텐츠 부분을 나타냅니다. 해당 위치가 이미 레이아웃이 지정된 콘텐츠와 충돌하는 경우 Figure로 인해 페이지 전체의 서식이 자동으로 다시 적용되는 경우도 있습니다. 고정 페이지 크기 시나리오에서 Figure 요소를 서로 가깝게 그룹화하거나 콘텐츠 위쪽에 선언하여 불필요하게 서식이 다시 적용될 가능성을 최소화할 수 있습니다.

최적의 단락

FlowDocument 개체가 제공하는 최적의 단락 기능은 공간이 최대한 일정하게 분배되도록 단락의 레이아웃을 지정합니다. 기본적으로 최적의 단락 기능은 사용되지 않습니다. 이 기능은 개체의 IsOptimalParagraphEnabled 속성을 true로 설정하여 사용할 수 있습니다. 그러나 이 기능을 사용하면 응용 프로그램 성능이 영향을 받을 수 있습니다. 필요하지 않은 한 최적의 단락 기능은 사용하지 않는 것이 좋습니다.

참고 항목

개념

WPF 응용 프로그램 성능 최적화

응용 프로그램 성능 계획

성능 최적화: 하드웨어 이용

성능 최적화: 레이아웃 및 디자인

성능 최적화: 2차원 그래픽 및 이미징

성능 최적화: 개체 동작

성능 최적화: 응용 프로그램 리소스

성능 최적화: 데이터 바인딩

성능 최적화: 기타 권장 사항

WPF 성능 도구 및 리소스