flutter WEB端启动优化(加载速度,加载动画)
Flutter WEB端的开发者可能都面临过一个共同的问题:由于需要加载大量的配置文件,启动速度相对较慢。
以下是针对这一问题的一些优化策略,旨在帮助开发者提升应用的加载速度。
一. 压缩加载资源
加载自定义字体和图片等资源往往会影响启动速度。以下是一些压缩资源的方法:
-
压缩图片资源:适当减小图片文件的大小。
-
优化字体资源:提取字体中的常用文字,创建一个小型的字体包,并在加载完成后异步加载完整字体包进行替换。
- 步骤1:创建一个包含常用文字的
data.json
文件。
- 步骤2:使用Python的
fontTools
库,根据data.json
生成压缩后的字体文件。
#!/usr/bin/python
# coding=UTF-8
import json
from fontTools import subset
# source_font: 全量TTF字体源文件
# json_file: 字段的json文件
# out_file: 导出的字体文件
def generate(source_font, json_file, out_file):
all_chars = []
checker = {}
with open(json_file, 'r', encoding='utf-8') as f:
text_data = json.load(f)
elements = text_data['elements']
for element in elements:
value = element['text']
for char in value:
uid = ord(char)
if uid not in checker:
checker[uid] = True
all_chars.append(char)
# 所有文本
text = ''.join(all_chars)
# TTF源文
# font = TTFont(source_font) NOTE: 这一版在源文件不变的情况下 生成的字体包md5会发生变化 改成下边这种方式
font = subset.load_font(source_font, subset.Options())
# 挑出需要的字符
subsetter = subset.Subsetter()
subsetter.populate(text=text)
subsetter.subset(font)
# 生成输出文件
subset.save_font(font, out_file, subset.Options())
font.close()
if __name__ == '__main__':
source_font = "./alipuhui-3-55.ttf"
json_file = "./data.json"
out_file = "picked.ttf"
generate(source_font, json_file, out_file)
- 步骤3:在
pubspec.yml
中添加字体文件,并在代码中初始化时使用压缩字体,待完整字体加载完成后替换。
String customFont = '阿里普惠shrink';
loadFont() async {
var bundle = await rootBundle.load('assets/fonts/alipuhui-3-55.ttf');
// final response = await Dio().get(
// "https://cdn.jsdelivr.net/gh/IlysvlVEizbr/via-font@0.3/AliPuHui.woff2");
var loader = FontLoader('阿里普惠')..addFont(Future.value(bundle));
await loader.load();
customFont = '阿里普惠';
if (mounted) setState(() {});
}
二. 网络字体(google字体)使用国内cdn
如果网络资源使用的是外网地址或国外CDN,加载速度可能会受到影响。建议使用国内CDN或移除这些资源。
三. 声明延迟导入
将代码拆分,仅在需要时加载相应的代码块,可以有效减少初始加载时间。
参考文章 Best practices for optimizing Flutter web loading speed
四. 优化首屏加载动画
在index.html
中添加加载动画,并在首屏加载完成后移除。
<!DOCTYPE html>
<html>
<head>
省略...
</head>
<body>
省略..
<!-- Loading indicator -->
<style>
.container{
width: 100vw;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
flex: auto;
flex-direction: column;
}
.indicator{
width: 100px;
height: 100px;
margin-bottom: 15px;
}
.progress-bar {
width: 100px;
background-color: #f3f3f3;
border-radius: 4px;
}
@keyframes progress {
0% {
width: 50%;
}
100% {
width: 100%;
}
}
.progress-bar-fill {
display: block;
height: 5px;
background-color: #46494b;
border-radius: 4px;
transition: width 0.2s ease-in;
animation: progress 5s ease-in-out forwards;
}
</style>
<div id="loading_indicator" class="container">
<img class="indicator" src="icons/icon-192.png"/>
<div class="progress-bar">
<div class="progress-bar-fill" style="width: 50%;"></div>
</div>
</div>
<script>
window.addEventListener('load', function(ev) {
var loading = document.getElementById('loading_indicator');
_flutter.loader.loadEntrypoint({
serviceWorker: {
serviceWorkerVersion: serviceWorkerVersion,
},
onEntrypointLoaded: async function(engineInitializer) {
let appRunner = await engineInitializer.initializeEngine();
await appRunner.runApp();
window.setTimeout(function () {
loading.remove();
}, 200);
}
});
});
</script>
<!-- App -->
</body>
</html>
五. 使用Wasm渲染
从Flutter 3.22版本开始,Wasm渲染方式得到了支持。与CanvasKit相比,Wasm不仅减小了应用程序的大小,而且启动速度更快。不过,目前Wasm还处于实验阶段,建议在稳定支持后再进行使用。
希望以上优化策略能够帮助你开发出既完善又快速响应的WEB应用。
关注【元助手AI】,获取更多教程