javascript - V8 可以执行 JS 代码的构建时预编译吗?

标签 javascript android v8 escape-analysis ahead-of-time-compile

我们正在尝试优化 JS 代码在移动设备上的启动时间并寻找机会。我找到了Facebook Hermes JS engine出于类似目的而创建,但我们目前严重依赖 V8。

是否可以使用 V8 来完成构建时预编译,这意味着解析和代码优化将在编译时完成并在运行时节省一些时间?从源代码生成 LLVM 位代码并在运行时执行位代码似乎与我想象的非常接近。 WASM 似乎不是一个选择(至少对于移动设备而言)。

如果可能的话,能否提供一个使用 V8 优化的简单 JS 代码的简单示例?

PS。也许它也有助于减少内存消耗,这可能是次要目标。

最佳答案

V8支持heap snapshots正是为了这个目的。这是used by the Atom editor例如,为了缩短启动时间。与其说是预编译,不如说是预构建全局环境并实例化函数(可能尚未编译,只是转换为 Ignition 的字节码,这就足够了)。如果您使用 Electron,则 mksnapshot npm package可能有用。 (如果没有,了解它的工作原理可能仍然有用。)

我没有做过任何 V8 黑客攻击,但是 example他们链接自blog post above如下:

TEST(PerIsolateSnapshotBlobs) {
  DisableTurbofan();
  const char* source1 = "function f() { return 42; }";
  const char* source2 =
      "function f() { return g() * 2; }"
      "function g() { return 43; }"
      "/./.test('a')";
  v8::StartupData data1 = v8::V8::CreateSnapshotDataBlob(source1);
  v8::StartupData data2 = v8::V8::CreateSnapshotDataBlob(source2);
  v8::Isolate::CreateParams params1;
  params1.snapshot_blob = &data1;
  params1.array_buffer_allocator = CcTest::array_buffer_allocator();
  v8::Isolate* isolate1 = v8::Isolate::New(params1);
  {
    v8::Isolate::Scope i_scope(isolate1);
    v8::HandleScope h_scope(isolate1);
    v8::Local<v8::Context> context = v8::Context::New(isolate1);
    delete[] data1.data;  // We can dispose of the snapshot blob now.
    v8::Context::Scope c_scope(context);
    CHECK_EQ(42, CompileRun("f()")->ToInt32(isolate1)->Int32Value());
    CHECK(CompileRun("this.g")->IsUndefined());
  }
  isolate1->Dispose();
  v8::Isolate::CreateParams params2;
  params2.snapshot_blob = &data2;
  params2.array_buffer_allocator = CcTest::array_buffer_allocator();
  v8::Isolate* isolate2 = v8::Isolate::New(params2);
  {
    v8::Isolate::Scope i_scope(isolate2);
    v8::HandleScope h_scope(isolate2);
    v8::Local<v8::Context> context = v8::Context::New(isolate2);
    delete[] data2.data;  // We can dispose of the snapshot blob now.
    v8::Context::Scope c_scope(context);
    CHECK_EQ(86, CompileRun("f()")->ToInt32(isolate2)->Int32Value());
    CHECK_EQ(43, CompileRun("g()")->ToInt32(isolate2)->Int32Value());
  }
  isolate2->Dispose();
}

那篇博文(以及相关的示例?)是 2015 年的,所以事情可能从那时起就发生了变化。

关于javascript - V8 可以执行 JS 代码的构建时预编译吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65773255/

相关文章:

javascript - Node.js v8 HOLEY 数组意外行为

C++ 作用域和 Google V8 脚本上下文

javascript - 如何在正则表达式替换中插入回车

javascript - 如何应用日期范围?

javascript - 需要从头开始使用 HTML/CSS 和 Javascript 制作计算器

java - 如何在Android Vision API中设置全屏?

java - 如何在 android 上的 textView 中设置 List<String>

Android:Listview 不保存复选框的状态

javascript - 如何从异步调用返回响应?

c++ - Node js 原生模块,从 Objective-C block 事件监听器触发回调不起作用