001 Debug
Dart的JIT(即时编译)模式动态编译,可以在真机和模拟器上同时运行。可以打断点 看到输出日志,可以ho tload
只为快速开发和运行做了优化,没有优化代码执行速度,二进制包大小和部署。
002 Release
Dart的AOT(提前编译)模式,静态编译,只能在真机上运行,不能在模拟器上运行,其最终目标是线上发布,给最终客户使用,会关闭所有断点,调试信息,服务扩展和调试辅助,
优化了应用快启动,代码快速执行,以及二进制包大小,编译时间较长。
003 Profile
和release模式基本一致,只是多了对Profile模式服务扩展和支持,支持跟踪以及一些最低限度支持所依赖,
该模式用于分析真实设备实际运行性能。
004 HotLoad
热重载,只能在在debug模式下使用,在debug模式下,flutter采用的是JIT动态编译,JIT编译器将Dart代码编译成在DartVM上的DartKernel,而DartKernel是可以动态更新的,这就实现了代码实时更新的功能。
1.工程改动。热加载模块会逐一扫描工程中的文件,检查是否有新增,删除,改动,直接找到上次编译后之后,发生变化的代码。
2.增量编译,热重载模块会将发生变化的Dart代码,通过编译转化为增量Dart Kernel 文件。
3.推送更新,热重载模块将增量的Dart kernel 文件通过Http端口,发送到正在移动设备上运行的dartVM
4.代码合并。Dart VM会将收到的增量Dartkernel文件,与原有的Dart kernel文件进行合并,然后重加载新的Dartkneel文件。
5.widget重建。在确认DartVM资源加载成功后,flutter会将其UI线程重置,通知flutter Framework重建widget。
这样做不会让app重新启动,只是触发widget树的重新绘制,因此可以保持改动前的状态,这就大大节约了调试复杂页面的时间。
不支持热重载的场景:
1.代码出现编译错误
2.widget状态无法兼容 应用程序保留的状态与新的更改不兼容。
3.全局变量和静止属性的更改 程序第一次运行的时候,会将它们的值设置为初始化的执行和结果
4.main方法里的修改 因为热重载只会根据原来的根节点重新创建树。
5.initState方法里的修改 initState是widget状态的初始化,这里的方法更改会与状态保存发生冲突
6.枚举和泛型更改 枚举和范型视为状态会导致热重载失败。
RN热重载原理:React Native 采用脚本语言编写,脚本语言即读即运行,不需要编译,在读之前替换成新版本的脚本,运行时执行的便是新的逻辑;RN打包时会将RN源代码、第三方库及自己编写的js代码都打包成一个bundle文件(Android是index.android.bundle,ios是index.ios.bundle),App启动时会加载bundle文件,所以替换掉这个bundle文件就能实现热重载了,RN中提供了修改读取bundle路径的方法,可以将最新的bundle更新到读取bundle的指定路径进而实现热重载。
Webpack的热重载原理:初始化注入一段js脚本,里面与webpack开发服务器建立一个WebSocket连接,当文件有改动的时间,通过WebSocket将文件下发,随后浏览器重新执行新的代码。状态管理则是在内存中,依赖Redux之类的库,所以UI和状态是分离的,可以比较容易的实现热重载。