What's more efficient to hide content - css or if/else

Viewed 67

What's more efficient in Blazor hiding content by changing css or by actually changing the content.

CSS:

<div class="@ProfileCssClass">Some content</div>

C# IF:

@if (IsProfileVisible)
{
    <div>Some content</div>
}

Assume that ProfileCssClass is a class that shows/hides using display:none and that is IsProfileVisible is a bool. Both are updated via an @onclick.

Let's assume that in this example, the div being displayed is not trivial (bigger web socket payload?) and that the content is pre-generated and already on the page (vs. going and getting the data when it's needed).

What's more efficient, just hiding and showing by changing a single class or reloading the contents of the div. I guess what I am not clear on is what changing the class on a div actually changes in Blazor world - a small 16 character diff or something else.

2 Answers

I think this depends on many things. But a really good way to be performant is to do a combination of both.

If there is a chance the element will be displayed, use the If statement. If the element will definitely be displayed, use CSS.

If the render is expensive but occasional, do a double whammy.

Here is a crude code example:

<div class="Parent" @onmouseover="@(() => _showElement = true)">
    <span>Render me baby, I'm expensive</span>
    @if (_showElement)
    {
        <div class="Child">Hoooray!</div>
    }
</div>

@code {
    bool _showElement = false;
}

<style>
    .Child {
        display: none;
    }

    .Parent:hover .Child {
        display: block;
    }
</style>

This will only render the object once, but will avoid rendering it if it's not hovered.

There is no simple answer to this question, because it depends on what and why you want to hide/show a fragment of code.

First a simple component I'll use in the example code below.

@if(!this.Hidden)
{
    <h3>My Component</h3>
    @Uid
}
@code {
    private Guid Uid = Guid.NewGuid();
    [Parameter] public bool Hidden { get; set; }
}

Consider these three options which all hide/show code blocks.

@page "/"

<PageTitle>Index</PageTitle>

 <div class="p-2">
     <button class="btn btn-primary" @onclick=this.Toggle>Switch</buttqn>
</div>

<h1 class="@this.cssClass">Hello, world!</h1>

@if(!this.Hidden)
{
    <MyComponent />
}

<MyComponent Hidden=this.Hide />

<style>
    .blazr-show { display:block; }
    .blazr-hide { display: none; }
</style>
@code{
    private bool Hidden = false;

    private string cssClass => this.Hide
        ? "blazr-hide"
        : "blazr-show";

    private void Toggle()
    {
        Hidden = !Hidden;
    }
}

Using Css:

  1. works Ok for turning on and off blocks of html markup.
  2. Fails if you are hiding because the block is invalid (such as iterating a null IEnumerable).

Using an @if block:

  1. works for simple html blocks
  2. works if you are hiding because the block is invalid (such as iterating a null IEnumerable).
  3. is expensive or may fail if the block contains one or more components because the Renderer will destroy and then initialize the enclosed components on every toggle (check the component Id).

Using an @if block within a component:

  1. works because you are now using the same component, just hiding or showing it's content.

I personally don't normally use the css option because it hide's the intent of the code. Another programmer looking at your code will probably need to go and find an entry in a Css file to figure out what's going on.

Here's an edit form example from some production code where the intent is clear.

 <UIButton ButtonType=UIButtonType.Exit Hidden=this.IsDirty ClickEvent=this.Exit">Exit</UIButton>

However, if it's a big block of simple markup that doesn't change, then I'd probably test and if it's faster (which I suspect) use the Css method with the Css in a component Css file.

Related