如何扩充浏览器的能力

常见的 JavaScript 接口暴露方式

Lu Yuan

2016-08-12

About

  • 陆远 (weixin: luyuandotorg)
  • 百度多模交互搜索部 (MMS)
  • web 前端开发工程师

内容

  • 为什么
  • 哪些方法
  • 如何实现

为什么要扩充浏览器的功能

  • 实现新规范
  • 使用中浏览器内核无法提供的能力
  • 自定义扩展机制
  • 第三方浏览器或 webview
  • 集成其他宿主环境
  • ...

浏览器中供 JavaScript 使用的原生功能的来源

  • 脚本引擎 (ECMA, extension)
  • 渲染引擎 (DOM, BOM, CSSOM, HTML5...) 
  • 扩展 (浏览器扩展机制, devtools) 
  • 引入的其他宿主环境 (Node...) 

从脚本引起进行扩展

增加纯 JavaScript 及原生接口

v8::Extension(kLoadTimesExtensionName,
      "var chrome;"
      "if (!chrome)"
      "  chrome = {};"
      "chrome.loadTimes = function() {"
      "  native function GetLoadTimes();"
      "  return GetLoadTimes();"
      "};"
      "chrome.csi = function() {"
      "  native function GetCSI();"
      "  return GetCSI();"
      "}") {}

对渲染引擎功能的扩充

增加一个 timing 属性

  • IDL
    • readonly attribute unsigned long long firstLayout;
  • Implementation
    •  
ScriptValue PerformanceTiming::toJSONForBinding
        (ScriptState* scriptState) const
{
    ...
    result.addNumber("firstLayout", firstLayout());
    return result.scriptValue();
}

扩展开发者工具

集成 Node

  • Chromium + Node
    • nw.js -> node-webkit
    • heX
    • atom-shell -> Electron

Node 的构成

  • node
    • V8
    • libuv
    • openssl
    • ...

Node 的启动过程

加入 Node 的同步逻辑

  • DidCreateScriptContext
    • init
    • process
    • start node.js
  • WillReleaseScriptContext
    • dispose
    • exit

整合 Node 的异步

  • heX
    • browser message loop (浏览器进程) 中通知 (IPC) uv_run_once (渲染进程)
  • Electron

比较

脚本引擎 渲染引擎 扩展 其他宿主
Pros 开发成本低
结构简单
可访问内核资源多
IDL 规范
接口标准
可访问内核资源多
开发成本低
可访问内核资源多
功能强大
扩展性
学习成本低
Cons 接口类型简单 build 时间长
直接修改内核
直接修改内核 开发、维护成本高
结构复杂

谢谢

How to Enhance Your Browser

By luyuan

How to Enhance Your Browser

如何扩充浏览器的能力——常见的 JavaScript 接口暴露方式 How to Enhance Your Browser

  • 1,557