src: use v8::Isolate::GetDefaultLocale() to compute navigator.language

Using the Intl API to get the default locale slows down the startup
significantly. This patch uses a new v8 API to get the default locale
directly.

PR-URL: https://github.com/nodejs/node/pull/54279
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Ethan Arrowood <ethan@arrowood.dev>
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
Joyee Cheung 2024-08-09 02:52:02 +02:00 committed by Node.js GitHub Bot
parent 54e20c1c94
commit 75741a1952
4 changed files with 26 additions and 9 deletions

View File

@ -30,7 +30,7 @@ const {
} = require('internal/process/per_thread');
const {
language,
getDefaultLocale,
} = internalBinding('config');
/**
@ -104,7 +104,9 @@ class Navigator {
* @return {string}
*/
get language() {
return language;
// The default locale might be changed dynamically, so always invoke the
// binding.
return getDefaultLocale() || 'en-US';
}
/**

View File

@ -20,10 +20,6 @@ const {
globalThis,
} = primordials;
const {
Intl,
} = globalThis;
const {
getOptionValue,
refreshOptions,
@ -333,7 +329,6 @@ function setupNavigator() {
// https://html.spec.whatwg.org/multipage/system-state.html#the-navigator-object
exposeLazyInterfaces(globalThis, 'internal/navigator', ['Navigator']);
internalBinding('config').language = Intl?.Collator().resolvedOptions().locale || 'en-US';
defineReplaceableLazyAttribute(globalThis, 'internal/navigator', ['navigator'], false);
}

View File

@ -2,6 +2,7 @@
#include "memory_tracker.h"
#include "node.h"
#include "node_builtins.h"
#include "node_external_reference.h"
#include "node_i18n.h"
#include "node_options.h"
#include "util-inl.h"
@ -9,12 +10,23 @@
namespace node {
using v8::Context;
using v8::FunctionCallbackInfo;
using v8::Isolate;
using v8::Local;
using v8::Number;
using v8::Object;
using v8::Value;
void GetDefaultLocale(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
Local<Context> context = isolate->GetCurrentContext();
std::string locale = isolate->GetDefaultLocale();
Local<Value> result;
if (ToV8Value(context, locale).ToLocal(&result)) {
args.GetReturnValue().Set(result);
}
}
// The config binding is used to provide an internal view of compile time
// config options that are required internally by lib/*.js code. This is an
// alternative to dropping additional properties onto the process object as
@ -23,7 +35,7 @@ using v8::Value;
// Command line arguments are already accessible in the JS land via
// require('internal/options').getOptionValue('--some-option'). Do not add them
// here.
static void Initialize(Local<Object> target,
static void InitConfig(Local<Object> target,
Local<Value> unused,
Local<Context> context,
void* priv) {
@ -76,8 +88,15 @@ static void Initialize(Local<Object> target,
#endif // NODE_NO_BROWSER_GLOBALS
READONLY_PROPERTY(target, "bits", Number::New(isolate, 8 * sizeof(intptr_t)));
SetMethodNoSideEffect(context, target, "getDefaultLocale", GetDefaultLocale);
} // InitConfig
void RegisterConfigExternalReferences(ExternalReferenceRegistry* registry) {
registry->Register(GetDefaultLocale);
}
} // namespace node
NODE_BINDING_CONTEXT_AWARE_INTERNAL(config, node::Initialize)
NODE_BINDING_CONTEXT_AWARE_INTERNAL(config, node::InitConfig)
NODE_BINDING_EXTERNAL_REFERENCE(config, node::RegisterConfigExternalReferences)

View File

@ -139,6 +139,7 @@ class ExternalReferenceRegistry {
V(buffer) \
V(builtins) \
V(cares_wrap) \
V(config) \
V(contextify) \
V(credentials) \
V(encoding_binding) \