DarkYeahs

Results 5 issues of DarkYeahs

## 【bigo】长列表在Likee年度盛典的应用 列表是页面常用的一种数据表现形式,在页面中常用写法如下 ```html ``` 但在likee2021年度盛典的这次活动中,产品给出了一个难题:在一个页面中显示一个数据量达上万的长列表,要求支持滑动至任一位置。 一个上万数据的简单列表在页面显示需要至少上万个元素,如果列表中存在交互事件,那浏览器需要花费多少时间去渲染呢? 用一个简单列表来显示,在chrome浏览器中需要800ms左右,使用的内存为95.7m,而活动中列表显示的内容会比演示的代码更多,交互更加复杂,webview渲染的时间及占用的内存也会更多,那如何去优化呢? ![加载时间及内存](https://static-web.likeevideo.com/as/likee-static/blog/202111291427.png?random=1) ### 列表可视化渲染 ![](https://static-web.likeevideo.com/as/likee-static/blog/20211129214823.png) 用户查看页面的时候,只能看到屏幕窗口显示的界面,那再窗口外的内容我们可以选择不进行全部渲染。如下图所示,我们将长列表截取一部分数据再页面上进行渲染,用户看到的数据是在内容显示区域,当用户上滑或者下滑的时候,使用处于上滑待显示区域或者下滑待显示区域的数据替代内容显示区域的数据,再从长列表中更新上滑待显示区域或者下滑待显示区域的数据,从而实现列表的可视化渲染。 ### 实现方案 ![时序图](https://static-web.likeevideo.com/as/likee-static/blog/202111300950.png?random) 当用户打开页面查看长列表的时候,页面会向后端请求接口,获取长列表的初始数据以及列表长度,根据列表长度以及初始化子元素的高度来初始化容器的滑动高度。 设定容器的滑动高度后,将当前显示容器设定为三个区域,滑动待显示区域以及可视显示区域,计算当前的滑动高度以及可视显示区域的高度,计算当前渲染的列表长度。 ```javascript const { total, list } = await this.fetchData(); if (this.cachedHeight.length ===...

       egret是一款小游戏开发引擎,支持跨平台开发,目前用这款引擎开发了一款捕鱼游戏,在这里简单聊下再egret中关于对象池的使用。 #### 起因        关于对象池的使用主要是有两个场景,一个是捕鱼游戏里面鱼的生成,还有一个是射击过程中子弹的生成。当用户处于游戏时,这两个场景会频繁的生成对象并展示对应的动画,会造成大量的内存碎片以及频繁的分配内存空间。而通过对象池能够比较好的解决这个问题。 ![捕鱼场景](https://static-web.likeevideo.com/as/likee-static/blog/clipboard.png) #### 对象池模式        首先定义一个池对象,用来存储可复用的对象。池对象包含两组列表,一组为可复用hash对象,一组为正在使用的hash对象。在游戏加载游戏资源的时候,对池对象进行初始化,创建了一个鱼对象集合,并且同时初始化可复用hash对象作为备用池。        当游戏资源加载完成的同时,向对象池尝试获取一个可复用的鱼对象,对象池查询可复用hash对象是否存在可以复用的鱼对象,存在可复用对象的时候将对象进行初始化并将对象的索引从可复用hash对象中移除加入正在使用的hash对象。当鱼对象在游戏舞台中被移除的时候,将其进行回收到可复用hash对象等待下一轮渲染。通过这种方式避免了大量的重复对象的创建跟销毁,减少不必要的内存分配。 #### 实现方式        首先设计一个工厂方法,实现一个FishGenerator类,负责各种类型Fish的生成,Distributor类负责各类鱼的回收与存储。 ![流程图](https://static-web.likeevideo.com/as/likee-static/blog/clipboard-5.png)        鱼的实现如下,前期开发过程中,不同种类的鱼没有单独分开类实现,都是通过传入骨骼动画与类型内部实现的,所以这里通过``` type``` 来识别不同的鱼进行获取与复用。``` hashc``` 是``` egret``` 本身的``` hashCode``` ,通过``` hashc``` 允许外部访问,并且由于其具有唯一性,所以将其作为存储管理的下标。 ```TypeScript interface IFish { hashc:number; //hashCode...

