V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
droiz
V2EX  ›  JavaScript

最近研究了一下 JavaScript 引擎嵌入问题,一点点经验分享给大家

  •  5
     
  •   droiz · 2018-04-14 00:03:44 +08:00 · 2118 次点击
    这是一个创建于 2197 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近由于要做基于 Python 的 React Server Rendering 的需求,就调研了下 Python 的 JS 引擎绑定。目前被应用最多的现代 JS 引擎有:

    • V8,Google 开发,霸主级别。

    • SpiderMonkey,Mozilla 开发,一个隐士。

    • JavaScriptCore,Webkit 自带的,主要用在 Apple 系。

    • Chakra,Microsoft 开发,Edge 的 JS 引擎。

    • Duktape,主攻小型化与可嵌入,不是那么主流。

    接着看看他们的可嵌入性怎么样:

    • V8,源码大,编译慢,在大陆地区必须得科学上网才能顺利的弄下来,但生产的服务器通常不会允许你这么搞。做 V8 绑定最好的是 Sony 的 v8eval,直接提供 Ruby, Python, Go 三种语言绑定,在这里又得说一下 Sony 大法好!但问题是你不一定能装上它。

    • SpiderMonkey,文档比较丰富,但源码也挺大,在 3.8GB 左右,需要自己 build,目前貌似很少有 SpiderMonkey 应用在 Mozilla 系软件外的例子,属于比较低调的那一型。

    • JavaScriptCore,主要是在 Apple 系上应用,对于非 Apple 似乎比较麻烦,文档也基本上是在 Apple 系的。

    • Duktape,非常小,省资源,但是 ES6 支持的不行,详细可以看下此表,目前几个 Duktape 的绑定都不支持 let,const,arrow function 这种语法。如果预期的 JS 是低版本的或者只把 JS 当作 DSL,那还是可以用的。

    • Chakra,真业界良心,支持 96% 的 ES6 特性,官方直接提供预编译的动态链接库,支持 OSX,Linux,Win32/64,并且才 20 多 MB,提供 C/C++ API 与引擎交互,可以说 Chakra 是目前在 JS 引擎嵌入这一领域的 最佳且唯一 选择。

    最后我选择 Chakra 作为要绑定的引擎,由于目前 Python 并没有这类的库,所以自己写了一个

    https://github.com/zhengrenzhe/PyChakra/,目前提供了执行执行 JS 字符串与 JS 文件的功能,欢迎 star 嘻嘻。

    Chakra 使用起来很方便,总的来说就三步:

    1. 创建 Runtime
    2. 创建 Context
    3. 执行你的逻辑

    所以以后如果大家有非 Node.js 平台的 JS 执行需求,只要你的语言支持与 C/C++ 交互,那可以很轻易的写出一个 Chakra 绑定出来,以后就不用再纠结没有合适的开源库该怎么办了。

    对于 C/C++ 操作 Chakra,最好的学习平台自然是 Chakra 的官方文档,同时我在学习过程中也写了一篇 blog: Microsoft Chakra 嵌入使用指南,各位在学习过程中也可以作为参考。

    尽情的享受 Chakra 带来的快感吧!嘻嘻。

    29 条回复    2018-04-15 13:58:12 +08:00
    noe132
        1
    noe132  
       2018-04-14 01:41:44 +08:00
    我在想,如果用 javascript 作为嵌入式语言来写游戏的逻辑开发
    比如 Don't Starve 饥荒(游戏多人联机和后期这么卡就是因为 lua )
    应该性能会比 lua 好不少吧?
    https://benchmarksgame-team.pages.debian.net/benchmarksgame/compare/javascript.html
    https://benchmarksgame-team.pages.debian.net/benchmarksgame/compare/lua.html
    根据 Node V8, lua 和 java 的执行效率相对比较,node v8 在很多测试上性能是 lua 的数十倍甚至几十倍
    ericls
        2
    ericls  
       2018-04-14 04:20:53 +08:00 via iPhone
    SSR 不知道用 puppeteer 效果怎样 感觉有点太重……
    faywong8888
        3
    faywong8888  
       2018-04-14 08:45:30 +08:00
    @noe132 很多小型游戏引擎本身就是嵌入 js 来写逻辑的。
    faywong8888
        4
    faywong8888  
       2018-04-14 08:49:13 +08:00
    补充下:

    SpiderMonkey 在 mozilla 的邮件服务软件以及 mongodb 的 client shell 里都有使用的。

    duktape 在嵌入式领域(内存资源受限)、Iot 领域还是很流行的 js 绑定首选,ES6 可以通过 pre-compile 来间接解决,也不是什么大问题,在 2k 行 js 代码量上,性能也不比其他巨型 js 引擎差。

    v8 会 JIT 运行时生成代码,这种在 apple 系 store 上是发布不了的。
    murmur
        5
    murmur  
       2018-04-14 08:59:15 +08:00
    @faywong8888 小游戏不是嵌入 lua 么 才几百 kb 比 js 好折腾多了
    kimown
        6
    kimown  
       2018-04-14 09:33:15 +08:00 via Android
    @murmur
    感觉为了复用已有模块,例如 momentjs 之类,开发效率提升 n 倍,当然体积也会暴增,看取舍
    DearMark
        7
    DearMark  
       2018-04-14 09:46:16 +08:00
    微软 良心企业啊
    KeepPro
        8
    KeepPro  
       2018-04-14 10:04:28 +08:00 via Android
    我司的游戏是嵌入 spidermonkey 的。
    secondwtq
        9
    secondwtq  
       2018-04-14 12:01:25 +08:00
    SpiderMonkey 的文档感觉一般,这东西历史很长,各种时期的文档混在一块,感觉很乱 ... 光名字就各种猴的很难搞清楚
    但是开源界貌似很喜欢用,大概是因为挺根正苗红的,MongoDB,CouchDB
    JSC 代码风格我很喜欢,Apple 的东西不一定经用,但是都挺好看的
    ChakraCore 出来的时候,我已经放弃 JS 了 ...
    secondwtq
        10
    secondwtq  
       2018-04-14 12:07:37 +08:00
    另外楼主做 Server Rendering 直接调 Node 不行么?
    不考虑性能之类的,嵌入引擎和调用外部引擎的最大区别就是嵌入进去方便做 host API 的 binding,如果楼主不需要这个的话,那么楼主不需要折腾这个(我看楼主的 Python binding 的作用,貌似直接 spawn 一个 node process 也能做到)
    cnnblike
        11
    cnnblike  
       2018-04-14 12:09:51 +08:00
    SpiderMonkey 嵌入到 cocos-js 里面有印象
    droiz
        12
    droiz  
    OP
       2018-04-14 12:33:36 +08:00 via iPhone
    @secondwtq 有于公司生产平台限制,这个会比较麻烦,不如做 python binding 方便
    Mutoo
        13
    Mutoo  
       2018-04-14 12:34:00 +08:00
    cocos2d-js 用的就是 SpiderMonkey 也是预编译的,可以支持 PC/Mac/iOS/Android
    droiz
        14
    droiz  
    OP
       2018-04-14 12:34:53 +08:00 via iPhone
    @Mutoo 学习了
    jinsongzhao
        15
    jinsongzhao  
       2018-04-14 15:06:46 +08:00
    好同志啊!有没有测试 Chakra 的多线程并发?我以前玩过用 C++嵌入 lua 和 py,lua 的多线程并发很简单,创建一个 Context 就可以对应一个线程,而 py 是所有线程共享唯一的一个 runtime,调度起来比较烦,不知道现在版本如何了,估计够呛,因为 py 称自己内部实现了线程调度,好牛的样子,估计舍不得放弃这个牛掰的东东。
    faywong8888
        16
    faywong8888  
       2018-04-14 18:27:55 +08:00
    @murmur lua 在游戏扩展、配置方面确实更广泛,但 js 也正在这一领域变得流行,小的 js 引擎也只有几百 kb。
    cholerae
        17
    cholerae  
       2018-04-14 20:01:49 +08:00
    luajit 难道性能也差很多吗
    zhicheng
        18
    zhicheng  
       2018-04-14 20:09:38 +08:00 via iPhone
    如果不限语言的话,欢迎尝试一下 Lemon 语言,小巧便于嵌入,就是性能差些,本人是作者。
    官网 https://lemon-lang.org
    代码 https://github.com/lemon-lang/lemon
    nino
        19
    nino  
       2018-04-14 20:35:40 +08:00
    厉害了
    est
        20
    est  
       2018-04-14 22:18:15 +08:00
    基于 Python 的 React Server Rendering


    what????? 用 nodejs 活着不好么。。
    xieranmaya
        21
    xieranmaya  
       2018-04-15 02:03:09 +08:00
    @est 我读到这句的时候也是这个反应,就算不行,加个 node 中间层也比用 py 跑 js 要强啊
    chemzqm
        22
    chemzqm  
       2018-04-15 02:37:51 +08:00
    以前有个项目是 rails 跑 react 的 server rendering,页面出来最快要 10s,那个酸爽!
    abcbuzhiming
        23
    abcbuzhiming  
       2018-04-15 10:43:58 +08:00
    @est
    “用 nodejs 活着不好么”
    我之前用 nodejs 作为渲染服务器(直接面向前端的 HTML 页面吐出)的时候遇到了以下问题,不知道 nodejs 现在解决了没有
    *.单线程,导致无法有效利用硬件资源
    *.单线程,容易死,死了还无法自动拉起来,只能重启了事,搞的我们还得专门为 nodejs 研发了一套监控程序

    如果这些问题没有得到有效解决的话,nodejs 作为一个 http 服务器是不合格的,我更希望能搞出目前业界流行的 nginx+lua 那样,搞出 nginx+javascript 的后端渲染服务器,至少 nginx 可比 nodejs 在做 http 服务商可靠的多了
    est
        24
    est  
       2018-04-15 10:49:16 +08:00 via Android
    @abcbuzhiming 你说的都有道理,但是 py 并不能很好解决你列出来的这几点问题吧。。。

    只找到 js 引擎是远远不够的,SSR 还得有模拟 DOM 才行吧?
    abcbuzhiming
        25
    abcbuzhiming  
       2018-04-15 10:52:46 +08:00
    @est 是的,你说的对,实际上这是一个业界痛点,我们现在都需要服务器渲染,然而传统的后端 http 服务器没有任何一家能提供 js 引擎和 DOM 树模拟能力。NodeJS 是唯一能提供的但是作为 Http 服务器本身它又很不给力。其实我在想这个问题应该早就有人注意到了,为啥没人出来做这方面的工作,莫非 google 在 V8 引擎的开源协议上设置了什么障碍
    breeswish
        26
    breeswish  
       2018-04-15 11:32:39 +08:00
    @est 如果业务是 py 写的,不想再单独起一个 nodejs renderer server 做个 proxy,而是直接在服务端集成的话,用 py 跑 js 就挺合理的。还可以参见 react 官方的 asp.net server renderer,也是跑了个 js engine
    newlifeinsc
        27
    newlifeinsc  
       2018-04-15 12:55:42 +08:00 via Android
    @abcbuzhiming 单线程和进城可能会挂的问题使用 pm2 之类的进程管理器就 ok,会起多进程解决只用一个 cpu,也会监控进程存活,自动重启之类的。就和 Python 的 supervisor 一样
    tommyZZM
        28
    tommyZZM  
       2018-04-15 13:53:38 +08:00
    @noe132 嵌入 js 引擎来做游戏开发,前不久也在研究这事,😄可以互相交流下。

    楼主可以关注一下这几个项目:
    https://github.com/nodejs/node-chakracore
    https://github.com/janeasystems/nodejs-mobile
    tommyZZM
        29
    tommyZZM  
       2018-04-15 13:58:12 +08:00
    @abcbuzhiming 我觉得对于这个问题,去分析是否哪里的 js 代码原因导致程序挂起原因更加有效,例如进入了一个死循环之类的。现在 node.js 跑正确的代码还是很稳定的。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5187 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 40ms · UTC 01:22 · PVG 09:22 · LAX 18:22 · JFK 21:22
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.