原生小程序 - 小程序架构 和 配置文件

189 阅读6分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第10天,点击查看活动详情

双线程模型

小程序的宿主环境是微信客户端,所以微信客户端为了执行wxml文件、wxss文件、js文件

会将wxml文件、wxss文件、js文件交给webview控件来进行执行

当小程序基于 WebView 环境下时,WebView 的 JS 逻辑、DOM 树创建、CSS 解析、样式计算、Layout、Paint (Composite) 都发生 在同一线程,在 WebView 上执行过多的 JS 逻辑可能阻塞渲染,导致界面卡顿

为此小程序在实际渲染的过程中,使用了双线程模型

所谓双线程模型,本质就是开启了两个webview, 其中一个webview专门用于进行页面的渲染,另一个webview专门用于进行JS脚本的执行,两者通过native的JSBridge进行两个线程之间的数据通信

也就是说双线程模型的本质是通过多开启一个webview的方式来执行js脚本,以通过消耗内存的方式来提升渲染性能

  • WXML模块和WXSS样式运行于 渲染层,渲染层使用 WebView线程渲染(一个程序有多个页面,会使用多个 WebView的线程)
  • JS脚本(app.js/home.js等)运行于 逻辑层,逻辑层使 用JsCore运行JS脚本(因为webview内置渲染引擎是webkit)
  • 这两个线程都会经由微信客户端(Native)进行中转交互
  • 多个页面就意味着存在多个用于渲染的webview,但是执行JS的webview有且只会有一个

image.png

目前小程序新引入了一个名为skyline的渲染线程,该线程专门渲染小程序的应用界面

skyline会将渲染后的内容,直接交给GPU来进行硬件加速渲染

同时因为skyline是一个单独用于渲染的线程

所以他不需要开辟多个webview,也不需要在多个webview之间进行数据通信

因此skyline的总体性能会远远大于小程序的双线程模型

唯一的缺点是skyline目前还处于beta测试阶段

配置文件

小程序的很多功能可以通过小程序的配置文件直接生成,不需要自己从零进行开发

这样做可以更有利于我们的开发效率,并且可以保证开发出来的小程序的某些风格是比较一致的

从而养成用户习惯,间接提升用户体验和接受程度

配置文件说明
project.config.json项目相关的配置文件,比如项目名称、appid,小程序基础库版本等
功能类似于package.json
目前可以分为project.config.json 和project.private.config.json
project.config.json是一些团队开发需要共享的配置信息
project.private.config.json 是个人对应当前项目的配置信息,该文件一般会被放置到.gitignore中,不被git所管理
sitemap.json当前项目对应的站点映射文件
微信是提供小程序搜索功能的,和浏览器的页面搜索功能一样
小程序的搜索功能也是通过爬虫来进行实现的
sitmap.json配置文件用来设置当前项目的那些页面可以被微信爬虫进行收录,那些文件不能被微信爬虫进行收录
当一个微信小程序被微信爬虫收录的时候,微信爬虫会解析当前小程序并识别关键字,建立索引,以提高该微信小程序被用户搜索到的可能性
app.json当前项目的全局配置文件
<pagename>.json对于每一个页面的配置文件

app.json

image.png

