Même si vous oubliez tout ce que vous savez sur JavaScript, vous n'oublierez jamais : il bloque.
Imaginez qu'il y ait un elfe magique vivant dans votre navigateur, responsable du fonctionnement normal du navigateur. Qu'il s'agisse du rendu HTML, de la réponse aux commandes de menu, du rendu de l'écran, de la gestion des clics de souris ou de l'exécution de fonctions JavaScript, tout est géré par un seul elfe. Il est tellement occupé qu'il ne peut gérer qu'une seule chose à la fois. Si vous lui confiez plusieurs tâches en même temps, il dressera une longue liste de tâches et les terminera dans l'ordre.
Les gens souhaitent souvent que le JavaScript qui initialise les composants et les gestionnaires d'événements soit exécuté le plus rapidement possible. Cependant, certaines tâches en arrière-plan moins importantes n'affectent pas directement l'expérience utilisateur, comme :
Statistiques d'enregistrement
Envoyer des données au réseau social (ou ajouter un bouton « Partager »)
Contenu préchargé
Prétraiter ou pré-afficher le HTML
Ils ne sont pas stricts dans le temps, mais pour que la page reste réactive, ils ne sont exécutés que lorsque l'utilisateur fait défiler la page ou interagit avec le contenu.
Une option est Web Workers, qui peut exécuter du code simultanément dans des threads indépendants. Idéal pour le préchargement et le prétraitement, mais vous n'avez pas d'accès direct ni de mise à jour du DOM. Vous pouvez contourner ce problème dans votre propre code, mais rien ne garantit que les scripts tiers comme Google Analytics n'en auront jamais besoin.
Une autre option est setTimeout, telle que setTimeout(doSomething, 1);. Une fois les autres tâches immédiates exécutées, le navigateur exécutera la fonction doSomething(). En fait, cela a été relégué au bas de la liste des choses à faire. Malheureusement, la fonction sera appelée quels que soient les besoins de traitement.
#requestIdleCallback
requestIdleCallback est une nouvelle API, utilisée pour effectuer des tâches planifiées en arrière-plan moins importantes lorsque le navigateur prend une pause. Cela rappelle forcément requestAnimationFrame, qui exécute la fonction de mise à jour de l'animation avant le prochain redessin. Si vous souhaitez en savoir plus, cliquez ici : Utilisez requestAnimationFrame pour réaliser des animations simples.
Surveillance de la fonctionnalité requestIdleCallback :
if ('requestIdleCallback' in window) { // requestIdleCallback supported requestIdleCallback(backgroundTask); } else { // no support - do something else setTimeout(backgroundTask1, 1); setTimeout(backgroundTask2, 1); setTimeout(backgroundTask3, 1); }
Vous pouvez également spécifier des objets de paramètres de configuration, tels que le délai d'attente,
requestIdleCallback(backgroundTask, { timeout: 3000; });
Assurez-vous que la fonction est appelée dans les 3 secondes, que le navigateur soit inactif ou non.
Lorsque l'objet date limite passe les paramètres suivants, requestIdleCallback n'exécute le rappel qu'une seule fois :
didTimeout - Défini sur true si le délai d'attente facultatif se déclenche
timeRemaining()—— La fonction renvoie le nombre de millisecondes restant pour exécuter la tâche
timeRemaining() alloue jusqu'à 50 ms pour l'exécution de la tâche. Si cette limite est dépassée, la tâche ne sera pas arrêtée. Cependant, il est préférable de rappeler requestIdleCallback pour organiser la suite du traitement.
Créons un exemple simple pour exécuter plusieurs tâches en séquence. La référence de fonction de la tâche est stockée dans le tableau :
//待执行的函数数组 var task = [ background1, background2, background3 ]; if ('requestIdleCallback' in window) { //支持 requestIdleCallback requestIdleCallback(backgroundTask); } else { //不支持 —— 立刻执行所有任务 while (task.length) { setTimeout(task.shift(), 1); } } //requestIdleCallback 回调函数 function backgroundTask(deadline) { //如果存在,执行下一个任务 while (deadline.timeRemaining() > 0 && task.length > 0) { task.shift()(); } //需要的话,安排进一步任务 if (task.length > 0) { requestIdleCallback(backgroundTask); } }
#Que ne faut-il pas faire entre requestIdleCallback ?
Paul Lewis a mentionné dans son article que les tâches effectuées par une requestIdleCallback doivent être découpées en petits morceaux. Il ne convient pas aux situations temporelles imprévisibles (telles que l'exploitation du DOM, il est préférable d'utiliser le rappel requestAnimationFrame). Soyez également prudent lorsque vous résolvez (ou rejetez) des promesses, la fonction de rappel sera exécutée immédiatement après la fin du rappel inactif, même s'il ne reste plus de temps.
#requestIdleCallback Prise en charge du navigateur
requestIdleCallback est une fonctionnalité expérimentale, la spécification est encore instable et il n'est pas surprenant de rencontrer des changements d'API. Chrome 47 est pris en charge... devrait être disponible avant fin 2015. Opera devrait emboîter le pas. Microsoft et Mozilla réfléchissent à la question de savoir si les API doivent prendre en charge les promesses. Apple, comme à son habitude, se montre pessimiste.
Paul Lewis (mentionné ci-dessus) a écrit un simple shim requestIdleCallback, qui peut simuler le comportement de surveillance inactive du navigateur, mais n'est pas un polyfill (la différence entre shim et polyfill).
Le code de cale requestIdleCallback est le suivant :
/*! * Copyright Google Inc. All rights reserved. * * Licensed under the Apache License, Version . (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-. * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing * permissions and limitations under the License. */ /* * @see https://developers.google.com/web/updates///using-requestidlecallback */ window.requestIdleCallback = window.requestIdleCallback || function (cb) { var start = Date.now(); return setTimeout(function () { cb({ didTimeout: false, timeRemaining: function () { return Math.max(, - (Date.now() - start)); } }); }, ); } window.cancelIdleCallback = window.cancelIdleCallback || function (id) { clearTimeout(id); }
ps : Comment exécuter une tâche planifiée
1. Exécutez GPEDIT.MSC
2. Sélectionnez la configuration de l'ordinateur
--- Paramètres Windows
Paramètres de sécurité
—Stratégie locale
—-Attribution des droits d'utilisateur
Double-cliquez sur Accéder à cet ordinateur depuis le réseau à droite
Ajoutez les noms d'utilisateur requis à la liste.
3. --- Paramètres de sécurité
---Choix sûr
Activez Autoriser les opérateurs de serveur à planifier des tâches
4.-----Stratégie locale
--- Connectez-vous en tant que tâche par lots
Ajoutez les noms d'utilisateur requis à la liste.
5.-----Stratégie locale
--- Autoriser la confiance des ordinateurs et des utilisateurs pour la délégation
Ajoutez les noms d'utilisateur requis à la liste.
Il est préférable d'être l'utilisateur administrateur.
Si le plan de tâches ne peut pas être démarré, code d'invite : 0X80041315
Solution : Il existe deux possibilités. La première est que le service "Task Scheduler" dans le système n'est pas démarré. Vous pouvez taper "services.msc" pendant le fonctionnement pour vérifier si le service "Task Scheduler" est défini sur "Déjà". "Désactiver", si c'est le cas, double-cliquez simplement dessus pour changer le type de démarrage en "Automatique" et réinitialisez une tâche planifiée pour l'exécuter.
Si votre compte actuel est configuré pour se connecter automatiquement et que son mot de passe de connexion est vide, cela peut également empêcher l'exécution du plan de tâches à temps. Dans XP Professional Edition, vous devez exécuter "gpedit.msc" pour. modifiez la stratégie de groupe : développez Configuration "Ordinateur" → Paramètres Windows → Paramètres de sécurité → Stratégie de l'ordinateur local → Options de sécurité ; double-cliquez sur l'élément " Comptes : les comptes locaux avec des mots de passe vides autorisent uniquement la connexion à la console " à droite, puis sélectionnez " Désactivé" dans la boîte de dialogue contextuelle.