最近研究了一下 Javascript 引擎嵌入问题,一点点经验分享给大家 - V2EX
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 2631 次点击
    这是一个创建于 2816 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近由于要做基于 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。
    6ufq0VLZn0DDkL80
        17
    6ufq0VLZn0DDkL80  
       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     Solana     3274 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 62ms UTC 04:58 PVG 12:58 LAX 20:58 JFK 23:58
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86