Pantalla de inicio (Splashscreen)
En este laboratorio implementaremos una funcionalidad básica de pantalla de inicio en una aplicación Tauri. Hacer esto es bastante sencillo; una pantalla de inicio es efectivamente solo cuestión de crear una nueva ventana que muestre algún contenido durante el período en el que tu aplicación realiza tareas pesadas de configuración y luego cerrarla cuando la configuración haya terminado.
Requisitos previos
Sección titulada “Requisitos previos”-
Instalar dependencias y ejecutar el proyecto
Sección titulada "Instalar dependencias y ejecutar el proyecto"Antes de comenzar a desarrollar cualquier proyecto, es importante compilar y ejecutar la plantilla inicial, solo para validar que tu configuración funcione como se espera.
# Make sure you're in the right directorycd splashscreen-lab# Install dependenciespnpm install# Build and run the apppnpm tauri dev
-
Registrar nuevas ventanas en
Sección titulada "Registrar nuevas ventanas en tauri.conf.json"tauri.conf.jsonLa forma más fácil de agregar nuevas ventanas es agregándolas directamente a
tauri.conf.json. También puedes crearlas dinámicamente al iniciar la aplicación, pero para simplificar, simplemente las registraremos. Asegúrate de tener una ventana con la etiquetamainque se cree como una ventana oculta y una ventana con la etiquetasplashscreenque se cree para mostrarse directamente. Puedes dejar todas las demás opciones en sus valores predeterminados o ajustarlas según tus preferencias.src-tauri/tauri.conf.json {"windows": [{"label": "main","visible": false},{"label": "splashscreen","url": "/splashscreen"}]} -
Crear una nueva página para alojar tu pantalla de inicio
Sección titulada "Crear una nueva página para alojar tu pantalla de inicio"Antes de comenzar, necesitarás tener algo de contenido para mostrar. La forma en que desarrolles nuevas páginas depende del framework elegido, la mayoría tiene el concepto de un "enrutador" que maneja la navegación de páginas, el cual debería funcionar con normalidad en Tauri; en cuyo caso simplemente creas una nueva página de pantalla de inicio. O, como vamos a hacer aquí, crea un nuevo archivo
splashscreen.htmlpara alojar el contenido.Lo importante aquí es que puedas navegar a una URL
/splashscreeny ver el contenido que deseas para tu pantalla de inicio. ¡Intenta ejecutar la aplicación nuevamente después de este paso!/splashscreen.html <!doctype html><html lang="en"><head><meta charset="UTF-8" /><link rel="stylesheet" href="/src/styles.css" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Tauri App</title></head><body><div class="container"><h1>Tauri used Splash!</h1><div class="row"><h5>It was super effective!</h5></div></div></body></html>
-
Iniciar algunas tareas de configuración
Sección titulada "Iniciar algunas tareas de configuración"Dado que las pantallas de inicio generalmente están destinadas a ocultar tareas pesadas de configuración, vamos a simular darle a la aplicación algo pesado para hacer, una parte en el frontend y otra en el backend.
Para simular una configuración pesada en el frontend usaremos una función
setTimeoutsimple.La forma más fácil de simular operaciones pesadas en el backend es usando la crate Tokio, que es la crate de Rust que Tauri utiliza en el backend para proporcionar un runtime asíncrono. Aunque Tauri proporciona el runtime, hay varias utilidades que Tauri no vuelve a exportar desde él, por lo que necesitaremos agregar la crate a nuestro proyecto para acceder a ellas. Esta es una práctica perfectamente normal dentro del ecosistema de Rust.
No uses
std::thread::sleepen funciones asíncronas; se ejecutan de forma cooperativa en un entorno concurrente, no en paralelo, lo que significa que si duermes el hilo en lugar de la tarea de Tokio, bloquearás todas las tareas programadas para ejecutarse en ese hilo, provocando que tu aplicación se congele.# Run this command where the `Cargo.toml` file iscd src-tauri# Add the Tokio cratecargo add tokio -F time# Optionally go back to the top folder to keep developing# `tauri dev` can figure out where to run automaticallycd ..src/main.ts // These contents can be copy-pasted below the existing code, don't replace the entire file!!// Utility function to implement a sleep function in TypeScriptfunction sleep(seconds: number): Promise<void> {return new Promise(resolve => setTimeout(resolve, seconds * 1000));}// Setup functionasync function setup() {// Fake perform some really heavy setup taskconsole.log('Performing really heavy frontend setup task...')await sleep(3);console.log('Frontend setup task complete!')// Set the frontend task as being completedinvoke('set_complete', {task: 'frontend'})}// Effectively a JavaScript main functionwindow.addEventListener("DOMContentLoaded", () => {setup()});/src-tauri/src/lib.rs // Import functionalities we'll be usinguse std::sync::Mutex;use tauri::async_runtime::spawn;use tauri::{AppHandle, Manager, State};use tokio::time::{sleep, Duration};// Create a struct we'll use to track the completion of// setup related tasksstruct SetupState {frontend_task: bool,backend_task: bool,}// Our main entrypoint in a version 2 mobile compatible app#[cfg_attr(mobile, tauri::mobile_entry_point)]pub fn run() {// Don't write code before Tauri starts, write it in the// setup hook instead!tauri::Builder::default()// Register a `State` to be managed by Tauri// We need write access to it so we wrap it in a `Mutex`.manage(Mutex::new(SetupState {frontend_task: false,backend_task: false,}))// Add a command we can use to check.invoke_handler(tauri::generate_handler![greet, set_complete])// Use the setup hook to execute setup related tasks// Runs before the main loop, so no windows are yet created.setup(|app| {// Spawn setup as a non-blocking task so the windows can be// created and ran while it executesspawn(setup(app.handle().clone()));// The hook expects an Ok resultOk(())})// Run the app.run(tauri::generate_context!()).expect("error while running tauri application");}#[tauri::command]fn greet(name: String) -> String {format!("Hello {name} from Rust!")}// A custom task for setting the state of a setup task#[tauri::command]async fn set_complete(app: AppHandle,state: State<'_, Mutex<SetupState>>,task: String,) -> Result<(), ()> {// Lock the state without write accesslet mut state_lock = state.lock().unwrap();match task.as_str() {"frontend" => state_lock.frontend_task = true,"backend" => state_lock.backend_task = true,_ => panic!("invalid task completed!"),}// Check if both tasks are completedif state_lock.backend_task && state_lock.frontend_task {// Setup is complete, we can close the splashscreen// and unhide the main window!let splash_window = app.get_webview_window("splashscreen").unwrap();let main_window = app.get_webview_window("main").unwrap();splash_window.close().unwrap();main_window.show().unwrap();}Ok(())}// An async function that does some heavy setup taskasync fn setup(app: AppHandle) -> Result<(), ()> {// Fake performing some heavy action for 3 secondsprintln!("Performing really heavy backend setup task...");sleep(Duration::from_secs(3)).await;println!("Backend setup task completed!");// Set the backend task as being completed// Commands can be ran as regular functions as long as you take// care of the input arguments yourselfset_complete(app.clone(),app.state::<Mutex<SetupState>>(),"backend".to_string(),).await?;Ok(())} -
Ejecutar la aplicación
Sección titulada "Ejecutar la aplicación"¡Ahora deberías ver aparecer una ventana de pantalla de inicio, tanto el frontend como el backend realizarán sus respectivas tareas pesadas de configuración de 3 segundos, después de lo cual la pantalla de inicio desaparece y se muestra la ventana principal!
Discusión
Sección titulada "Discusión"¿Deberías tener una pantalla de inicio?
Sección titulada "¿Deberías tener una pantalla de inicio?"En general, tener una pantalla de inicio es una admisión de derrota de que no pudiste hacer que tu aplicación se cargara lo suficientemente rápido como para no necesitar una. De hecho, tiende a ser mejor ir directamente a la ventana principal y mostrar un pequeño indicador de carga en alguna esquina que informe al usuario de que aún hay tareas de configuración ejecutándose en segundo plano.
Sin embargo, dicho esto, puede ser una elección estilística querer tener una pantalla de inicio, o podrías tener un requisito muy particular que haga imposible iniciar la aplicación hasta que se realicen ciertas tareas. Definitivamente no está mal tener una pantalla de inicio, simplemente suele no ser necesaria y puede hacer que los usuarios sientan que la aplicación no está muy bien optimizada.
© 2026 Colaboradores de Tauri. CC-BY / MIT