分类
微信小程序 编程相关

小程序云开发数据库/Mongodb时间戳转时间

我个人习惯在数据库中把所有时间按照时间戳保存,因此在某些使用场景如查询同一天过生日的人,需要忽略年份

此时需要将时间戳转为时间,并且格式化查询

AggregateCommand.add(value: Expression[]): Object
聚合操作符。将数字相加或将数字加在日期上。如果数组中的其中一个值是日期,那么其他值将被视为毫秒数加在该日期上。

故如下操作即可

$dateToString: {
    format: "%m%d",
    date: {
        "$add": [new Date(0), "$birthday"]
    }
}
分类
生命在于折腾 编程相关

Javascript使用Selenium

因为一些特殊原因,有一些网页用常规爬虫手段特别难爬,就常用到Selenium,由于我是做微信小程序开发的比较多,所以尽可能都是用Javascript

恰好Selenium提供了Javascript的使用文档,而简单易懂的使用案例局限性比较大,网上的帖子大多都是Python的

远程调用

部署远程服务器

在服务器上使用下面的命令启动容器,这里使用的是Chrome,如果要使用FireFox,Safari,Edge等其他浏览器去GitHub上找就行了这里是链接

$ docker run -d -p 4444:4444 --shm-size=2g selenium/standalone-chrome

Javascript使用

首先需要安装selenium-webdriver,使用npm install selenium-webdriver即可

const {
  Builder,
  Capabilities,
  By,
  until
} = require('selenium-webdriver');

const capabilities = Capabilities.chrome();

// ------
// 如果要忽略SSL问题加上这一行
// capabilities.setAcceptInsecureCerts(true);
// ------

const driver = new Builder()
    .usingServer("http://××.××.××.××:4444") // 服务器地址
    .withCapabilities(capabilities)
    .build();

await driver.get('目标网址');

// 等待指定元素加载完成 / 出现
await driver.wait(until.elementLocated(By.id('id')), 10000);

// 查找指定元素
const input = driver.findElement(By.className('input'));

// 往指定元素输入内容
await input.sendKeys('text');

// 点击某个元素
driver.findElement(By.className('submit')).click();

// 获得指定名称的Cookie
await driver.manage().getCookie('Cookie');

// 关闭
await driver.quit();

大概我用到的就是上面所写的,具体更加详细的文档点这里,上面只是列举一下常用的代码,这个文档翻着挺麻烦的,总结常用的会节省一些时间。

分类
微信小程序 生命在于折腾 编程相关

小程序长列表性能优化

2023 年 1 月 26 日更新:

在 skyline 渲染器中, scroll-view 设置 type=”list” 即可自动处理长列表的渲染


在小程序官方的文档“性能“一部分中写道

建议一个页面使用少于 1000 个 WXML 节点,节点树深度少于 30 层,子节点数不大于 60 个。一个太大的 WXML 节点树会增加内存的使用,样式重排时间也会更长,影响体验。

但是有一些场景下我们需要”无限“下划,此时越往下划页面上的WXML节点就越多。于是不显示在屏幕上的节点我们可以将其卸载掉。

在微信官方文档中,平台能力-扩展能力-扩展插件-“recycle-view”组件就可以用来解决这个问题,但是我们需要自己写一个方法来传入当前循环的列表组件的尺寸,但是很多时候,我们不能很好的预知即将渲染的组件的确切尺寸。

解决方法

我们在微信官方文档中看到了IntersectionObserver,可以用来监听组件是否和某个区域有交集,我们使用IntersectionObserver IntersectionObserver.relativeToViewport(Object margins)来监控可视区域的所有组件

同时长列表中的每个元素大多为循环,给每一个组件分配一个唯一的id,然后监听这个组件即可:

this.listener = this.createIntersectionObserver()
        this.listener.relativeToViewport({
            top,
            bottom
          }).observe(`#${id}`, (res) => {
            if (res.intersectionRatio == 0) {
              this.setData({
                show: false,
                height: res.boundingClientRect.height
              })
            } else {
              this.setData({
                show: true,
                height: res.boundingClientRect.height
              })
            }
          })

参考recycle-view中在滚动过程中,为了避免频繁出现白屏,会多渲染当前屏幕的前后2个屏幕的内容,所以上面的top和bottom参数为两个屏幕高度。

然后在渲染和卸载时,重新获得组件高度,在下次渲染时基本能够确定高度,设置css min-height为监听器中获得的height,在内容卸载后保持原有高度,防止滚动条发生奇怪的抖动。

由于近期我在外面出差,所以只是大致在原理上讲了讲,在即将写完的时候,发现网上有一篇文章使用了类似的方法,并且还给出了相关示例代码,文章:https://juejin.cn/post/6844904014404927496,GitHub:https://github.com/godaangel/wxapp-long-list

大家可以参考和使用他的解决方法,他的示例代码中没有卸载时的组件高度获取,时间关系,我就不测试是否会出问题了,我认为如果在中途组件高度有变化,在卸载时重新获取一次组件高度似乎更加可行。