Cet article vous aidera à comprendre le modèle double thread dans les mini-programmes WeChat. Parlons de ce qu'est le modèle double-thread des mini-programmes ? Pourquoi l'applet n'utilise-t-elle pas le modèle de thread du navigateur, mais utilise le modèle à double thread ? J'espère qu'elle sera utile à tout le monde !
Les amis qui ont de l'expérience dans le développement d'applets WeChat devraient tous connaître le concept de « modèle à double thread ». Cet article résume brièvement certaines connaissances scientifiques populaires sur le modèle à double thread. erreurs, veuillez me corriger.
J'ai travaillé dans l'équipe "Mini Programme·Cloud Development". Lors de certaines formations externes et partage de technologie, on m'a souvent posé cette question : "Quelle est la principale différence technique entre le mini programme WeChat et le site Web ?" du langage et du paradigme de programmation, le développement de petits programmes est très similaire au développement frontal Web (par exemple, les deux utilisent le langage JavaScript, WXML/WXSS, qui est très similaire au HTML/CSS, etc.), mais il n'utilise pas directement technologie frontale native. [Recommandations d'apprentissage associées : Tutoriel de développement de mini-programmes]
Par rapport aux sites Web Web, les mini-programmes hébergés sur WeChat doivent prendre en compte la sécurité, les performances et d'autres facteurs pour garantir que les mini-programmes ne poseront pas de risques de sécurité pour l'application WeChat elle-même. , tout en essayant d'atteindre des performances et une expérience utilisateur proches des applications natives. Ce sont les deux principales raisons pour lesquelles les petits programmes n'utilisent pas directement le modèle de thread du navigateur et doivent créer eux-mêmes un modèle à double thread.
Alors, quel est le modèle dual-thread des petits programmes ?
La meilleure façon de comprendre un nouveau concept ou une nouvelle technologie est de lui donner une référence. Par conséquent, pour comprendre le modèle de thread d'un petit programme, vous devez d'abord avoir une certaine compréhension du modèle de thread du navigateur.
Peut-être que l'intervieweur a demandé plus d'une fois à chaque ingénieur front-end lorsqu'il est entré dans l'industrie : « Comment comprenez-vous le thread unique du front-end parce que le langage JavaScript ? , l'une des compétences de base du front-end, est le threading unique, comprendre et maîtriser pleinement le fonctionnement du thread unique JS est l'exigence la plus fondamentale pour un ingénieur front-end. Mais il existe un malentendu dans lequel tombent facilement de nombreux débutants : comprendre à tort "JavaScript monothread" comme "navigateur monothread".
En fait, l'architecture interne du navigateur est très complexe, mais elle utilise un modèle de gestion mutuellement exclusif et bloquant pour gérer le fil de rendu de l'interface graphique et le fil de script logique JavaScript, ce qui a provoqué des malentendus parmi certains développeurs.
Prenons l'exemple du navigateur Chrome. Cliquez sur le bouton Paramètres dans le coin supérieur droit, puis entrez "Plus d'outils" -> "Gestionnaire des tâches". Vous pouvez voir combien d'options Chrome sont ouvertes. Les processus, y compris les processus du navigateur, les processus réseau, les processus GPU, etc., sont tous des processus courants.
Veuillez noterqu'il y a deux processus d'onglet dans l'image ci-dessus. Chrome ouvre un processus de rendu indépendant (Renderer Process) pour chaque page d'onglet Les ressources (CPU, mémoire, etc.) et les comportements (UI) entre chaque processus, logique. , etc.) ne sont pas partagés entre eux, donc même si une page à onglet plante, cela n'affectera pas les autres pages à onglet.
Dans chaque processus d'onglet, le navigateur confiera différentes tâches aux threads correspondants. Par exemple, le thread de rendu de l'interface graphique est responsable du rendu du HTML dans une interface utilisateur visuelle ; le thread du moteur JavaScript est responsable de l'analyse et de l'exécution de la logique du code JavaScript ; déclenchement du timing Le thread du programmeur est responsable du traitement des timers setTimeout/setInterval, etc.Encore une chose, il y a un endroit où il est facile de se tromper. En fait, setTimeout/setInterval ne fait pas partie du langage JavaScript, mais une fonctionnalité fournie par le runtime (à l'origine le navigateur, et plus tard Node.js). le soutient également).
Le thread de rendu de l'interface graphique et le thread du moteur JavaScript s'excluent mutuellement. JavaScript bloquera le rendu de l'interface utilisateur pendant l'exécution. Même si le temps d'exécution du script est trop long, il plantera car la page ne répond pas pendant une longue période. .C'est le thread de rendu de l'interface graphique et le moteur JavaScript qui font que certains développeurs front-end pensent que le navigateur est monothread. Cette méthode de gestion des threads d'exclusion mutuelle et de blocage entre les threads.Alors pourquoi JavaScript est-il conçu pour être monothread ?Le fondateur de JavaScript n'a mis que 10 jours pour créer ce langage. Au départ, son idée était simplement de fournir une logique de script simple dans le navigateur pour gérer l'interaction de l'utilisateur, les opérations DOM, etc., la conception doit donc suivre deux points :
Syntaxe simple ;
En termes de mécanisme d'exécution, JavaScript ne fournit pas de fonctionnalités multithread comme Java. La raison principale est d'éviter les conflits d'interface utilisateur causés par les opérations DOM multithread. Par exemple, si plusieurs threads exploitent le même DOM en même temps, comment le navigateur doit-il déterminer quel thread est utilisé pour produire l’effet final de l’interface utilisateur ? Il s'agit d'un problème classique de sécurité des threads (également connu sous le nom de synchronisation des threads). Il existe de nombreuses solutions dans le domaine de la programmation multithread, comme l'ajout de mécanismes de verrouillage, mais cela apporte plus de complexité, contrairement à la conception simple et facile à utiliser. de JavaScript Cela va à l’encontre de l’intention initiale.
Cela explique également pourquoi le thread de rendu de l'interface graphique et le thread du moteur JavaScript s'excluent mutuellement : le code JavaScript a la permission de modifier le DOM.
Lorsque le code JavaScript est exécuté, le thread de rendu de l'interface graphique sera suspendu et attendra que le thread du moteur JavaScript soit inactif avant d'être exécuté pour éviter une pression de rendu inutile causée par la modification répétée du DOM par JavaScript pendant le rendu. L'utilisation d'un mode mutuellement exclusif pour attendre la fin de l'exécution du code JavaScript peut garantir que le rendu est le résultat final de l'exécution. Par conséquent, le temps d'inactivité du navigateur est également devenu l'un des indicateurs importants pour mesurer les performances du site Web. Le temps d'inactivité indique principalement que la logique JavaScript n'est pas intensive et que la fréquence des modifications du DOM est faible. Dans ce cas, le navigateur peut répondre aux interactions des utilisateurs. plus rapidement et plus facilement. Le comportement est le suivant :
React Fiber utilise le temps d'inactivité pour traiter les tâches de partitionnement.
Plus tard, HTML5 a introduit Web Worker, qui offre la possibilité d'exécuter du code JavaScript dans plusieurs threads. Cependant, contrairement à d'autres langages de programmation, le thread Worker n'est pas parallèle au thread principal, mais est une sorte de Multi maître-esclave. -modèle fileté. Le code JavaScript dans
Worker ne peut pas faire fonctionner le DOM et peut être compris comme thread-safe. Gardez cela à l'esprit. Il s'agit d'une base importante pour le modèle double thread de petits programmes discuté plus tard.
Alors pourquoi les mini-programmes WeChat n’utilisent-ils pas directement le modèle de thread du navigateur ? Cela nécessite de comparer les différences entre les mini-programmes et les sites Web du point de vue du produit et du point de vue technique.
Lorsque je suis entré en contact pour la première fois avec le développement de mini-programmes, j'ai souvent « détesté » ses capacités affaiblies par rapport au Web et sa syntaxe trop simple par rapport à Vue. À cette époque, j’avais presque l’impression que les mini-programmes constituaient le monopole technologique de WeChat s’appuyant sur son grand nombre d’utilisateurs.
Cependant, avec la compréhension approfondie et continue de la technologie et des produits, mon attitude envers les mini-programmes a également changé, de « je n'aime pas » à l'admiration, car après avoir pleinement compris le positionnement produit des mini-programmes, j'ai trouvé Double Le modèle de fil est la solution optimale dans des scénarios de produits tels que les petits programmes. Alors, quel type de produit est le mini-programme ?
L'hôte du mini programme est WeChat, mais l'itération de la version du mini programme est indépendante et les mises à niveau et mises à jour ne dépendent pas de l'hôte. C'est la même chose que le site Web. En d’autres termes, les mini-programmes héritent de certains avantages du Web, mais ce n’est pas le Web. Actuellement, les technologies liées au Web sont assez complètes et peuvent héberger de très grandes applications, comme des cartes 3D, des jeux, etc.
Le positionnement des mini-programmes est d'être petit, beau et de disparaître après utilisation. Il n'exploite pas toutes les capacités Web de WeChat, il est donc nettement inférieur au Web en termes de capacités. possède certaines fonctionnalités natives fournies par WeChat, telles que les fonctionnalités natives, les API au niveau du système et de l'écosystème WeChat, etc.
De plus, la relation entre « mini programme-WeChat » est différente de la relation entre « site Web-navigateur ». La première est plus proche de chaque cas de programme (appelé cas) dans les plateformes de programmation en ligne telles que CodePen et JSFiddler ( relation plateforme-classe).
D'un point de vue technique, l'une des considérations fondamentales de la plateforme est de garantir que la logique du cas ne mettra pas en danger la sécurité de la plateforme tout en fournissant des capacités suffisantes pour le cas. Imaginez si vous pouviez écrire un programme sur CodePen pour obtenir les informations privées de CodePen, peut-être que CodePen planterait le lendemain et licencierait tous les employés. Sous un tel ton de produit, lorsque la sélection technologique est faite, l'étape suivante est le travail des architectes et des programmeurs.
Prenons CodePen comme exemple. Si on vous demandait de concevoir une telle plateforme de programmation, quelle technologie utiliseriez-vous ?Peut-être que votre première pensée est d'utiliser iframe, car toutes les fonctionnalités Web peuvent être utilisées dans iframe. En fait, CodePen utilise l'iframe pour présenter l'effet du programme, mais il ne copie pas complètement le code JavaScript d'entrée dans l'iframe pour l'exécution. Au lieu de cela, le code passera par un processus de compilation avant d'être injecté dans l'iframe. Le point de départ est principalement basé sur des considérations de sécurité, et certains codes dangereux sont éliminés pendant le processus de compilation ; deuxièmement, cela peut également prendre en charge davantage de languesdans la plate-forme, comme le typescript. Bien sûr, il y a aussi les problèmes de performances qui sont courants avec les iframes, je n'entrerai donc pas dans les détails. Donc, non seulement vous devez utiliser iframe, mais vous devez également introduire un compilateur JavaScript supplémentaire. CodePen doit s'assurer que le code JavaScript dans chaque cas est thread-safe. La chose la plus élémentaire est d'interdire au programme d'exploiter le DOM du site Web CodePen. Il existe deux manières d'y parvenir : L'une est Web Worker ; L'autre consiste à utiliser Shadow DOM. Web Worker est thread-safe. Le code JavaScript dans Worker ne peut pas obtenir les objets Window et Document, et ne peut donc pas faire fonctionner le DOM. De plus, en raison de la fonctionnalité de sécurité des threads de Worker, le code contenu dans Worker ne bloquera pas le thread de rendu de l'interface graphique externe pendant l'exécution, et les deux peuvent s'exécuter en parallèle. Shadow DOM fait partie de la spécification des composants Web. Définir le mode de ShadowRoot sur En comparant les deux, Shadow DOM a une moins bonne compatibilité que Web Worker et est encore loin d'une utilisation à grande échelle, la solution de Web Worker est donc plus réaliste. Cela forme un modèle simple à deux threads : le thread Worker est responsable du calcul, transmettant les résultats au thread principal via postMessage, et le thread principal est responsable du rendu. Cependant, ce modèle présente de sérieux problèmes de performances. Web Worker est très consommateur de ressources. En plus de la consommation informatique, le processus de communication avec le thread principal a également un impact très sérieux sur les performances. Alors existe-t-il un moyen d'obtenir la même sécurité des threads que Web Worker, tout en prenant en compte les performances et en garantissant une bonne expérience utilisateur ? C'est l'objectif principal de l'utilisation du modèle double thread pour l'applet WeChat. Bien que des plates-formes de programmation telles que CodePen aient été utilisées auparavant comme analogie, les exigences techniques des mini-programmes et de CodePen ne sont pas exactement les mêmes. La principale différence est que les mini-programmes n'ont pas besoin d'être pris en charge. toutes les balises HTML, seul un nombre limité de types de composants d'interface utilisateur sont fournis. Selon le positionnement du produit du mini-programme, nous pouvons résumer les principales exigences techniques du mini-programme comme suit. (Toute nouvelle technologie ou architecture est conçue pour résoudre des problèmes spécifiques, il est donc nécessaire de comprendre les principales exigences techniques du mini-programme.) Limiter les types de composants de l'interface utilisateur et autoriser uniquement la déclaration de quelques composants spécifiés Le mini-programme est présent. Lors de la déclaration des composants, vous n'utilisez pas de balises HTML natives. Au lieu de cela, vous ne pouvez utiliser que plusieurs composants de base intégrés fournis par WeChat. Bien sûr, vous pouvez également personnaliser les composants, mais cela se fait également via. une combinaison de composants de base intégrés. Garantit la sécurité des threads logiques et ne permet pas la manipulation directe des composants de l'interface utilisateur La façon dont les mini-programmes mettent à jour l'interface utilisateur est similaire aux frameworks MVVM tels que le code JavaScript Vue/React ne peut pas exploiter directement le DOM (juste par analogie, en fait, dans les mini-programmes, il n'y a pas de concept de DOM), mais l'interface utilisateur est mise à jour de manière asynchrone en mettant à jour l'état (setState). Dans ce processus, VDOM et un algorithme de diff efficace seront utilisés (ces deux points ne sont pas ce que nous allons faire). discuter, vous pouvez le rechercher vous-même après le cours) informations pertinentes). Peut être mis à jour en ligne sans compter sur WeChat L'hôte du mini-programme est WeChat S'il est implémenté en utilisant Pure Native, alors la mise à jour de la version du mini-programme doit s'appuyer sur WeChat et être publiée avec. le code WeChat. Cela ne fonctionnera certainement pas. S’il s’agit d’une implémentation purement web, la sécurité et les performances seront difficiles à garantir. Les mini-programmes doivent pouvoir héberger des ressources dans le cloud comme le Web et être mis à jour de manière indépendante en même temps, ils doivent pouvoir assurer une sécurité et des performances suffisantes. Ainsi, au final, l'applet a adopté un modèle d'architecture mixte : Utilisez Webview pour restituer l'interface utilisateur et utilisez des threads indépendants similaires aux Web Workers pour exécuter la logique Il s'agit du modèle à double thread. Les performances doivent être améliorées autant que possible pour garantir l'expérience utilisateur Les performances du modèle simple à double thread basé sur Web Worker mentionné précédemment sont un gros problème. Le programme n'utilise pas de threads enfants Web Worker. Il s'agit d'un "thread principal" indépendant qui peut garantir des performances relativement bonnes. Les fils doubles de l'applet font référence au fil de rendu et au fil logique. Ces deux fils sont respectivement responsables du rendu de l'interface utilisateur et de l'exécution du code JavaScript. Comme le montre la figure ci-dessous : Le fil de rendu utilise Webview pour restituer l'interface utilisateur. Webview est un environnement d'exécution complet de type navigateur avec la possibilité d'exécuter du JavaScript. Cependant, l'applet ne place pas le script logique dans Webview pour s'exécuter, mais sépare la couche logique en un thread parallèle à Webview, en utilisant le client pour fournir le JavaScript. Le moteur exécute le code, JavaScriptCore d'iOS, l'environnement JsCore d'Android et l'outil IDE nwjs fourni par le noyau X5 de Tencent. Le fil logique est un environnement sandbox qui ne peut exécuter que JavaScript. Il ne fournit pas d'API liées aux opérations DOM, il ne peut donc pas faire fonctionner directement l'interface utilisateur. Il ne peut mettre à jour l'interface utilisateur que de manière asynchrone en mettant à jour les données via setData. Méthode de communication basée sur les événements Faites attention à la méthode de communication entre le fil de rendu et le fil logique dans la figure ci-dessus. Différent de Vue/React, la communication entre la couche de rendu et la couche logique de l'applet. n'est pas entre deux Les données ou événements sont transférés directement entre utilisateurs, mais sont transmis par Native en tant qu'intermédiaire.
D'une part, ce mode de division des threads qui sépare la logique et le rendu peut garantir que le code JavaScript exécuté dans le bac à sable du thread logique est thread-safe. D'autre part, parce que la quantité de calcul du thread de rendu est très faible, cela garantit que le comportement d'interaction de l'utilisateur est sûr. Une réponse rapide améliore l'expérience utilisateur. En général, par rapport au modèle de thread du navigateur, le modèle double thread du mini programme résout ou évite les performances inquiétantes du Web Worker tout en obtenant la même sécurité des threads que le Web Worker, à la fois en termes de performances et de sécurité. a été réalisé sous plusieurs angles. On peut résumer que le . Résumé En comprenant l'arrière-plan, la conception et la communication du modèle double thread du mini-programme, j'espère que tout le monde pourra avoir une compréhension plus approfondie de l'architecture sous-jacente du mini-programme. Il pourra également être utilisé comme référence s'il existe un. nécessité de scénarios similaires dans les travaux ultérieurs. Bien entendu, comprendre le modèle dual-thread des petits programmes n'est pas le seul objectif. Cette connaissance peut dans une certaine mesure inspirer le travail de développement quotidien, principalement en termes de performances :
closed
empêchera l'obtention du nœud ShadowRoot et le DOM interne ne pourra donc pas être manipulé. Modèle double thread sûr et efficace
Fil de rendu et fil logique
La couche de rendu (peut également être appelée couche de vue) déclenche des événements spécifiques via une interaction avec l'utilisateur
À mon avis, la compétence de base et la compétitivité des programmeurs ne sont pas de comprendre pleinement l'API d'un certain langage ou framework, mais la connaissance des principes sous-jacents de ces langages et frameworks. Pour un petit développeur de programme, la solution face à des problèmes techniques au travail repose souvent sur les principes sous-jacents (encore plus simplement, lorsque vous recherchez un entretien d'embauche, personne ne vous posera de questions sur la syntaxe du petit programme).
Essayez d'utiliser des structures simples tout en vous assurant. fonctionnalité. UI ;
Vidéo de programmation
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!