Fonctionnement de Wails
Comprendre l’architecture de Wails et la manière dont elle offre des performances natives
Wails est un framework permettant de créer des applications de bureau avec Go pour le backend et des technologies web pour le frontend. Mais contrairement à Electron, Wails n’intègre pas de navigateur : il utilise la WebView native du système d’exploitation.
Principales différences par rapport à Electron :
| Aspect | Wails | Electron |
|---|---|---|
| Navigateur | WebView fournie par le système d’exploitation | Chromium intégré (~100 Mo) |
| Backend | Go (compilé) | Node.js (interprété) |
| Communication | Pont en mémoire | IPC (interprocessus) |
| Taille du paquet | ~15 Mo | ~150 Mo |
| Mémoire | ~10 Mo | ~100 Mo+ |
| Démarrage | <0.5s | 2-3s |
Composants principaux
1. WebView native
Wails utilise le moteur de rendu web intégré au système d’exploitation :
WebView2 (Microsoft Edge WebView2)
- Basé sur Chromium (comme le navigateur Edge)
- Préinstallé sur Windows 10/11
- Mises à jour automatiques via Windows Update
- Prise en charge complète des standards web modernes
WebKit (moteur de rendu de Safari)
- Intégré à macOS
- Même moteur que le navigateur Safari
- Excellentes performances et autonomie
- Prise en charge complète des standards web modernes
WebKitGTK (portage GTK de WebKit)
- Installé via le gestionnaire de paquets
- Même moteur que GNOME Web (Epiphany)
- Bonne prise en charge des standards
- Léger et performant
Pourquoi est-ce important ?
- Aucun navigateur intégré → Application moins volumineuse
- Natif au système d’exploitation → Meilleures intégration et performances
- Mises à jour automatiques → Correctifs de sécurité fournis par les mises à jour du système d’exploitation
- Rendu familier → Identique à celui du navigateur système
2. Le pont Wails
Le pont est au cœur de Wails : il permet une communication directe entre Go et JavaScript.
Fonctionnement :
- Le frontend appelle une méthode Go (via une liaison générée automatiquement)
- Le pont encode l’appel au format JSON (nom de la méthode + arguments)
- Le routeur trouve la méthode Go dans les services enregistrés
- La méthode Go s’exécute et renvoie une valeur
- Le pont décode le résultat et le renvoie au frontend
- La promesse est résolue dans JavaScript avec le résultat
Caractéristiques de performance :
- En mémoire : aucune surcharge réseau, aucun HTTP
- Sans copie lorsque cela est possible (pour les données volumineuses)
- Asynchrone par défaut : non bloquant des deux côtés
- À typage sûr : définitions TypeScript générées automatiquement
3. Système de services
Les services constituent la méthode recommandée pour exposer les fonctionnalités Go au frontend.
// Define a service (just a regular Go struct)
type GreetService struct {
prefix string
}
// Methods with exported names are automatically available
func (g *GreetService) Greet(name string) string {
return g.prefix + name + "!"
}
func (g *GreetService) GetTime() time.Time {
return time.Now()
}
// Register the service
app := application.New(application.Options{
Services: []application.Service{
application.NewService(&GreetService{prefix: "Hello, "}),
},
})Découverte des services :
- Au démarrage, Wails analyse votre structure
- Les méthodes exportées peuvent être appelées depuis le frontend
- Les informations de type sont extraites pour les liaisons TypeScript
- La gestion des erreurs est automatique (erreurs Go → exceptions JS)
Liaison TypeScript générée :
// Auto-generated in frontend/bindings/GreetService.ts
export function Greet(name: string): Promise<string>
export function GetTime(): Promise<Date>Pourquoi utiliser des services ?
- Typage sûr : prise en charge complète de TypeScript
- Découverte automatique : aucun enregistrement manuel des méthodes
- Organisation : regroupez les fonctionnalités associées
- Testabilité : les services sont de simples structures Go
En savoir plus sur les services →
4. Système d’événements
Les événements permettent une communication par publication-abonnement entre les composants.
Cas d’utilisation :
- Communication entre fenêtres : une fenêtre en informe d’autres
- Tâches en arrière-plan : le service Go informe l’interface utilisateur de leur progression
- Synchronisation de l’état : maintenez plusieurs fenêtres synchronisées
- Couplage faible : les composants n’ont pas besoin de références directes
Exemple :
// Go: Emit an event
app.Event.Emit("user-logged-in", user)// JavaScript: Listen for event
import { Events } from '@wailsio/runtime'
Events.On('user-logged-in', (user) => {
console.log('User logged in:', user)
})En savoir plus sur les événements →
Cycle de vie de l’application
Comprendre le cycle de vie vous aide à déterminer quand initialiser les ressources et quand les libérer.
Points d’accroche du cycle de vie :
app := application.New(application.Options{
Name: "My App",
// Cleanly intercept quit requests (e.g. unsaved changes).
ShouldQuit: func() bool { return true },
// Called when the app is confirmed to be quitting — save state, close connections, etc.
OnShutdown: func() {},
})application.Options ne comporte aucun champ OnStartup. Les opérations de démarrage doivent être placées dans la méthode ServiceStartup(ctx, options) d’un service, dans une fonction de rappel enregistrée via app.Event.OnApplicationEvent(events.Common.ApplicationStarted, ...), ou simplement avant app.Run().
En savoir plus sur le cycle de vie →
Processus de compilation
Voici comment Wails compile votre application :
Étapes de compilation :
- Analyser le code Go
- Rechercher les méthodes exportées dans les services
- Extraire les types des paramètres et des valeurs de retour
- Générer les signatures des méthodes
- Générer les liaisons TypeScript
- Créer des fichiers
.tspour chaque service - Inclure les définitions de types complètes
- Ajouter des commentaires JSDoc
- Compiler le frontend
- Exécuter votre outil de regroupement (Vite, webpack, etc.)
- Minifier et optimiser
- Écrire la sortie dans
frontend/dist/
- Compiler le code Go
- Compiler avec les optimisations (
-ldflags="-s -w") - Inclure les métadonnées de compilation
- Effectuer la compilation propre à la plateforme
- Intégrer les ressources
- Intégrer les fichiers du frontend au binaire Go
- Compresser les ressources
- Créer un exécutable unique
Résultat : un exécutable natif unique qui contient tous les éléments intégrés.
En savoir plus sur la compilation →
Développement et production
Wails se comporte différemment en développement et en production :
Caractéristiques :
- Rechargement à chaud : les modifications du frontend sont rechargées instantanément
- Mappages de sources : débogage à partir du code source d’origine
- Outils de développement : les outils de développement du navigateur sont disponibles
- Journalisation : journalisation détaillée activée
- Frontend externe : servi par le serveur de développement (Vite)
Fonctionnement :
Avantages :
- Retour immédiat sur les modifications
- Fonctionnalités de débogage complètes
- Itérations plus rapides
Caractéristiques :
- Ressources intégrées : le frontend est incorporé au binaire
- Optimisé : minifié et compressé
- Aucun outil de développement : désactivés par défaut
- Journalisation minimale : erreurs uniquement
- Fichier unique : tous les éléments sont regroupés dans un seul exécutable
Fonctionnement :
Avantages :
- Distribution sous forme de fichier unique
- Taille réduite (minifié)
- Meilleures performances
- Aucune dépendance externe
Modèle de mémoire
Comprendre l’utilisation de la mémoire vous aide à créer des applications efficaces.
Zones de mémoire :
- Tas Go
- Vos services et l’état de votre application
- Géré par le ramasse-miettes de Go
- Généralement 5-10MB pour les applications simples
- Mémoire de la WebView
- DOM, tas JavaScript, CSS
- Gérée par le moteur de la WebView
- Généralement 10-20MB pour les applications simples
- Mémoire du pont
- Tampons de messages pour la communication
- Surcoût minimal (<1MB)
- Copie nulle pour les données volumineuses lorsque cela est possible
Conseils d’optimisation :
- Évitez les transferts de données volumineux : transmettez des identifiants et récupérez les détails à la demande
- Utilisez des événements pour les mises à jour : n’effectuez pas d’interrogations périodiques depuis le frontend
- Diffusez les fichiers volumineux : ne les chargez pas entièrement en mémoire
- Nettoyez les écouteurs : supprimez les écouteurs d’événements lorsqu’ils ne sont plus nécessaires
En savoir plus sur les performances →
Modèle de sécurité
Wails fournit une architecture sécurisée par défaut :
Fonctionnalités de sécurité :
- Liste blanche des méthodes
- Seules les méthodes exportées peuvent être appelées
- Les méthodes privées sont inaccessibles
- L’enregistrement explicite des services est obligatoire
- Validation des types
- Les arguments sont vérifiés par rapport aux types Go
- Les types non valides sont rejetés
- Empêche les attaques par injection
- Aucun eval()
- Le frontend ne peut pas exécuter de code Go arbitraire
- Seules les méthodes prédéfinies peuvent être appelées
- Aucune exécution dynamique de code
- Isolation du contexte
- Chaque fenêtre possède son propre contexte
- Les services peuvent vérifier le contexte de l’appelant
- Des autorisations par fenêtre sont possibles
Bonnes pratiques :
- Validez les saisies utilisateur dans Go (ne faites pas confiance au frontend)
- Utilisez le contexte pour l’authentification et l’autorisation
- Assainissez les chemins de fichiers avant toute opération sur les fichiers
- Limitez la fréquence des opérations coûteuses
En savoir plus sur la sécurité →
Étapes suivantes
Cycle de vie de l’application - Comprenez le démarrage, l’arrêt et les hooks de cycle de vie En savoir plus →
Pont entre Go et le frontend - Découvrez en détail le fonctionnement du pont En savoir plus →
Système de build - Comprenez comment Wails construit votre application En savoir plus →
Commencez à développer - Mettez en pratique ce que vous avez appris dans un tutoriel Tutoriels →
Des questions sur l’architecture ? Posez-les sur Discord ou consultez la référence de l’API.