### 问题起因     公司的设计小姐姐突然找我说我做的一个图片合成工具透明的区域变成黑色了。 ![原图](https://static-web.likeevideo.com/as/likee-static/blog/202107061237.png )![转化后的图片](https://static-web.likeevideo.com/as/likee-static/blog/202107061236.png)     第一步想法是背景初始化存在问题,导致透明区域黑化。但试了下通过浏览器选中canvas元素下载图片透明区域是生成正常的,那就是在绘制完成后到下载这一步中间发生了问题。检索了一下整个步骤,再绘制完成到下载过程中有 1. 将canvas转成blob对象 2. 调用压缩库压缩blob对象 3. 将blob对象写到本地     通过浏览器选中canvas元素下载跟执行过程1,3是类似的,所以问题应该是出现再过程2将blob对象压缩过程中的操作导致的黑底,压缩用的库是使用的image-conversion,其中进行压缩的核心代码是 ![压缩代码](https://static-web.likeevideo.com/as/likee-static/blog/202107061231.png)     上图是压缩库的核心方法,利用的是canvas转图片时通过对第2个参数设置进行压缩,但仅限于图片格式为 image/jpeg 或 image/webp,因为调用的时候是没有指定图片格式,默认为image/jpeg的格式,所以再进行压缩的过程中,透明区域的颜色会默认为黑色渲染,所以生成的图片在透明区域就会呈现为黑色区域。也就是image-conversion的图片压缩只适用于不存在透明通道的图片,对需要透明通道的图片并不适用。 ### png图片格式的压缩     那如何保留透明通道的图片压缩呢,先了解下png图片的一些基础。     png,全称为流式网络图形格式(Portable Network Graphic Format),是一种位图文件(bitmap file)存储格式。主要有3种格式:png8,png24, png32     png本身是一种数据压缩文件,是由很多种数据块,分为两种类型:关键数据块以及辅助数据块。图片的内容集中在关键数据块上,数据类型如下: |数据块符号| 数据块名称...

# 调试工具分享 ## spy-debugger调试 能够再安卓低端机型上进行调试,支持iOS及安卓跨端调试 工具github地址: https://github.com/wuchangming/spy-debugger ### 安装环境 node v10.16.0v npm v6.9.0 ### 安装 >npm install -g spy-debugger ### 启动 >spy-debugger -p 8888 ### 代理配置 根据启动命令界面进行配置,执行启动命令后界面一般如下: ### 正在启动代理 本机在当前网络下的IP地址为:xxx.xx.xxx.xx...

## 【bigo】LikeeLive年度盛典优化浅谈 #### 一、背景 LikeeLive首次举办线上年度盛典,不管是用户玩法内容还是主播玩法内容都是月度活动的2-3倍,安排了前端4个人投入开发,在各自开发完成后合并代码,在自测阶段发现测试环境页面加载过慢,性能评分未能到达上线要求。 #### 二、问题分析 先放大图 ![google性能评分](https://static-web.likeevideo.com/as/likee-static/yeahs/blog-1.png) 在Performance这方面的评分只有32分,一个对用户体验极差的分数。首屏的加载时间需要6.2s,阻塞时间480ms,css文件最大文件大小超过1.7m,js文件最大文件大小超过800kb+。 #### 三、问题方案 首先加载时间与资源文件大小是有一定关系的,所以先对1.7m的css文件与800kb的js文件进行瘦身。 css文件分析 ![css文件](https://static-web.likeevideo.com/as/likee-static/yeahs/blog-2.png) 项目构建过程中会将小于10kb的图片转成base64字符串储存到css文件中,这次活动用到的本地图片数量700+,icon小图标100+,检查了下编译后的css文件,存在大量的base64编码的图片,所以考虑接入雪碧图构建,对小icon进行合并处理,减少图片转成base64编码数量以及网络请求数。 目前调用icon小图标的方式是通过mixin方式进行调用的,调用方式如下: ```scss @mixin Ricon($width, $height, $url, $important: '') { @include background(#{$baseURL}#{$url}.png, $important); display: inline-block;...