The Picture failed to display, please check it again, thank.
Though some users/contributors/committers are Chinese(including me), English is 
recommended for email communication as it will make most of the subscribers 
understanding what is happening in Weex Community.

> 在 2019年1月22日,20:28,龙泉 <[email protected]> 写道:
> 
> the design can refer to below:
> 
> ### 预渲染
> 
> 
> #### 调用方式
> 
> 
> 1. 在需要预渲染的地方调用下面方法:
> > WXPrerenderManager.getInstance().preRenderByXXX()
> 
> 注意:
> > *  
> > 预渲染接口参数与WXSDKIntance.renderByUrl()或者renderByTemplete()基本一致,分别对应了从网络加载和从本地加载。
> > *  
> > 预渲染时必须传入页面的宽高值,预渲染时不会生成真正的view,renderContainer也不会存在,但是页面在预渲染时可能会需要依赖页面的宽高用于布局,所以预渲染时必须指定宽高值。
> > *  
> > 预渲染本地的templete时,也需要传入一个url值,但是此时只需要保证url是唯一的任意值即可。预渲染会使用url作为key存储预渲染的instance,因此即使是templete也需要构造出url。
> > *  此时仅需要传入application context即可
> 
> 2. 当页面真正打开是,调用下面方法获取WXSDKInstance:
> > WXPrerenderManager.getInstance().fetchPreload(String url)
> 
> 注意:
> > * 获取的instance可能为空,此时需要走正常的逻辑初始化WXSDKInstance
> 
> 3. 调用获取到的instance的realRender()方法,将activity的context传入,创建component和View。
> 
> 注意:
> > * 当该方法返回false时,表示预渲染失败,需要重新走原有的render方法。
> 
> 使用样例:
> 
> ```java
>     // 合适时机先预渲染页面
> 
>     // 预渲染的页面宽占满全屏,高需要减去状态栏的高度和标题栏高度
>     int realWidth = 
> (int)DeviceInfoUtil.getWidth(BaseApplication.getApplicationContext());
>     int realHeight = (int) 
> (DeviceInfoUtil.getHeight(BaseApplication.getApplicationContext()) - 
> TitleBar.getStatusBarHeight() - TitleBar.getTitleBarHeight());
> 
>     // 页面加载时需要带入的额外信息
>     HashMap<String, Object> loadExturas = new HashMap<>();
>     loadExturas.put(WXSDKInstance.BUNDLE_URL, url);
>     loadExturas.put("userAgent", userAgent);
>     loadExturas.put("cookie", cookie);
>     loadExturas.put("viewSize", String.format("{\"width\":%d,\"height\":%d}", 
> realWidth, realHeight));
>     WXPrerenderManager.getInstance().preRenderByUrl(
>             BaseApplication.getApplicationContext(),
>             "Weex_Preload",
>             url,
>             loadExturas,
>             null,
>             realWidth,
>             realHeight,
>             WXRenderStrategy.APPEND_ONCE);
> 
> 
>     // 页面打开时加载instance
>     bool hasPrerenderPage = false;
>     if (!TextUtils.isEmpty(webUrl)) {
>         mWXSDKInstance = 
> WXPrerenderManager.getInstance().fetchPreload(webUrl);
>         if (mWXSDKInstance != null) {
>             mHasPrerenderPage = true;
>         }
>     }
>     if (!hasPrerenderPage) {
>         mWXSDKInstance = new WXSDKInstance(context);
>     }
> 
>     if (hasPrerenderPage) {
>         boolean result = mWXSDKInstance.realRender(context);
>         // 预渲染出错的情况下,需要走普通渲染逻辑
>         if (!result) {
>             mWXSDKInstance = new WXSDKInstance(context);
>             // 正常的渲染页面逻辑
>             renderWithOutPreload(url);
>         }
>     } else {
>         renderWithOutPreload(url);
>     }
> ```
> 
> #### 预渲染原理
> 
> 预渲染主要解决的问题是weex页面render耗时长的问题,这里定义从WXSDKInstance的render方法开始到onRenderSuccess执行中间的时间为渲染的耗时。
> 
> 有了耗时的定义再来看看weex正常的render过程:
> > render -> http请求JsBundle -> weexcore createInstance -> jsCore执行jsBundle -> 
> > 创建虚拟dom action -> weex frameWork执行dom action -> 创建component、view、更新layout等 
> > -> android系统渲染view
> 
> 通过trace,发现刨除网络耗时,weex页面打开的性能热点主要在下面2个阶段:
> 
> 1. jsCore执行jsBundle的耗时
> 2. 创建虚拟dom action以及执行dom action的耗时
> 
> 而这2个阶段恰巧又是weex最核心的部分,难以撼动。而优化耗时常用的手段无非是下面两种:
> 1. 并行化
> 2. 提前执行
> 
> 预渲染方案则是选择提前执行耗时部分来减少用户打开页面的等待时间。
> 
> 对比终端页面的打开过程:
> > 创建 view -> 系统渲染
> 
> 如果能够让weex render创建view之前的步骤提前执行,real render的时候,打开速度就可以和终端页面打开速度媲美。
> 
> 所以有了下面的预渲染方案:
> 
> 预渲染的prerender过程:
> > prerender -> http请求JsBundle -> weexcore createInstance -> jsCore执行jsBundle 
> > -> 创建虚拟dom action -> weex frameWork执行dom action -> 创建、更新componentNode
> 
> realRender过程:
> > realrender -> 通过componentNode创建component、view -> 系统渲染
> 
> #### 预渲染效果
> 
> 
> 预渲染的实际效果根据页面动态性的不同会有不同的展现,但是毫无疑问可以大大提升用户打开页面的体验。且越是复杂的页面,优化的效果越好。
> 
> 以企鹅电竞的游戏首页的为例,现网上报中render->rendersuccess的耗时将近1.2s(已做预加载,jsBundle直接从本地文件中获取,耗时80ms),加上预渲染方案后,时间缩短到了160-180ms。
> 
> 预渲染生效的原因在于realRender的时候只需要根据componnetNode创建component和view,这一步操作已经等同于终端自身创建view的操作。
> 
> 另外,因为担心node节点过多导致在一个message中创建view anr,预渲染方案将创建component以node节点为单位post到了weex 
> render thread中执行action,这会有部分的性能损失,因此预渲染还没办法真正做到终端级别的页面打开耗时(100ms以内)。
> 
> #### 预渲染存在的问题
> 
> 1. 不支持recyclerList的页面(UpdateComponentDataAction尚未改造)
> 2. 预渲染时不支持InvokeMethod(InvokeMethodAction未改造)
> 3. 预渲染现在会导致部分统计数据有问题
> 4. 预渲染阶段不存在真正终端控件,故此时通过扩展module操作终端控件的行为会失效
> 
> 
> 
> 
> 
> ------------------ 原始邮件 ------------------
> 发件人: "申远"<[email protected]>; 
> 发送时间: 2019年1月22日(星期二) 下午5:31
> 收件人: "dev"<[email protected]>; 
> 主题: Re: prerender discuss
> 
> If this is about feature/issue discussion, rename the mail title to [DISCUSS] 
> XXXX next time.
> Describe the design or theory of pre-rendering as there are lots of code 
> change without a document.
> 
> Thanks
> 
> 
> 
> > 在 2019年1月22日,17:05,龙泉 <[email protected] <mailto:[email protected]>> 写道:
> > 
> >  solve the problem that the weex page is slow to open, we implemented the 
> > pre-rendering scheme. In many scenarios, we think that modifying the action 
> > in Java is the least modified solution. You are welcome to give suggestions 
> > for the prerender implementation.PR:
> > https://github.com/apache/incubator-weex/pull/1978 
> > <https://github.com/apache/incubator-weex/pull/1978> 
> > <https://github.com/apache/incubator-weex/pull/1978> 
> > <https://github.com/apache/incubator-weex/pull/1978%3E>;

Reply via email to