Fermer

novembre 10, 2022

L’interface utilisateur de Kendo pour jQuery est transformée en modules ECMAScript12 minutes de lecture


Découvrez pourquoi nous avons transformé notre code source d’ADM en ESM et voyez comment vous pouvez bénéficier d’importations de scripts dynamiques avec des navigateurs modernes dans vos applications.

Avec le Sortie de novembre de Kendo UI pour jQuery, notre code source est transformé d’AMD en modules ECMAScript (ESM). Vous pouvez apprendre ici pourquoi nous avons transformé notre propre code source en ESM et voir comment vous pouvez utiliser des importations de scripts dynamiques avec des navigateurs modernes et en tirer d’énormes avantages dans vos applications.

Alors que le billet de blog actuel décrit les modifications apportées à l’interface utilisateur de Kendo, les avantages réels des modules ESM seront également disponibles pour l’interface utilisateur Telerik pour les wrappers de serveur ASP.NET Core et MVC.

Si vous comptez sur les modules AMD, n’ayez pas peur – ils sont toujours là et ils sont expédiés aux mêmes endroits où ils ont toujours été.

Pourquoi sommes-nous passés à l’ESM ?

L’équipe a investi beaucoup de temps et d’efforts lors de la réécriture du code source de l’interface utilisateur de Kendo pour jQuery vers ESM afin d’assurer un achèvement correct et une distribution fluide de notre pipeline. Avec cela, nous avons réussi à trouver une solution pour passer à un nouveau système de modules plus récent sans casser les changements pour quiconque pourrait vouloir utiliser les bons vieux modules AMD/UMD avec les bundles Kendo UI distribués.

Vous pouvez également trouver des informations utiles à ce sujet dans notre documentation : Modules ECMAScript.

En bref, les avantages du passage à l’ESM sont :

  • Utiliser des chargeurs et des bundlers de modules modernes et prendre en charge le concept de regroupement moderne dans l’interface utilisateur de Kendo pour jQuery.
  • Compiler des modules JavaScript afin que vous puissiez laisser le navigateur s’occuper des dépendances de script et les charger dynamiquement (en savoir plus : Les modules Javascript).
  • L’utilisation des bundles Kendo UI distribués et l’utilisation du chargement de script dynamique peuvent améliorer les performances de vos applications (en savoir plus : Comment améliorer les performances).
  • Mise à jour des packages NPM avec différents types de systèmes de modules pour correspondre à ES, CommonJS et AMD/UMD (en savoir plus : Mises à jour dans les packages NPM).
  • Et la meilleure partie est que l’utilisation d’ECMAScript ouvre la porte à d’autres améliorations possibles dans l’interface utilisateur de Kendo pour les produits basés sur jQuery (en savoir plus : L’avenir).

Comment utiliser les nouveaux modules

Les modules Javascript

La Modules Javascript sont des scripts que le navigateur traitera comme des modules ECMAScript et permettront le chargement dynamique. En peu de temps, activez
import et export afin que le navigateur puisse charger lui-même les dépendances de script.

En quoi est-ce si différent des bons vieux fichiers JavaScript ? La différence est énorme lorsque vous utilisez de grandes bibliothèques comme Kendo UI pour jQuery. Si vous voulez tout le code de la bibliothèque, vous devrez charger le kendo.all.js dossier qui, honnêtement, est volumineux. Cela oblige le navigateur à charger un fichier énorme alors que vous n’en avez peut-être besoin que d’une partie pour que votre page fonctionne.

Si vous deviez optimiser le chargement de la page, le kendo.all.js serait une douleur. Et vous devrez entrer et supprimer les dépendances en fonction des composants que vous utilisez et des ensembles de fonctionnalités dont vous avez besoin. Et vous vous référerez à notre documentation (Créer vos propres bundles personnalisés) afin de créer un bundle personnalisé, qui produirait à nouveau un grand bundle. Ou ajoutez uniquement les scripts de pré-groupe spécifiques dont vous auriez besoin, ce qui donnerait une liste de plus de 10 ou 20 fichiers js.

