硬核万字长文:我是如何把Skia的体积“缩小”到1/8的?
作者|陈国栋
随着移动互联网的一路高歌 , 越来越多的App不满足系统原生的UI体系 。 开启了各种花式的玩法 。 早几年ReactNative、Weex等 , 企图尝试让系统组件可以像浏览器一样动态加载 , 从而提高发版本的效率 。 更早几年还有一众通过在系统Webview基础上面搭建起来的动态化方案 , 包括当下诸多的小程序平台等 。 Flutter的发布仿佛给业界带来一丝新的生机 , 通过Skia渲染器完美的保证了在诸多平台渲染的一致性 。 但也带来专属于Flutter本身的一些问题 。 不过多的讨论关于Flutter本身 , 这里只谈关于Skia和矢量渲染技术中属于我的理解 。
首先要承认我是彻彻底底的标题党 。 目前为止我通过官方的编译选项来对Skia进行编译裁剪 , 二进制体积依旧很大 。 而我的目标就是把CSS和排版还有渲染器整体做到1.5MB以内 , 如果选用合理小巧的JS引擎整体控制在2MB到2.5MB左右 。
所以如何把Skia裁剪到1/8?答案是重写一个(认真严肃)!!!
目前渲染器已经基本完成 , 关键节点的性能测试和Skia处于同一水平(甚至还要好一些) 。 但是体积只有Skia体积(疯狂裁剪后)的1/8 。
大概是多大?580KB(x86-64下构建的产物 , AndroidArmv7a下还要小许多) 。 在这基础上又添加了对复杂文本的排版功能 , 这部分依赖Freetype(解析字体文件的开源库)和Harfbuzz(对字模整形的开源库)还有文本的排版引擎 , 带上这部分功能体积会大一些(目前为止Skia还不具备复杂文本排版能力) 。
本文希望可以通过简单通俗的语言和大家探讨渲染器背后的核心技术 , 如果你也有类似的需求希望能给到足够的启发 。
关于矢量渲染器
矢量渲染器作为现代UI的核心支撑模块 , 常常被作为内嵌在操作系统内的图形子系统的一部分提供给上层开发者 。 比如Windows下的GDI/GDI+/Direct2D , Android下的Skia/HWUI(HWUI对一些复杂多边形的处理依旧依赖Skia的软绘制 , 所以不能算完备的矢量渲染器) , MacosX/iOS内置的CoreGraphics , Linux下的Cario渲染器 。
同样其他的跨平台的库 , 比如QT就自己实现了矢量渲染器 , 这样可以在不同平台下拥有统一的渲染效果 。 Flutter , Chrome和Android采用同样的Skia渲染器来完成跨平台的能力 。
所以要想在不同平台拥有比较好的渲染一致性 , 剥离对系统提供渲染器的依赖是很重要的一步 。
同样行业出现了一些类似于包括NanoVG在内的一些渲染器 , 此类渲染器都采用了模板掩码的一种特殊技法(Opengl红宝书中提到的)来解决复杂多边形的绘制问题 , 巧妙的规避了复杂的几何运算 。
但是天下没有免费的午餐 , 它同样也会带来相对应的性能问题 。 而且天花板很低 , 后续优化几乎无从下手 。 对于游戏这类的场景偶尔需要显示一些面板来说无可厚非 , 但是对于传统的界面程序还是显得捉襟见肘 。
前言
在探讨之前我觉得有必要定义一下“渲染”这个词 。 这个词在目前互联网技术上面有诸多含义 , 带有一定的迷惑性 。 下文所有提及的“渲染”都和计算机图形学中“渲染”拥有同样的含义 , 指的是把特定的像素填充对应的颜色 , 以及围绕这一目的的相关算法 。
鸟瞰渲染器全貌
时至今日Google甚至微软的诸多产品都采用Skia作为核心渲染组件 。 包括但是不限于Android、Chrome、Flutter、Xamarin等等 。 不得不说这是一个伟大的技术产品 。
渲染器本身是一个极其复杂的程序 , 就拿Skia来说核心侧有超过80w行的代码 。 如果算上第三方库甚至达到了惊人的150w到200w行之巨 。
即使构造的这个轻量的渲染器项目也有超过25w行的代码(剔除第三方库 , 比如图片编解码、字体解析、XML加载库等等 。 仍然还有超过13w行的核心代码) 。
- 量子专家的硬核实验1:宇宙共有3个世界,人类可进阶高层次世界
- iqoo|强悍来袭!硬核材质造就高端旗舰质感
- 推特能发长文了 新功能叫Note
- 移动互联网|中科大学霸硬核创业:打破海外垄断,做成中国第一
- 7月23日-25日|倒计时30天 | 超大型硬核户外展7月必赴
- 7月降至|小米发布长文讲述小米摄影光学发展
- 荣耀|价格相差2000元,两台手机表面一模一样,区别在于硬核技术
- 18 个会杀死初创公司的错误,Paul Graham 万字指南
- 深度学习|罗永浩二十二年前写给俞敏洪的万字求职信被曝光!老罗的自信度爆棚
- 雷军|雷军转发UP主硬核改装:小米空气净化器改成了ITX主机 还能联动小爱
