Version V8 v7.6
Toutes les six semaines, nous créons une nouvelle branche de V8 dans le cadre de notre processus de sortie. Chaque version est dérivée du master Git de V8 juste avant une étape Beta de Chrome. Aujourd’hui, nous sommes heureux d’annoncer notre nouvelle branche, V8 version 7.6, actuellement en version beta jusqu’à sa sortie en coordination avec Chrome 76 Stable dans plusieurs semaines. V8 v7.6 est rempli de nombreuses nouveautés pour les développeurs. Cet article donne un aperçu de certains points forts en prévision de la sortie.
Performances (taille & vitesse)
Améliorations de JSON.parse
Dans les applications JavaScript modernes, le JSON est couramment utilisé comme format pour communiquer des données structurées. En accélérant l'analyse JSON, nous pouvons réduire la latence de cette communication. Dans V8 v7.6, nous avons révisé notre analyseur JSON pour qu’il soit beaucoup plus rapide dans le balayage et l’analyse du JSON. Cela se traduit par une analyse jusqu’à 2,7× plus rapide des données servies par des pages Web populaires.
Jusqu’à V8 v7.5, l’analyseur JSON était un analyseur récursif qui utilisait la pile native en fonction de la profondeur d’imbrication des données JSON entrantes. Cela signifiait que nous pouvions manquer de pile pour des données JSON très profondément imbriquées. V8 v7.6 passe à un analyseur itératif qui gère sa propre pile, limitée uniquement par la mémoire disponible.
Le nouveau parseur JSON est également plus efficace en termes de mémoire. En mettant en mémoire tampon les propriétés avant de créer l’objet final, nous pouvons désormais décider comment allouer le résultat de manière optimale. Pour les objets avec des propriétés nommées, nous allouons des objets avec la quantité exacte d’espace nécessaire pour les propriétés nommées dans les données JSON entrantes (jusqu’à 128 propriétés nommées). Si les objets JSON contiennent des noms de propriété indexés, nous allouons un espace de stockage d’éléments qui utilise un minimum d’espace, soit un tableau plat, soit un dictionnaire. Les tableaux JSON sont maintenant analysés dans un tableau dont la taille correspond exactement au nombre d’éléments des données d’entrée.
Améliorations des tableaux congelés/sellés
Les performances des appels sur des tableaux congelés ou scellés (et des objets similaires aux tableaux) ont reçu de nombreuses améliorations. V8 v7.6 améliore les modèles de codage JavaScript suivants, où frozen
est un tableau ou un objet similaire à un tableau congelé ou scellé :
frozen.indexOf(v)
frozen.includes(v)
- appels avec propagation comme
fn(...frozen)
- appels avec une propagation imbriquée comme
fn(...[...frozen])
- appels avec apply et propagation comme
fn.apply(this, [...frozen])
Le graphique ci-dessous montre les améliorations.
Voir le document de conception “fast frozen & sealed elements in V8” pour plus de détails.
Gestion des chaînes Unicode
Une optimisation lors de la conversion de chaînes en Unicode a permis une accélération significative des appels tels que String#localeCompare
, String#normalize
, et certaines des API Intl
. Par exemple, ce changement a permis de doubler environ le débit brut de String#localeCompare
pour des chaînes d’un byte.
Fonctionnalités du langage JavaScript
Promise.allSettled
Promise.allSettled(promises)
fournit un signal lorsque toutes les promesses en entrée sont résolues, ce qui signifie qu’elles sont soit tenues, soit rejetées. Cela est utile dans les cas où l’état de la promesse ne vous importe pas, vous voulez seulement savoir quand le travail est terminé, qu’il ait réussi ou échoué. Notre explication sur les combinateurs de promesses contient plus de détails et inclut un exemple.
Meilleur support pour BigInt
BigInt
dispose maintenant d’un meilleur support API dans le langage. Vous pouvez maintenant formater un BigInt
d’une manière adaptée à la locale en utilisant la méthode toLocaleString
. Cela fonctionne de la même manière que pour les nombres ordinaires :
12345678901234567890n.toLocaleString('en'); // 🐌
// → '12,345,678,901,234,567,890'
12345678901234567890n.toLocaleString('de'); // 🐌
// → '12.345.678.901.234.567.890'
Si vous prévoyez de formater plusieurs nombres ou BigInt
en utilisant la même locale, il est plus efficace d’utiliser l’API Intl.NumberFormat
, qui prend désormais en charge les BigInt
dans ses méthodes format
et formatToParts
. De cette manière, vous pouvez créer une instance de formateur réutilisable.
const nf = new Intl.NumberFormat('fr');
nf.format(12345678901234567890n); // 🚀
// → '12 345 678 901 234 567 890'
nf.formatToParts(123456n); // 🚀
// → [
// → { type: 'integer', value: '123' },
// → { type: 'group', value: ' ' },
// → { type: 'integer', value: '456' }
// → ]
Améliorations d'Intl.DateTimeFormat
Les applications affichent souvent des intervalles ou des plages de dates pour montrer la durée d'un événement, comme une réservation d'hôtel, une période de facturation ou un festival de musique. L'API Intl.DateTimeFormat
prend désormais en charge les méthodes formatRange
et formatRangeToParts
permettant de formater facilement les plages de dates de manière spécifique à la langue et à la région.
const start = new Date('2019-05-07T09:20:00');
// → '7 mai 2019'
const end = new Date('2019-05-09T16:00:00');
// → '9 mai 2019'
const fmt = new Intl.DateTimeFormat('fr', {
year: 'numeric',
month: 'long',
day: 'numeric',
});
const output = fmt.formatRange(start, end);
// → '7 – 9 mai 2019'
const parts = fmt.formatRangeToParts(start, end);
// → [
// → { 'type': 'month', 'value': 'mai', 'source': 'shared' },
// → { 'type': 'literal', 'value': ' ', 'source': 'shared' },
// → { 'type': 'day', 'value': '7', 'source': 'startRange' },
// → { 'type': 'literal', 'value': ' – ', 'source': 'shared' },
// → { 'type': 'day', 'value': '9', 'source': 'endRange' },
// → { 'type': 'literal', 'value': ', ', 'source': 'shared' },
// → { 'type': 'year', 'value': '2019', 'source': 'shared' },
// → ]
De plus, les méthodes format
, formatToParts
et formatRangeToParts
prennent désormais en charge les nouvelles options timeStyle
et dateStyle
:
const dtf = new Intl.DateTimeFormat('de', {
timeStyle: 'medium',
dateStyle: 'short'
});
dtf.format(Date.now());
// → '19.06.19, 13:33:37'
Parcours natif de la pile
Alors que V8 peut parcourir sa propre pile d'appels (par exemple, lors du débogage ou du profilage dans DevTools), le système d'exploitation Windows était incapable de parcourir une pile d'appels contenant du code généré par TurboFan lorsqu'il fonctionne sur l'architecture x64. Cela pouvait provoquer des piles cassées lors de l'utilisation de débogueurs natifs ou de l'échantillonnage ETW pour analyser des processus utilisant V8. Une modification récente permet à V8 de enregistrer les métadonnées nécessaires pour que Windows puisse parcourir ces piles sur x64, et dans v7.6 cela est activé par défaut.
API V8
Veuillez utiliser git log branch-heads/7.5..branch-heads/7.6 include/v8.h
pour obtenir une liste des modifications de l'API.
Les développeurs avec un dépôt V8 actif peuvent utiliser git checkout -b 7.6 -t branch-heads/7.6
pour expérimenter les nouvelles fonctionnalités de V8 v7.6. Alternativement, vous pouvez vous abonner au canal Beta de Chrome et essayer bientôt les nouvelles fonctionnalités vous-même.