最近更新时间:2023.11.16 15:18:29
首次发布时间:2023.09.20 16:23:44
Hybrid 同层渲染能力处于 Beta 内测阶段,如有需求请 提交工单 联系技术支持申请试用并获取帮助信息。
Hybrid 同层渲染(Hybrid Same-Layer Rendering)是指在图形渲染中将基于 CPU 的软件渲染及基于 GPU 的硬件渲染结合在一起,以实现更高效的渲染和呈现效果。请参考以下内容先接入双端 SDK 后开启端上 hybrid 指定加载页面地址,再接入 WEB 端并指定具体加载图片的处理配置。
适用于客户端 App 中 Hybrid 页面(以 Hybrid 技术开发的页面)加载图片。
支持 HEIF、WEBP 等高级格式的图片加载及显示,可节省图片传输流量和加载耗时,提升用户体验。
支持监控各种场景下图片元素的加载情况,通过上报图片加载数据,助力您分析图片加载耗时、成功率、分辨率等数据。
平台 | 版本限制 |
---|---|
Android 端 | 系统版本:Android 8 及以上版本 |
iOS 端 |
|
Web 端 | 系统版本:React 16 及以上版本 |
您可在根据实际情况开启 Android 或 iOS 同层渲染后,使用 Web 端加载能力。
登录 veImageX 控制台。
单击左侧导航栏 SDK管理 > 应用管理,进入应用管理页面。
选择一个 App 类应用,单击卡片进入应用详情页面。
开启 Android Hybrid-HEIF TTwebview 插件 的开关。
说明
确保 project 根目录下的 build.gradle 下配置服务,代码示例如下所示:
maven { url 'https://artifact.bytedance.com/repository/Volcengine/' }
请在 module 目录下的 build.gradle 文件中的 dependencies 中添加 Hybrid 加载 SDK 依赖,X.X.X 为技术支持提供的具体版本号。代码示例如下所示:
implementation "com.bytedance.fresco:pia-image:X.X.X" // 用于加载和显示 Pia 格式的图像 implementation "com.bytedance.fresco:ttweb-wrapper:X.X.X" // 用于在应用程序中加载和展示 TTWebView implementation "com.bytedance.fresco:fresco:X.X.X" // Fresco 图片加载库,提供了基本的图像加载和显示功能 implementation "com.bytedance.fresco:fresco-api:X.X.X" // Fresco API implementation "com.bytedance.fresco:animated-gif:X.X.X" // 用于支持加载和显示 GIF 格式的动态图像 implementation "com.bytedance.fresco:animated-webp:X.X.X" // 用于支持加载和显示 WebP 格式动态图像 implementation "com.bytedance.fresco:webpsupport:X.X.X" // 提供对低版本 webp 的支持 implementation "com.bytedance.fresco:drawee:X.X.X" // fresco 组件,用于显示和管理图像的视图组件 implementation "com.bytedance.fresco:heif:X.X.X" // 用于解码和显示 HEIF 格式的静态图像 implementation "com.bytedance.fresco:animated-heif:X.X.X" // 用于解码和显示HEIF格式的动画图像 implementation "com.bytedance.fresco:authorization:X.X.X" // 授权
请参考以下内容完成 SDK 的初始化。
public class BDFrescoApplication extends Application { @Override public void onCreate() { super.onCreate(); // TTWebView Render进程和GPU进程不走端上初始化流程 // 使用步骤 2:TTWebView 子进程初始化 if (TTWebSdk.needInitIndependent(this)) { initALog(this); TTWebWrapper.initTTWebViewProcess(this); return; } // 日志打印 FLog.setMinimumLoggingLevel(FLog.VERBOSE); Logger.INSTANCE.setEnableDefaultLog(true); initDataReport(this); // 使用步骤 3:主进程初始化 initALog(this); // HostAbi 需要与 abiFilters 的值相对应: // abiFilters 是 "armeabi-v7a",则传 "32" // abiFilters 是 "arm64-v8a",则传 "64" CloudControl.setHostAbi(BuildConfig.HOSTABI); TTWebWrapper.initAppProcess(this); // 初始化 applog 和 fresco,参考帮助文档:https://www.volcengine.com/docs/508/176049#%E5%88%9D%E5%A7%8B%E5%8C%96 initAppLog(); initFresco(); initMonitor(); // 使用步骤 4:其他必要调用,可放入子线程,优化启动时间 new Thread(() -> { // 同层渲染埋点 TTWebWrapper.initEmbedLog(); // 配置 settings TTWebWrapper.setTTWebSettings(); // 同层渲染初始化 TTWebMixRender.INSTANCE.initialize(); }).start(); } @Override public Context getApplicationContext() { // 使用步骤 1:返回 Context return this; } private void initALog(final Context context) { TTWebDataCenter.registerLogexCallback(context, new LogExCallback() { @Override public void onLogExe(String tag, String msg) { Log.e(TAG, tag + " " + msg); } @Override public void onLogExi(String tag, String msg) { Log.i(TAG, tag + " " + msg); } @Override public void onLogExd(String tag, String msg) { Log.d(TAG, tag + " " + msg); } }); } private void initDataReport(Context context) { TTWebDataCenter.registerEventListener(context, new EventListener() { @Override public void onCommonEvent(int eventCode, JSONObject jsonValue, JSONObject exjs) { Log.i(TAG, "onCommonEvent " + eventCode + " " + jsonValue.toString()); switch (eventCode) { case 443: // 加载结果 Log.i(TAG, "loadso_result:" + jsonValue.optString("sdk_loadso_result")); break; case 201: // 开始下载 Log.i(TAG, "start download"); break; case 299: // 下载完成 Log.i(TAG, "finish download"); break; case 399: //解压完成 Log.i("[onCommonEvent]", "finish decompress"); break; } } @Override public void onCrucialEvent(int eventCode, JSONObject jsonValue, JSONObject exjs) { Log.i(TAG, "onCrucialEvent " + eventCode + " " + jsonValue.toString()); switch (eventCode) { case 1100: // 加载内核版本号 Log.i(TAG, "loadso: " + jsonValue.optString("LoadSo")); break; } } }); } }
使用 WebView 加载网页的应用程序,代码示例如下所示:
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main_activity); WebView webView = findViewById(R.id.main_webview); // 使用步骤 5:允许同层渲染 2.0,添加自定义组件。 TTWebMixRender.INSTANCE.enableForWebView(webView, Collections.singletonList(TTWebMixRender.EmbedRuntimeType)); TTWebMixRender.INSTANCE.addComponent(BDImageView.class); webView.setWebViewClient(new WebViewClient()); WebSettings webSettings = webView.getSettings(); webSettings.setJavaScriptEnabled(true); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { WebView.setWebContentsDebuggingEnabled(true); } // 使用步骤 6:调用 loadUrl 方法加载指定的网址到 WebView 中 webView.loadUrl("您自己的应用程序地址"); } }
参考 BDImageView、BDImageViewFactory 代码自定义插件。
同层渲染并在一个 Web 页面滑动时,即使图片不可见,SimpleDraweeView 也不会自动释放,此时内存会累加。同一个页面中存在大量图片时,您可以在图片处于不可见位置时,从 Web 端将图片节点直接删除。
请确保已完成 Android/iOS SDK 接入后,再按照以下步骤接入 Web 同层渲染。
运行该命令后,npm 将会下载 @volcengine/imagex-hybrid-react
包及其所有的依赖项,并将其记录在 package.json
文件中的 dependencies
字段中,以便在项目中使用该包。
npm install @volcengine/imagex-hybrid-react -S
引入了 Viewer
组件后并在代码中使用 <Viewer>
标签来创建 Viewer
组件,并传递相应的参数。
import { Viewer } from "@volcengine/imagex-hybrid-react"; //具体参数说明请见功能接入 <Viewer width={680} height={376} formats={["heic", "avif", "webp"]} loader={({ src, format }) => `//www.example.com/${src}~tplv-serviceid-image.${format}`} src='xxx' />
具体支持的参数如下所示:
属性名 | 类型 | 是否必填 | 说明 |
---|---|---|---|
src | string | 是 | 图片路径,可访问的图片 URL。 |
width | number | string | 是 | 图片渲染宽度,值类型和 css width 一致 |
height | number | string | 是 | 图片渲染高度,值类型和 css height 一致 |
objectFit | "none" | "contain" | "cover" | "fill" | 否 | 用于指定图片元素如何适应容器,与 css 属性 object-fit 相同。其中容器范围由上述 width、height 定义。 |
cornorRadius | string | 否 | 圆角半径,支持以下两种类型:
|
formats | string[] | 否 | 自适应格式列表,结合 loader 方法实现格式自适应,在同层渲染场景下优先采用 heic 格式,不支持同层渲染时走格式自适应的方式。默认值为 ['heic', 'avif', 'webp']。取值如下所示:
说明 指定 |
loader | (props: ImageLoaderProps) => string | 是 | 图片 URL 生成函数。函数入参包含 domain, src, format 等参数,返回拼接处理参数后的 url。格式自适应依赖该函数实现。
|
ssrConfig | ISSRConfig | 否 | SSR (服务端渲染)配置,该配置用于在 SSR 配置场景提升图片加载速度。参与了服务端渲染的图片需要配置该属性,使用方式详见 SSR 配置说明。具体配置参数如下所示:
|
loader 入参类型如下所示:
type IImageLoaderProps = { src: string; // 图片访问 path 部分,不包含域名,如:imagex-common/59***************** format: string; // 图片格式 extra: { domain?: string; // 从图片访问 url 解析出的域名 protocol?: 'http:' | 'https:'; // 从图片访问 url 解析出的协议 template?: string; // 从图片访问 url 解析出的 veImageX 模板 suffix?: string; // 从图片访问 url 解析出的格式后缀 search?: string; // 从图片访问 url 解析出的query部分 origin: string; // 图片访问 url }; }; type ISSRConfig = { isSSR?: boolean; //是否在服务器进行渲染 hybridRender?: boolean; //是否使用混合渲染 platform?: 'Android' | 'iOS'; //当前所处的渲染平台 };
说明
在 CSR(客户端渲染)的场景中,您无需关注此配置。
以下仅适用于服务端渲染场景。在完成以下配置后,本组件将自动在服务端提前生成图片占位标识。获取并应用这些占位标识到客户端后,可以帮助尽可能提前图片渲染的时间,减少图片加载的延迟,从而提升图片加载速度。具体流程如下所示:
在服务端完成页面渲染之后(例如在执行 renderToString 后),请调用 Web SDK 提供的 exportInitScript
方法生成触发同层渲染逻辑的 JS 字符串。
将生成的 JS 字符串以 <script> 标签的形式插入到 HTML 模板中。
代码示例如下所示。
// 以下 demo 描述了 SSR 场景下的使用流程,请您根据业务实际情况进行配置 import { exportInitScript } from '@volcengine/imagex-hybrid-react'; app.get('/', (req, res) => { // 1. 业务组件渲染成初始 HTML let domContent = renderToString(<Home />); // 2. 导出用于初始化的 script 字符串 const script = exportInitScript(); // 3. 拼接生成完整的 HTML 结构 let html = ` <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" /> <title>react-ssr</title> <script>${script}</script> </head> <body> <div id="root">${domContent}</div> <script src="/client.js"></script> </body> </html> `; // 4. 响应客户端请求 res.send(html); });