ToB企服应用市场:ToB评测及商务社交产业平台
标题:
CesiumJS 更新日志 1.96 与 1.97 - 新构建工具 esbuild 体验及 Model API
[打印本页]
作者:
温锦文欧普厨电及净水器总代理
时间:
2022-9-16 17:16
标题:
CesiumJS 更新日志 1.96 与 1.97 - 新构建工具 esbuild 体验及 Model API
目录
1.96 更新情况
1.97 更新情况
新构建工具 esbuild 和大换血的构建指令使用
1. 官方自述构建工具更新的原因
2. 选择使用 esbuild
3. 关于 WebWorker 遗留问题
4. 重头戏之旧构建指令移除与新指令用法
5. 收益
6. 之后的改进方向
7. 开发者如何使用新的构建成果
CesiumJS 更新日志 1.96 与 1.97 - 新构建工具 esbuild 体验及 Model API 更替完成
截止发文,1.97 还未发布,但已经在源码仓库完成了 Model API 的替换,文章会跟进。
本文着重介绍新的构建指令的用法(配套 esbuild 的使用)
,见第三节。
首先介绍 1.96 和 1.97 两个大版本的更新内容。
1.96 更新情况
1.96 已于 2022 年 8 月初更新;重大更新如下:
改用 esbuild 完成库程序的构建,并更新了一批 npm script(与之前的很不一样);
Model.boundingSphere 属性现在返回 ECEF(地心地固)坐标系下的坐标值,也就是世界坐标(EPSG:4978)而不是模型原来的局部坐标;
具备 CESIUM_primitive_outline 扩展的 glTF 模型或 Cesium 3DTiles 数据,现在可以通过控制 showOutline 属性来显示外廓线了;将来有可能加入 outlineColor 属性控制颜色;
使用模型 API 新架构(1.97将正式替代旧版 Model API,下文不再重复描述)制作的点云类型 3DTiles 现在支持了样式化;
升级 earcut 库至 2.2.4 版本,提升了 10% 到 15% 的性能;
修复新 Model API 的若干 bug,包括但不限于 draco 点云示例崩溃的问题、cmpt 瓦片数据示例缓存不正常的问题、具有透明度的模型示例不更新的问题、逐要素后处理(per-feature post-processing)不生效的问题、具备量化坐标的 i3dm 瓦片数据不能正确加载的问题等;
1.96 有两项过期 API 消息:
ModelInstanceCollection 模块中 CPU 端的实例化技术(于 1.97 废除);
requestAnimationFrame 和 cancelAnimationFrame 两项兼容性库实现(于 1.99 废除),因为基本上所有的浏览器都实现了这个 API。
1.97 更新情况
1.97 主要更新如下(持续更新中):
把 ModelExperimental 转正,重命名为 Model,位于 Source/Scene/Model/ 目录下,完全替代旧版的 Source/Scene/Model.js 等较为糅杂、耦合的旧模型加载架构;
正式支持 CustomShader API
正式支持
EXT_structural_metadata
,
EXT_mesh_features
和
EXT_instance_features
三项未来 3DTiles 1.1(当前被称作 3DTiles Next,以 1.0 的扩展存在)的特性,极大增强 3DTiles 各分层的数据语义能力;
正式支持
EXT_mesh_gpu_instancing
这项未来 3DTiles 1.1(同上,不赘述)的特性,此特性为 glTF 规范专门设计、扩展,以逐步替代旧版 i3dm 瓦片格式的实例化技术;
正式支持
EXT_meshopt_compression
这项 glTF 的网格优化压缩扩展,与 Draco 相比各有优劣;
支持了跨瓦片文件的纹理贴图缓存技术;
enableModelExperimental 配置移除,所有的 glTF 模型、3DTiles 新旧版本均使用上述新版模型架构
新版的 Model API 在公共 API 的文档和调用几乎没有差距,做到了对上层应用的无缝兼容(待这两个版本测试),因此开发者几乎不需要更改原来的 API 调用代码。
此外,还有几个极为重大的改变:
glTF 1.0 版本的支持已移除
,请尽快转换你的数据到 glTF 2.0 版本;
glTF 的一项扩展 KHR_techniques_webgl 已移除
,如果你有自定义着色需求,请使用 CustomShader API
ModelInstanceCollection 这个私有类使用的 CPU 端实例化技术已移除;
ModelMesh 和 ModelMaterial 两个私有类已移除;
单一模型的分类分级着色已支持,使用 classificationType 参数配置 Model 类即可,详见帮助文档
总结下来就是下一代的 3DTiles 越来越近了。
新构建工具 esbuild 和大换血的构建指令使用
本段大部分材料参考自官方博客:
Build Tooling Updates Coming to CesiumJS – Cesium
1. 官方自述构建工具更新的原因
近几个月,官方团队致力于改进开发者体验,最近已经把成果合并到主分支,那就是使用新的代码构建工具。在 CesiumJS 的源代码开发时,已经能获得更小体积的发行版 CesiumJS 库文件(未压缩版本体积小了 33%,压缩版小了 16%),而且速度有质的飞跃。发行版变小,使得网络加载时间变短,速度更快。
由于精简了代码资源、移除无关的空格和注释,得到了更小的构建版本的库文件,这也有利于提高浏览器加载速度
这样做还有额外的好处,就是解决了一个在
Linux 系统中 Chrome 浏览器长期存在的问题
2. 选择使用 esbuild
CesiumJS 项目启动之初,它所用的辅助开发工具基本上都是同类项目中的“新鲜玩意儿”,比如,RequireJS 就是当时最突出的依赖管理工具,1.62 版本之前的模块机制都是异步模块定义(AMD)。后来自 1.63 版本完全为 ESModule 后,就改用 Rollup 来构建了。
到目前为止,CesiumJS 在构建时是存在没有轻量化、最小化等毛病的。CesiumJS 最重要的环节,即把所有源代码模块合并到一个主文件(以方便分发),官方并没有在这个过程中对代码进行重大转换,因为需要考虑到兼容性问题。
由 ESModule 多个模块文件合并到单一文件,这个单一文件我一般叫它库文件
现在的 JavaScript 工具已经越来越快、越来越好用了,开发者们更习惯走打包的路线,所以是时候评估构建工具的更新了。
官方选择使用 esbuild 来代替 Rollup 来完成 “ESModule -> 库文件” 这个最重要的环节。
首先,esbuild 足够快(译者注,参考 vite,速度有目共睹),这能满足快速开发的要求;
其次,Rollup 虽然有很多插件,但是相比较之下这些插件很多 esbuild 都是开箱支持的,例如从 node_modules 中自动打包第三方库、代码转换、代码压缩等;
最后,esbuild 还能进一步减小构建出来的主库程序文件的大小(无论压缩版还是未压缩版本),更有利于浏览器加载提速。
3. 关于 WebWorker 遗留问题
WebWorker 是浏览器后台运行的独立脚本,在 CesiumJS 中,它们广泛用于创建几何图形和数据解码任务。
Firefox 仍未在 worker 中支持 ESModule,这意味着必须使用 iife 或者 amd 模块化机制来加载 worker 文件;但 esbuild 只支持 ESModule 的代码分割,如果不进行代码分割,worker 文件大小就会显著增大。
为了避免这个问题,只能暂时继续用 Rollup 和 RequireJS 来解决 worker 的问题。直到 Firefox 支持之后,才能完全切换到 esbuild 来。
4. 重头戏之旧构建指令移除与新指令用法
除了用上 esbuild 之外,官方还借此机会从全局重新考虑了构建过程,包括构建脚本负责的任务的粒度问题。
最大的变化是开发时的构建方法,由于 esbuild 的加速(尤其是快速增量构建),现在已经不需要提前构建(即旧版的 combine 指令)才能进行本地开发了(npm run build)。现在,源代码的开发调试只需要安装依赖,就可以直接启动服务器:
npm run install && npm run start
复制代码
CesiumJS 多年的积累,相关工具增加、配置的增加,导致 gulp 中添加了很多指令,他们命名似乎有点乱。现在官方重新评估了这些指令,重新设计如下(主要):
移除 combine、combineRelease、minify、minifyRelease、build-specs、convertToModules 指令;
重命名 startPublic 为 start-public,功能不变;
保留 build 指令,但与之前意义不同,下文细说;
保留 release 指令,但与之前意义不同,下文细说;
重命名 generateDocumentation 指令为 build-docs,下文细说;
重命名 makeZipFile 指令为 make-zip 指令,功能不变;
重命名 buildApps 指令为 build-apps 指令,需要构建版本的示例应用(而不是使用源代码的版本)可调用此指令;
保留 build-ts 指令,但与之前意义不同,下文细说;
移除的指令不再赘述,请读者自行查阅互联网上的资料。下面着重介绍 build、build-ts、build-docs、release 四个最重要的新增/变化指令。
我使用了两台电脑对比运行时间,一台标记为 A,使用桌面 i7 12700 CPU;一台标记为 B,使用 AMD r7 4800U。
指令AB做了什么build约 5s约 9s转译 glsl 文件为 ESModule,导出着色器代码字符串常量;创建出 Source/Cesium.js ESModule 格式的入口文件,并生成 Build/CesiumUnminified 版本的三类库文件和 source-map 映射文件;处理测试文件等build-docs约 19s约 40s调用 generateDocumentation 任务生成离线文档页面build-ts约 14s约 24s根据 jsdoc 注释创建 TypeScript 类型定义文件release约 46s约 85s先执行生成 Build/CesiumUnminified 版本和生成 Build/Cesium 版本库文件的 build 任务;然后调用 build-ts 任务生成类型文件;最后调用 generateDocumentation 任务生成离线文档页面其中,build 指令内部会调用 esbuild 来完成 ESModule、iife、commonjs 三种格式的库文件的打包。表格不够详细的,见下文:
build:做了 4 件事,①转换 Source/Shaders 下所有 .glsl 格式的文件成 ESModule 文件,导出着色器代码字符串常量;②生成 Source/Cesium.js 这个 ESModule 出口文件,导出所有 CesiumJS 的模块、常量、类等,无论公开或私有;③生成 Build/CesiumUnminified 文件夹,并调用 gulp 配置文件中的 build 任务,生成 ESModule、iife、commonjs 三种格式的单文件 CesiumJS 库,含 source-map 映射文件;④复制 Source/ 目录下的四个静态文件夹到 Build/CesiumUnminified 下;这个指令有 esbuild 的参与,也有 rollup 的参与(解决 Firefox 仍旧无法在 worker 中使用 ESModule 的问题)
build-ts:调用 jsdoc,把源码中的 jsdoc 注释生成 Source/Cesium.d.ts
build-docs:调用 jsdoc,生成离线帮助文档页面,以便开发者页面或部署的 API 帮助文档能够使用;
release:这是个复合指令,会顺序执行 ①调用 gulp 配置文件(gulpfile.cjs)中的 build 任务,build 指令实际上用的就是 build 任务(一个 JavaScript 函数,被 gulp 称作任务),生成无 TypeScript 类型定义文件和源代码映射文件的 Build/Cesium 和 Build/CesiumUnminified 两个版本的库程序,前者会压缩,后者与 build 指令实际差不多;②调用 build-ts 指令;③调用 gulp 配置文件内的 generateDocumentation 任务,实际上也就是 build-docs,生成离线帮助文档
注意,build-apps 依赖于 build,有先后顺序
有两个小技巧,
根据 npm 指令的规则,想为某个指令的内部调用继续传递参数的,需要接两个横线,例如生成离线文档时想生成私有模块的文档,则使用 npm run build-docs -- --private,那么 --private 就会传递给 build-docs 内部实际调用的 jsdoc
想查看开发者示例程序必须再次调用 build 指令,release 指令一旦执行会清掉开发者示例程序,也就是 Sandcastle 中的 Development 分页的示例
5. 收益
就官方的说辞和笔者自己的体验来看,build 指令比起之前的速度,简直就是做了火箭,原本同一台电脑进行 minifyRelease 可能要 4 分多钟,现在 release 只需 1 分半左右。
而且最显著的,无论是压缩版(Build/Cesium)还是未压缩版(Build/CesiumUnminified)的三种格式的库程序,其库文件大小均比原来小不少,加上 gzip 的加持还能更小(请读者自测),基本上全库加载能做到从黑场景到出地球只需 2 秒左右。
压缩版,4.3MB → 3.3MB(基于 1.97,GZIP 后 900+ KB)
未压缩版,12.5MB → 8.0MB(基于 1.97)
CDN 上的 Cesium.js 主文件传输体积,基于 HTTP2 甚至能做到 700+ KB,显著提升场景加载速度。
6. 之后的改进方向
可能之后有考虑转向 TypeScript;一旦 Firefox 的 worker 可以加载 ESM,那么理想状态下可以完全移除 RequireJS 和 Rollup,进一步加速构建速度和减小发布版本的库代码。
7. 开发者如何使用新的构建成果
我没有直接翻译官方的表述,这里我给一个更符合思考逻辑的建议:
如果你打算在你的工程中用打包器加载 CesiumJS 源代码模块,那么你直接使用 import {} from 'cesium' 即可,这种用法将会增加你的工程打包时间,但是可以利用 ESModule 的 Tree-Shaking 特性减小构建产物的大小;
如果你打算使用官方构建出来的 ESModule 单库文件,请使用 Build/Cesium/index.js 或 Build/CesiumUnminified/index.js,看你需要压缩或未压缩的版本;
如果你在 CommonJS 模块中使用 CesiumJS,那么继续使用 const cesium = require('cesium') 即可导入,默认会指向 Build/Cesium/index.cjs或Build/CesiumUnminified/index.cjs;
如果你打算使用官方构建出来的 iife 风格的单库文件,请继续使用 Build/Cesium/Cesium.js 或 Build/CesiumUnminified/Cesium.js
以后有兴趣可以写文讲讲如何最优地在你的项目中引入 CesiumJS,我认为 CDN 引入是一个不错的加速手段,尽量避免让应用打包器再次打包 CesiumJS,Tree-Shaking 对于这种级别的 3D 地球库来说可能收益甚微。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/)
Powered by Discuz! X3.4