Skip to content

Performance#

Key Points#

KPIs & Standards#

Name Code Definition Good Average Poor
Time to First Byte TTFB Measures the duration from the user or client making an HTTP request to the first byte of the page being received by the client’s browser. It is a measurement used as an indication of the responsiveness of a webserver or other network resources. < 800 ms. 800 ms. to 1800 ms. >= 1800 ms.
First Contentful Paint FCP The time when the browser first rendered any text, image (including background images){target=_blank}, non-white canvas or SVG. This includes text with pending webfonts. This is the first time users could start consuming page content < 1800 ms. 1800 ms. to 3000 ms. >= 3000 ms.
Largest Contentful Paint LCP A user-centric metric for measuring perceived load speed because it marks the point in the page load timeline when the page’s main content has likely loaded—a fast LCP helps reassure the user that the page is useful. < 2500 ms. 2500 ms. to 4000 ms. >= 4000 ms.
First Input Delay FID A user-centric metric for measuring load responsiveness because it quantifies the experience users feel when trying to interact with unresponsive pages—a low FID helps ensure that the page is usable. < 100 ms. 100 ms. to 300 ms. >= 300 ms.
Cumulative Layout Shift CLS A user-centric metric for measuring visual stability because it helps quantify how often users experience unexpected layout shifts—a low CLS helps ensure that the page is delightful. < 0.1 0.1 to 0.25 >= 0.25

Best Practices#

Use Efficient Processes#

The code should be efficient, and should not affect TTFB in a way where the site would go down.

Incorrect

<mvt:assign name="l.settings:has_forbidden_items" value="0" />

<mvt:foreach iterator="group" array="basket:groups">
    <mvt:item name="customfields" param="Read_Product_ID( l.settings:group:product_id, 'forbidden', l.settings:group:customfield_values:customfields:forbidden )" />
    <mvt:if expr="l.settings:group:customfield_values:customfields:forbidden">
        <mvt:assign name="l.settings:has_forbidden_items" value="1" />
    </mvt:if>
</mvt:foreach>

Reasoning: Continues to loop when it’s not necessary.

Correct

<mvt:assign name="l.settings:has_forbidden_items" value="0" />

<mvt:foreach iterator="group" array="basket:groups">
    <mvt:item name="customfields" param="Read_Product_ID( l.settings:group:product_id, 'forbidden', l.settings:group:customfield_values:customfields:forbidden )" />
    <mvt:if expr="l.settings:group:customfield_values:customfields:forbidden">
        <mvt:assign name="l.settings:has_forbidden_items" value="1" />
        <mvt:foreachstop />
    </mvt:if>
</mvt:foreach>

Reasoning: Once the field has been found, it stops looping.

Use Efficient Functions#

Incorrect

<mvt:do file="g.Module_Library_DB" name="l.product_loaded" value="Product_Load_Code( l.product_code, l.product )" />

Reasoning: Not utilizing the “Cached” function when applicable, to possibly reduce a DB lookup.

Correct

<mvt:do file="g.Module_Library_DB" name="l.product_loaded" value="Product_Load_Code_Cached( l.product_code, l.product )" />

Reasoning: Utilizes the “Cached” function when applicable, to possibly reduce a DB lookup.

Avoid Infinite Loops#

There should not be a way to create an infinite loop.

Incorrect

<mvt:if expr="g.Empty_Cart">
    <mvt:do file="g.Module_Library_DB" name="l.success" value="Runtime_Basket_Empty( g.Basket:basket_id )" />
    <mvt:do file="g.Module_Feature_PGR_DB" name="l.success" value="BasketDiscountTotal_Delete_All_Basket( g.Basket:basket_id )" />

    <mvt:assign name="l.result" value="miva_output_header( 'Status', '302 Moved Temporarily' )" />
    <mvt:eval expr="miva_output_header( 'Location', 'https://' $ encodeentities(g.domain:name) $ s.request_uri )" />
    <mvt:exit />
</mvt:if>
<a href="&mvte:urls:BASK:auto_sep;Empty_Cart=1">Empty Cart</a>

Reasoning: The code will infinitely loop because the query-string ?Empty_Cart=1 will continue to get passed in the s.request_uri of the following Location headers.

Correct

<mvt:if expr="g.Empty_Cart">
    <mvt:do file="g.Module_Library_DB" name="l.success" value="Runtime_Basket_Empty( g.Basket:basket_id )" />
    <mvt:do file="g.Module_Feature_PGR_DB" name="l.success" value="BasketDiscountTotal_Delete_All_Basket( g.Basket:basket_id )" />

    <mvt:assign name="l.result" value="miva_output_header( 'Status', '302 Moved Temporarily' )" />
    <mvt:assign name="l.result" value="miva_output_header( 'Location', encodeentities( l.settings:urls:BASK:auto ) )" />
    <mvt:exit />
</mvt:if>
<a href="&mvte:urls:BASK:auto_sep;Empty_Cart=1">Empty Cart</a>

Reasoning: The redirect to the new location is a fix value that cannot create an infinite loop.