Ce que les modules JavaScript vous permettent, c’est d’avoir un seul fichier comme référence de script (par exemple, <script src="https://www.telerik.com/blogs/./js/index.js" type="module"></script>) et utilise import et export pour charger dynamiquement toutes les autres dépendances.

Prenons l’exemple de la grille de l’interface utilisateur de Kendo. Afin de charger le composant Grid avec toutes les fonctionnalités, vous devez répertorier les fichiers js 70ish (vous pouvez consulter la liste ici : Composants de gestion des données). Avec les modules JavaScript, vous devez ajouter une référence ou importer un seul fichier, le bundle principal : <script src="https://www.telerik.com/blogs/./mjs/kendo.grid.js" type="module"></script>. Et cela permettra au navigateur de charger lui-même toutes les autres dépendances.

Liste des dépendances du module kendo.grid.js

Et, oui, un module n’est chargé qu’une seule fois. Cela signifie que si vous chargez un autre composant qui s’appuie sur une dépendance déjà chargée, il ne sera pas récupéré à nouveau – il est déjà chargé par le navigateur et il sera directement utilisé.

Toutes nos principales distributions (paquets zip, CDN et ainsi de suite) incluent des modules JavaScript compilés.

1. Utilisation des modules JavaScript de CDN

Dans le CDN, les modules JavaScript sont situés dans le /mjs/ dossier.

Vous pouvez les utiliser comme ceci :

<script src="https://kendo.cdn.telerik.com/2022.3.1109/mjs/kendo.grid.js" type="module"></script>
 <script type="module">
    $("#grid").kendoGrid({
        ...
    });
</script>

ou

import 'https://kendo.cdn.telerik.com/2022.3.1109/mjs/kendo.grid.js';
 $("#grid").kendoGrid({
    ...
});

2. Utiliser les modules JavaScript d’une distribution téléchargée

Vous pouvez télécharger les bundles distribués depuis votre compte Telerik dans la section de téléchargement. Dans le mjs dossier, vous trouverez les modules facilement disponibles pour que vous puissiez les copier dans votre application et les utiliser.

<script src="./mjs/kendo.grid.js" type="module"></script>
 <script type="module">
    $("#grid").kendoGrid({
        ...
    });
</script>

ou

import "https://www.telerik.com/blogs/./mjs/kendo.grid.js";
 $("#grid").kendoGrid({
    ...
});

Comment améliorer les performances

Je pense que nous sommes tous sur la même page maintenant – les modules JavaScript sont cool. Mais voyons comment ils peuvent améliorer nos applications et les performances de chargement.

Disons que nous avons une application très simple avec un bouton qui ouvre une boîte de dialogue/fenêtre et charge une grille contenant un tas de données. L’utilisation de l’interface utilisateur de Kendo pour les composants jQuery et les fichiers JS simples ressemblera à ceci :

index.html

<html>
    <head>
        <meta content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport">
    </head>
    <body>
        <button id="openBtn">Open</button>
        
        <div id="gridDialog">
        </div>
        
        <link async href="./styles/kendo/web/kendo.default-ocean-blue.css" rel="stylesheet" media="screen" />
        <script defer src="./js/jquery/jquery.min.js"></script>
        <script defer src="./js/kendo/js/kendo.all.min.js"></script>
        <script defer src="./js/products.js"></script> 
        <script defer src="./js/index.js" type="module"></script>
    </body>
</html>

index.js

$('#openBtn').kendoButton({
    click: openDialog
});

function openDialog() {
    const gridDialog = $("#gridDialog").kendoDialog({
        width: 400,
        content: '<div id="dialogContent"></div>'
    }).data("kendoDialog");
    
    gridDialog.one("show", async () => {
        const gridElm = $('<div id="grid"></div>').appendTo("#dialogContent");
        initGrid(gridElm);
    });
    
    gridDialog.open();
}