{
  // pages -- 页面路径列表
  // 用于指定小程序由哪些页面组成,每一项都对应一个页面的 路径(含文件名) 信息
  // 小程序中所有的页面都是必须在pages中进行注册的
  // pages[0] 即为 当前展示的小程序页面
  "pages":[ 
    "pages/index/index",
    "pages/profile/profile"
  ],
  // 窗口展示的相关配置选项
  "window":{
    // 下拉背景色 - 可选值 light | dark
    "backgroundTextStyle":"light",
    "navigationBarBackgroundColor": "#fff",
    "navigationBarTitleText": "Demo",
    // navigationBar 的字体颜色 - 可选值 black | white
    "navigationBarTextStyle":"black"
  },
  // 顶部或底部 tabbr的配置文件
  "tabBar": {
    // 选中时候文字的颜色
    "selectedColor": "#ff8189",
    // tabbar 上边框的颜色 - 可选值 white | black
    "borderStyle": "black",
    // tabbar的列表信息 至少两项,最多三项
    "list": [
      {
        // 页面路径 -- 必须在pages中注册过
        // 在tabBar中配置的路径必须是相对路径,也就是说该路径不能以/开头
        "pagePath": "pages/index/index",
        // 展示文本
        "text": "首页",
        // 未选中时候 展示的图标
        "iconPath": "assets/tabbar/home.png",
        // 选中的时候 展示的图标
        "selectedIconPath": "assets/tabbar/home_active.png"
      },

      {
        "pagePath": "pages/profile/profile",
        "text": "我的",
        "iconPath": "assets/tabbar/profile.png",
        "selectedIconPath": "assets/tabbar/profile_active.png"
      }
    ]
  },
  // 小程序对内置组件样式进行过一次改动,如果要使用最新版本的样式,需要将style的值设置为v2
  "style": "v2",
  // 设置站点映射文件所在的目录,默认是位于项目的根目录
  "sitemapLocation": "sitemap.json"
}

page.json

每一个小程序页面也可以使用 .json 文件来对本页面的窗口表现进行配置

页面中配置项在当前页面会覆盖 app.json 的 window 中相同的配置项

{
  // 在页面中使用的第三方组件或自定义组件需要在这里进行注册
  "usingComponents": {},
  // 默认页面是不可以下拉刷新的
  // 只有开启enablePullDownRefresh后,页面才可以下拉属性,才可以在界面中监听到onPullDownRefresh事件
  "enablePullDownRefresh": true,
  // 默认下拉刷新时候的 loading进度条是light的
  // 在白色背景下 显示不明显 所以可以修改为dark形式的loading动画条
  "backgroundTextStyle": "dark",
  // 下拉加载更多的时候,距离页面多少px的时候,触发onReachBottom事件
  "onReachBottomDistance": 100 // onReachBottomDistance 的默认值为 0
}

示例

  1. 默认显示50条数据
  2. 当快到达页面底部的时候,追加50条记录
  3. 当上拉刷新后,页面恢复50条数据
{
  "usingComponents": {},
  "enablePullDownRefresh": true,
  "backgroundTextStyle": "dark",
  "onReachBottomDistance": 100
}
<view>数据列表 </view>

<block wx:for="{{ count }}" wx:key="*this">
  <view>列表数据项: {{ item }}</view>
</block>
Page({
  data: {
    count: 50
  },

  // 和自定义事件一样
  // Page对应的事件回调函数也是写在配置对象顶层的
  // onPullDownRefresh 为当下拉刷新后触发的事件回调
  onPullDownRefresh() {
   setTimeout(() => {
    // 默认情况下,小程序的下拉刷新动画会持续3s的时间
    // 如果我们提前获取到对应的数据后,可以调用 stopPullDownRefresh 方法来结束下拉刷新动画
    // wx是小程序提供的全局对象,在该对象上挂载了一系列的全局方法
    // wx.stopPullDownRefresh的参数是一个 可选 的 配置对象
    wx.stopPullDownRefresh({
      // 下拉刷新 成功的时候 执行的回调
      success: res => {
        this.setData({
          count: 50
        })

        // console.log(res)
      },
      // 下拉刷新 失败的时候 执行的回调
      fail: err => {
        console.log(err)
      }
    })
   }, 1000)
  },

  // 页面显示内容 距离 页面底部 还有 onReachBottomDistance 距离的时候 
  // 触发的回调函数  可以用来完成 无限加载的功能
  onReachBottom() {
    // 小程序对应的数据状态会被存储到AppData页签中
    // 可以通过查看AppData页签中的数据 可以确认下拉刷新后 是否成功重置了数据
    this.setData({
      count: this.data.count + 50
    })
  }
})