小程序(程序小游戏)


今年年初,在官方文档上看到小程序团队要推出一款性能逼近原生的渲染引擎Skyline,就一直在关注。刚好最近打算做一款新的阅读小程序,作为一名独立开发者,对于性能和用户体验的追求是永无止境的,于是我决定用纯Skyline打造这款小程序。

当然,这个项目里面所用到的skyline特性只是冰山一角,并非全部,更多酷炫的特性请前往官方文档查阅。

接下来小程序,我会结合快书小程序,从以下几个方面,逐条阐述关于skyline特性(快书项目中所用到的)的理解与应用:

1. 效果演示。

2. 如何开启Skyline。

3. 新版组件swiper。

4. 新版组件scroll-view。

5. 全新组件snapshot。

6. 增强特性worklet动画。

7. 增强特性手势系统。

8. 增强特性自定义路由。

9. 增强特性共享元素动画。

希望对于刚接触Skyline,或者想要了解Skyline的同学有所帮助。当然,如有错误或遗漏,欢迎在评论区批评指正,不胜感激。

一、效果演示

image

二、如何开启Skyline

开启Skyline的方式非常简单,只需要在app.json文件中,加入以下配置即可(这里是全局Skyline,若只打算指定页面开启,则在指定页面的json文件中配置即可):

"renderer":"skyline",
"lazyCodeLoading":"requiredComponents",
"rendererOptions": {
  "skyline": {
    "defaultDisplayBlock":true,  
  }
},
"componentFramework":"glass-easel",

三、新版组件-Swiper

旧版的Swiper基于webview的,在性能上有所局限,特别是当swiper-item的数量动态不断增加的情况下。当然,也可以自己想办法去优化,比如做懒加载和缓存,但相对来说比较麻烦。而Skyline版本的Swiper性能会大幅度提升,首先渲染引擎本身的性能提升了,另外官方也做了缓存的功能,只需要通过定义cache-extent的值,就能轻松定义缓存区域大小,例如值为 1 则表示提前渲染上下各一屏区域。

swiper

用法上,和webview版本没有太大区别(这里就不放代码了),只需注意不要使用某些webview独有的特性即可。

四、新版组件-Scroll-view

同样小程序,旧版的scroll-view也基于webview的,滚动元素过多的时候会有明显卡顿,当然也是可以通过虚拟Dom的方式自行优化。然而,Skyline版本的scroll-view官方已经实现了只会渲染在屏节点的特性,大大提升了滚动的流畅度,真正做到了开箱即用。

用法上,有以下几个点要注意的。

指定type属性,有2个可选值,分别为:list和custom,对应的是列表模式和自定义模式。如是普通列表,list即可,如果是稍微复杂的列表,比如常见的瀑布流表现形式(类似小红书那样),则可使用custom。

只有直接子节点才能根据是否在屏来按需渲染。即你不能把你的列表项,都放在同一个父级view中,而是应该直接放在scroll-view组件下。

// 错误的方式:

  
    
  

// 正确的方式

  

// 正确的方式

  
    
  

另外,上面提到了瀑布流的问题,实现方式也很简单,官方提供了一个叫做grid-view的组件,只需定义它的*type=“masonry”*即可,但若是在webview下,除了性能不理想以外,还会有一些小BUG,比如经常会出现大块区域的空白。在Skyline下,就不会出现此类问题。

瀑布流


  
    
  

五、全新组件Snapshot

我们常常会有分享精美海报的需求,但由于海报上的内容是动态,仅仅使用一张图片分享达不到我们的目的。在以往,我们可能会使用到wxml-to-canvas,通过绘制 canvas ,导出图片。现在,在Skyline下(基础库3.0.0以上),实现此需求就非常简单。只需要将我们要分享的内容包裹在snapshot组件下就行。

00

分享海报

// wxml:

  content

// page:
Page({
  onReady() {
    this.createSelectorQuery()
      .select("#target")
      .node()
      .exec(res => {
        const node = res[0].node
        node.takeSnapshot({
          type: 'arraybuffer',
          format: 'png',
          success: (res) => {
            fs.writeFileSync(savePath,res.data,'binary'); //图片保存至本地
            wx.showShareImageMenu({ //唤起分享图片的界面
              path:savePath
            })
          },
          fail(res) {}
        })
  }
})

六、增强特性-worklet动画

worklet动画相比传统的方式,流畅度提升了不少,但如何使用呢?常见的普通动画无非是对于页面元素的平移,缩放,旋转等变换。那么,要让一个元素动起来,只需要做以下2件事:

将页面元素的样式与某个变量进行绑定,变量值的变化会自动触发样式的更新。

实时动态地改变这个变量。

结合快书的例子(下拉时,让页面缩小,松手后,页面弹回),来看一下具体的实现步骤。

worklet动画.gif

第一步,如何绑定样式与变量,通过官方提供的一个applyAnimatedStyle函数:

// Wxml:
content
// Page:
this.scale = shared(1); //这里是定义一个共享变量,即可在UI线程和JS线程间同步的变量。
this.applyAnimatedStyle(`#box`, () => {
  'worklet'; // 声明这是一个worklet函数
  return {
    transform: `scale(${this.scale.value})`,
  };
});
// 1、这里使用共享变量是为了让后续改变这个变量时,worklet的函数能捕获到。
// 2、#box你要动起来的元素
// 3、当this.scale.value变化时,会自动触发函数体的执行,从而改变#box的样式

第二步,下拉时,根据下拉的偏移量,改变这个scale的值。

this.scale.value = (evt.deltaY / 100) * 0.15;
// 这里的evt.deltaY是下拉时的位置偏移量,然后根据偏移量按比例计算缩放的值
// 如何获取这个下拉偏移量?下一小节讲手势系统时会讲到

第三步,松手时,复原scale的值。

this.scale.value = timing(1, { duration: 300, easing: Easing.ease });
// timing函数表示:在300毫秒内,scale.value会逐渐变成1
// easing: Easing.ease 表示缓动的方式,具体可参考https://easings.net
// 如何知道已经松手了?下一小节讲手势系统时会讲到

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站不拥有所有权,不承担相关法律责任。如发现有侵权/违规的内容, 联系QQ3361245237,本站将立刻清除。