function initGrid(gridElm) {
    gridElm.kendoGrid({
        dataSource: {
            data: products,
            schema: {
                model: {
                    fields: {
                        ProductName: { type: "string" },
                        UnitPrice: { type: "number" },
                        UnitsInStock: { type: "number" },
                        Discontinued: { type: "boolean" }
                    }
                }
            },
            pageSize: 20
        },
        height: 550,
        scrollable: true,
        sortable: true,
        filterable: true,
        pageable: {
            input: true,
            numeric: false
        },
        columns: [
            "ProductName",
            { field: "UnitPrice", title: "Unit Price", format: "{0:c}", width: "130px" },
            { field: "UnitsInStock", title: "Units In Stock", width: "130px" },
            { field: "Discontinued", width: "130px" }
        ]
    });
}

Un exemple assez simple qui se charge rapidement et tout fonctionne bien. Vérifions le score de performance en exécutant une vérification avec le Outil phare dans la console de développement de Chrome.

Le contrôle des performances affiche 68 en orange

À ce stade, si les performances de chargement sont importantes pour vous, vous devez essayer d’optimiser l’application. Avec les bundles JS Kendo UI simples, vous pouvez plus ou moins sauver la situation en répertoriant uniquement le script dont vous avez besoin, créer un bundle Kendo UI personnalisé avec uniquement le code dont vous avez besoin et obtenir un score de 85-90. Vous pouvez également appliquer un chargement dynamique en utilisant des méthodes tierces ou une autre magie et éventuellement obtenir un peu plus de 90. Mais tout cela nécessite beaucoup de va-et-vient avec le code. Sans oublier que cela le rend illisible et non maintenable (dans la plupart des cas).

Voyons maintenant comment nous pouvons utiliser le système de modules du navigateur pour améliorer les choses. Tout d’abord, nous devrons prendre du recul et séparer tout le code en modules qui reposent sur des dépendances.

index.html

<html>
    <head>
        <meta content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport">
    </head>
    <body>
        <button id="openBtn">Open</button>
        
        <div id="gridDialog">
        </div>
        
        <link async href="./styles/kendo/web/kendo.default-ocean-blue.css" rel="stylesheet" media="screen" />
        <script async  src="./js/index.js" type="module"></script>
    </body>
</html>

index.js

import './jquery/jquery.min.js';
import './kendo/mjs/kendo.button.js';

$('#openBtn').kendoButton({
    click: async () => {
        const { openDialog } = await import("./dialog.js");

        openDialog();
    }
});

dialogue.js

import './kendo/mjs/kendo.dialog.js';

export function openDialog() {
    const gridDialog = $("#gridDialog").kendoDialog({
        width: 400,
        content: '<div id="dialogContent"></div>'
    }).data("kendoDialog");

    gridDialog.one("show", async () => {
        const { initGrid } = await import("./grid.js");
        const gridElm = $('<div id="grid"></div>').appendTo("#dialogContent");

        initGrid(gridElm);
    });

    gridDialog.open();
}

grille.js

import './kendo/mjs/kendo.grid.js';

export async function initGrid(gridElm) {
    const { products } = await import("./products.js");

    gridElm.kendoGrid({
        dataSource: {
            data: products,
            schema: {
                model: {
                    fields: {
                        ProductName: { type: "string" },
                        UnitPrice: { type: "number" },
                        UnitsInStock: { type: "number" },
                        Discontinued: { type: "boolean" }
                    }
                }
            },
            pageSize: 20
        },
        height: 550,
        scrollable: true,
        sortable: true,
        filterable: true,
        pageable: {
            input: true,
            numeric: false
        },
        columns: [
            "ProductName",
            { field: "UnitPrice", title: "Unit Price", format: "{0:c}", width: "130px" },
            { field: "UnitsInStock", title: "Units In Stock", width: "130px" },
            { field: "Discontinued", width: "130px" }
        ]
    });
}

produits.js

