kraken icon indicating copy to clipboard operation
kraken copied to clipboard

使用统一字符串 ID 来优化样式设置链路

Open andycall opened this issue 3 years ago • 5 comments

使用场景 | Use case

现在 kraken 上,给一个 Element 设置 style 的链路如下:

  1. JS 执行 element.style['width'] = '100px'
  2. 将 JSValue 复制一遍转成 NativeString,然后发送到 Dart
  3. Dart 将 NativeString 复制一遍转成 Dart String
  4. Dart 将字符串作为 Key 存储在 inlineStyle 中,Key 会复制一遍存储到 Map 中
  5. 中间还有一些特殊的判断,也都是依据 key 进行比较,每进行一次比较,都会按照字节,逐一进行对比
  6. Dart 将 style 转成 renderStyle 的过程中,也依据字符串作为 key 进行比较,每进行一次比较,都会按照字节,逐一进行对比。

可以看出,一个 'width' 在整个运行的流水线中,至少被复制 & 遍历 >= 5 次。 T(n) >= 5N

setStyle 是 Kraken 中使用频率 Top 1 的 API,我们可以进行以下的优化:

提案 | Proposal

QuickJS 中会对字符串做一个 hash,生成一个 ID (int) 来对应一个字符串。相同的字符串会得到相同的 ID。 如果 Kraken 后面处理 style 的流程都是用这个 ID 的话,设置 style 的链路就可以优化成:

  1. JS 执行 element.style['width'] = '100px'
  2. 直接将 ID 发送到 Dart
  3. Dart 将 ID 存储在 inlineStyle 中,ID 会复制一遍存储到 Map 中
  4. 中间还有一些特殊的判断,也都是依据 key 进行比较,每进行一次比较,都是一次 int 数值的比较
  5. Dart 将 style 转成 renderStyle 的过程中,也依据 ID 进行比较,每进行一次比较,都是一次 int 数值的比较。

可以看出,在整个流程中,字符串的比较仅仅会在第一步,在 Quickjs 内部通过一次对比生成 ID。后续的所有流程都是通过数字进行计算,相比之前,时间被严格控制在一次字符串对比。T(n) = N

字符串 ID 的固化

要想实现以上功能,需要在 Kraken 中内置已经支持的属性,并提前预置在 QuickJS 中,可以通过一个配置文件来分别生成 Dart code 和 C code,这样更加方便维护 Kraken 所支持的 CSS 属性

andycall avatar Jan 07 '22 05:01 andycall

其实样式走 inline 不是最佳实践, 后面实践上还是尽量用外联层叠样式表; 不过这个优化还是有意义的

wssgcg1213 avatar Jan 07 '22 05:01 wssgcg1213

外联层叠样式表和这个不冲突。

andycall avatar Jan 07 '22 06:01 andycall

https://github.com/openkraken/kraken/issues/1110

answershuto avatar Jan 17 '22 07:01 answershuto

其实样式走 inline 不是最佳实践, 后面实践上还是尽量用外联层叠样式表; 不过这个优化还是有意义的

所以最新的版本样式还是只能用inline的对吗? image image

试着引入index.css 或者index.module.css class是有了 但是没样式 image @wssgcg1213

cma290 avatar Sep 16 '22 04:09 cma290

奥 flutter中只加载了js文件 css文件没引进来

cma290 avatar Sep 16 '22 06:09 cma290