exporter constante des produits = [{
    ProductID : 1,
    ProductName : "Chai",
    SupplierID : 1,
    CategoryID : 1,
    QuantityPerUnit : "10 boxes x 20 bags",
    UnitPrice : 18.0000,
    UnitsInStock : 39,
    UnitsOnOrder : 0,
    ReorderLevel : 10,
    Discontinued : false,
    Category : {
        CategoryID : 1,
        CategoryName : "Beverages",
        Description : "Soft drinks, coffees, teas, beers, and ales"
    }
},
    ....

Now let’s run a performance check once more.

Performance check shows 97 in green

This score is more satisfactory. And now we have more readable code with good separation, which makes it better than before. Plus, we can take advantage and reuse parts of the code we write in our applications.

A bit more drilling down will explain more why using dynamic loading and modules save the day. In the example above, we see that none of the huge scripts (kendo.dialog.js and kendo.grid.js) are loaded until the button is clicked.
Therefore, scripts are loaded only when the end user requires a specific functionality in your application. In short, with initial load, only the CSS and the scripts for the Button are loaded. The rest is handled by the browser.

Using JavaScript Modules in Telerik UI for ASP.NET MVC and Core

The new modules are available in the Telerik UI for ASP.NET MVC and Core bundles as well. You can find them in the mjs folder. Using them requires deferred initialization.

This is an example how to use a Telerik UI for ASP.NET Core Grid component with the module system:

(Html.Kendo().Grid<My_App.Models.ProductViewModel>()
    .Name("Grid")
    .Columns(columns =>
    {
        columns.Bound("productName");
        columns.Bound("unitPrice");
    })
    .DataSource(dataSource => dataSource
        .Custom()
        .Transport(tr => tr.Read("Products_Read", "Grid"))
        .Schema(sc => sc.Data("data"))
    )
    .Deferred()
)

@section Scripts { 
<script type="module">
    import '@Url.Content("/js/mjs/kendo.grid.js")';
    import '@Url.Content("/js/mjs/kendo.aspnetmvc.js")';

    @Html.Kendo().DeferredScripts(false)
</script>
}

Updates in the NPM Packages

The NPM packages (@progress/kendo-ui and kendo-ui-core) are extended with module and browser fields so that you can include scripts according to the module system of your project.

That means that now you can instruct the module loader/bundler (according to its specific configuration) to get the specific module system from the NPM package so that you do not need to alter the preferred compiler/transpiler.

Note that WebPack uses the browser field with priority. You can check that from here as well: WebPack docs.

For example, using WebPack with ECMAScript-based application, you can set up the mainFields option to get the module field:

...
  resolve: {
    mainFields: [ 'module', 'browser', 'main' ]
  },
...

ou créer un alias :

  resolve: {
    alias: {
      '@progress/kendo-ui': path.resolve(__dirname, 'node_modules/@progress/kendo-ui/esm/kendo.all.js') 
    },
  },

Ou vous pouvez le configurer pour utiliser les modules CommonJS :

...
  resolve: {
    mainFields: [ 'main', 'browser', 'module' ]
  },
...

ou créer un alias :

  resolve: {
    alias: {
      '@progress/kendo-ui': path.resolve(__dirname, 'node_modules/@progress/kendo-ui/js/kendo.all.js') 
    },
  },

Chaque chargeur de module est différent et vous devriez consulter la documentation pour voir comment vous pouvez le configurer en fonction de vos besoins.

L’avenir

Avec cet effort, nous recherchons de nouvelles façons d’améliorer l’interface utilisateur de Kendo pour jQuery et Telerik UI pour les produits ASP.NET MVC et Core. Et cette étape ouvre de nouvelles façons d’aborder les fonctionnalités, les fonctionnalités et de fournir un meilleur support.

Par exemple, une petite divulgation sur ce sur quoi nous travaillons après la publication du système de modules concerne un meilleur support CSP et un mécanisme de modèle alternatif.

Comme toujours, nous sommes ouverts aux commentaires. Donc, si vous avez une suggestion ou une idée qui améliorerait votre vie avec nos produits, n’hésitez pas à nous contacter via notre canaux de soutien,
Portail de commentaires, forums ou des commentaires.




Source link