干货 | 瘦身50%-70%,携程 Taro 小程序样式 Size 缩减方案

这篇具有很好参考价值的文章主要介绍了干货 | 瘦身50%-70%,携程 Taro 小程序样式 Size 缩减方案。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

作者简介

Can,携程前端开发,目前从事小程序开发工作,对编译打包技术、小程序跨平台解决方案有浓厚兴趣。

一、概述

目前我们团队小程序是使用 Taro 跨端方案 React 框架进行开发,基于现有样式方案,在编译打包后会产生大量的样式代码冗余,在项目编译后的产物中占有较大比例。

分析了编译后的样式代码后,我们发现冗余代码主要体现在两个方面:

  • 项目样式文件中大量使用了父子选择器作为作用域进行样式隔离,编译后出现类名大量重复冗余。如以下 SCSS 文件样式代码中,编译后 .box .item 重复冗余了三次。

// 编译前代码
.box {
  .item {
    .item1 {}
    .item2 {}
    .item3 {}
    .item4 {}
  }
}
// 编译后代码
.box .item .item1 {}
.box .item .item2 {}
.box .item .item3 {}
.box .item .item4 {}
  • 样式代码中大量属性值重复冗余。如最常用的 display: flex 属性值,在项目中可能存在几百上千份重复冗余,而且为了兼容性开启了 Autoprefixer 插件后, display:flex 将会变成 display:-webkit-flex;display:-ms-flexbox;display:flex; ,使得样式文件属性值的冗余情况更为严重。

针对 Taro项目 React 框架小程序遇到的以上问题,本文将介绍一种新的样式解决方案。本方案在较少改变现有开发体验的条件下,采用 cssModules 样式方案语法要求,利用 Taro 插件的便利性给出对应的解决方案,以此对产物进行“瘦身”。最终样式文件的瘦身效果可以达到 50% - 70%,进一步缓解官方包 Size 的限制,便于业务的高速发展。

二、cssModules 简单介绍

本文样式方案学习了 cssModules 解决样式冲突的基本原理,并在此基础上改进以达到缩减样式文件 Size 的目的。因此在正式了解本方案之前,本文先用 Taro 官网中使用 cssModules 方案的例子代码作为示例,简单了解下其语法要求与原理。

2.1 语法要求

在配置开启了 cssModules 后,按照语法要求,Taro 项目中有 index.module.scss 和 index.js 两个文件,文件代码如下。cssModules 默认是开启部分自定义模式转换,只有文件名中包含 .module. 的样式文件才会经过 cssModules 转换处理。在如下 index.module.scss 样式文件中,我们正常使用了父子选择器、类选择器。但是在index.js 文件中,className 赋值不再是字符串,而是 SCSS 文件导出的 Object 的某个 Key,该 Key 为 SCSS 文件中的类选择器的命名。

import React, { Component } from 'react'
import { View, Text } from '@tarojs/components'
import styles from './index.module.scss'


export default class Index extends Component {
  render() {
    return (
      <View className={styles.test}>
        <Text className={styles.txt}>Hello world!</Text>
      </View>
    )
  }
}
.test {
  color: red;
  .txt {
    font-size: 36px;
  }
}

2.2 原理

Taro 项目开启 cssModules 配置后,在编译打包时,会使用实现了 cssModules 规范的 css-loader 对 SCSS 等样式文件进行处理。它首先会处理原 SCSS 文件中的类选择器,将类名进行哈希处理得到新类名如 index-module__test___Bm2J6 ,生成新的样式代码输出到最终的 index.wxss,同时保存了原类名与哈希处理后的新类名的映射关系。此后它会将原 SCSS 文件 index.module.scss 编译为导出了原类名与哈希后的新类名的映射对象。JS 文件在运行时能通过该映射对象获取到哈希后的新类名,保证该文件类名不会与其他样式文件的同类名冲突,从而解决样式冲突问题。以下为编译后的代码示例, styles.test 在运行时会会变成 index-module__test___Bm2J6 。

// index.module.scss
export default ({"test":"index-module__test___Bm2J6","txt":"index-module__txt___nIysk"});
// index.wxss
.index-module__test___Bm2J6 {
  color: red;
}
.index-module__test___Bm2J6 .index-module__txt___nIysk {
  font-size: 36rpx;
}

三、方案原理介绍

3.1 基本原理

3.1.1 当前样式文件 size 分析

在正式介绍本文方案是如何缩减样式文件 Size 之前,本文通过以下两个正则去分别匹配打包产物中所有样式文件的两个核心组成部分 ClassName 与 PropertyValue,并进行 Size 统计分析。

注:在本文中,有如该 .txt .tit {color: #red;} CssRule代码,ClassName 指的是其中的 txt 和 tit ,PropertyValue 指的是 color:#red; 。

const classNamePattern = /(?<=\.)[A-Za-z0-9\-_]+(?=\s|{|:)/g // 匹配 ClassName 如 .txt {color: #red;}中的txt
const cssPropertyPattern = /(?<=\{)[^}]+(?=})/g // 匹配PropertyValue, 如 .txt {color: #red;}中  中括号之间的所有内容 color: #red;

下图是对整个编译打包后的小程序项目的样式文件进行组成 Size 分析。通过该图我们可以发现,我们项目打包编译后的所有的样式文件中,ClassName 占用大约有五分之一的空间,而 PropertyValue 则占用了有十分之七的空间,其余空间占比可能是如空格、伪类这种形态存在,本文暂不考虑。

干货 | 瘦身50%-70%,携程 Taro 小程序样式 Size 缩减方案,taro,小程序,前端,html,css

3.1.2 处理方案

通过上一小节,我们可以知道一个样式文件中核心主要有两部分内容,一是 ClassName,二是 PropertyValue。本文样式方案对这两部分分别进行了处理来达到节省 Size 的目标。

1)缩减 ClassName 长度

核心就是将原 ClassName 替换成更短且唯一的 ClassName,在解决样式冲突的同时,也通过缩减了 ClassName 长度节省了 Size。当我们使用 cssModules 时,通常如第二章介绍 cssModules 时的示例代码一样,都是将 ClassName 进行 hash 化处理来保证唯一性,但是经过 hash 处理后的 ClassName 长度反而变得更长了,不符合我们缩减样式代码 Size 的目标。

本方案是从最短字符开始,逐渐递增的方式生成全项目唯一的 ClassName,从而保证唯一性的同时能够保证 ClassName 长度尽可能的短。如第一个解析到的 ClassName 替换成 -a ,第二个解析到的ClassName替换成 -b ,第五十二个解析到的 ClassName 替换成 -Z ,第五十三个解析到的 ClassName 替换成 -aa 。其中 ClassName 前面的 - ,用于防止新生成的类名与未转换的类名冲突。此外,新生成的 ClassName 注意需要符合规则,本插件算法先取 prevString 中一个字符,后续所有字符可以取任意 charString 中字符。

const prevString = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' // 52个字符数
const charString = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_' // 64个字符数

可能有人担心,随着整个项目中 ClassName 申明的越来越多,逐渐递增生成的 ClassName 也会越来越长,反而导致总 ClassName 过长。通过上述算法,算上最前面加上的  -  , 当使用完三个字符长度的类名可 以替换 52 * 64 = 3328 个 ClassName 了,达到使用完四个字符长度需要 52 * 64 * 64 =  212992 个 className。新生成的 ClassName 不超过四个字符,就可以满足大部分项目的使用,使用本样式方案前可以检索下自己项目中 ClassName 的量级。

2)缩减 PropertyValue

通过上面的分析可以发现,其实占据样式文件 Size 最多的部分是 PropertyValue,因此缩减 PropertyValue 是本样式方案能够节省大量 Size 的核心手段。其实我们在开发时用到的样式属性值很多都是重复的,比如开发过程中用到的最多布局属性 display:flex 。每次用到该属性都需要新写一份,而且为了兼容性开启了Autoprefixer插件, display:flex 将会变成 display:-webkit-flex;display:-ms-flexbox;display:flex; ,这使得样式文件的 Size 变得更大。本插件是通过尽可能复用 PropertyValue 的方式来缩减 PropertyValue。

本插件会将样式文件中的仅使用了类选择器的 CssRule 进行 PropertyValue 拆分,每一次拆分都会生成新的 PropertyValue ClassName。如以下示例代码,仅类选择器CssRule txt 被拆分了 _a 和 _b 两个 PropertyValue ClassName。后续若其他使用仅类选择器 CssRule 进行拆分时,若有相同的 PropertyValue 就会直接复用 _a 或者 _b 。

// 原代码
.txt { display: flex;flex: 1; }
// 处理后的代码
._a {display: -webkit-flex; display: -ms-flexbox;display: flex;}
._b {-webkit-flex: 1;-ms-flex: 1;flex: 1;}

而在使用 cssModules 样式写法的 js 文件中也需要进行相应的映射处理,通过 babel 插件在编译时进行转换处理,判断 css 文件的引用关系并进行替换,示例代码如下。

// 原代码
import styles from './index.module.scss'
Index = () => {
  return <View className={styles.txt} />
}
// 处理后的代码
import './index.module.scss'
Index = () => {
  return <View className="_a _b" />
}

本样式方案通过对仅使用了类选择器的 CssRule 的 PropertyValue 拆分成新的 PropertyValue ClassName,后续任何进行拆分的地方就可以直接复用该 PropertyValue ClassName,从而可以大量缩减 PropertyValue 重复冗余占用的 Size。

3)插件处理流程

以上两小节已经介绍了两个核心缩减 Size 的方案,本小节举一个更加全面的例子来介绍本插件是如何在编译时运用以上两个方案,对样式文件和 JS 文件进行处理转化的。主要有以下两步。

第一步,针对仅使用类选择器的 CssRule,进行 PropertyValue 拆分。如下示例代码中, .box{display:flex} 拆分出了 ._a {display: -webkit-flex;display: -ms-flexbox;display: flex;} ,后续 .item1` `.item2 拆分时,直接复用了 ._a ,缩减了 PropertyValue 重复冗余。

第二步,针对非仅使用类选择器的 CssRule,直接替换成全局唯一且更短的 ClassName。如下示例代码中, .box .item2{color: red;} ,原选择器中的 ClassName 直接替换成了更短的 .-a .-b{ color: red;} ,并且添加了该映射关系 styles = {box: "_a -a", item1: "_a _b _c", item2: "_a _b _d -b"} ,并在编译时进行替换。

// 原代码
import React from 'react'
import styles from './index.module.scss'


export default Index = () => {


  return <View className={styles.box}>
    <View className={styles.item1}>item1</View>
    <View className={styles.item2}>item2</View>
  </View>
}
// 处理后的代码
import React from 'react'
import './index.module.scss'
// styles = {box: "_a -a", item1: "_a _b _c", item2: "_a _b _d -b"}
export default Index = () => {


  return <View className="_a -a">
    <View className="_a _b _c">item1</View>
    <View className="_a _b _d -b">item2</View>
  </View>
}
// 原index.module.scss代码
.box {
    display: flex;
}
.item1{
    display: flex;
    font-size: 32px;
    color: red;
}
.item2{
    display: flex;
    font-size: 32px;
    color: grey;
}
.box .item2{
    color: red;
}
// 处理后index.module.scss代码
._a {display: -webkit-flex;display: -ms-flexbox;display: flex;}
._b {font-size: 32px;}
._c {color: red;}
._d {color: grey;}
.-a .-b{
    color: red;
}

3.2 需要注意的问题

3.2.1 styles 对象的属性不支持运行时

cssModules 方案中,JS 文件中引入的样式文件对象支持运行时计算属性的,如以下示例写法。这是因为在打包后的 JS 文件中,保存有一份原 ClassName 与 hash 后新 ClassName 映射关系的对象数据,因此运行时 styles 还能映射属性,但是这种处理方式会导致 js 文件 size 增大。

import styles from './index.module.scss'
const Index = () => {
  return <View className={styles['t' + 'xt']} />
}

本方案为了尽可能保证项目 Size 足够小,并没有采用 cssModules 这种处理方式。本方案在编译时会直接对原 CLassName 与拆分 PropertyValue 后的新 ClassName 直接进行了替换,如直接把 className={styles.txt} 替换成 className="_a _b" 。

因此本方案 styles 对象不支持如上示例代码中,运行时计算得到 txt 属性,如需动态调整样式有两种方案,一是直接使用内联样式。二是新写 ClassName 而不是拼接,如className={value ? styles.txt1 : styles.txt2}} 。

3.2.2 仅类选择器不依赖先后顺序定优先级

在上文中,提到过会拆分仅使用类选择器 CssRule,来尽可能复用已有的 PropertyValue ClassName。但是这种复用是有缺陷的,它会导致 ClassName 的先后顺序可能不符合预期,如下代码所示,通常来说我们认为标题颜色应当是 grey 。

// 原代码
import styles from './index.module.scss'
const Index = () => {
  return <View className={styles.tit1 + ' ' + styles.tit2}>标题</View>
}
// 处理后的代码
import styles from './index.module.scss'
const Index = () => {
  return <View className={'_a' + ' ' + '_b'}>标题</View>
}
// 原代码
.other { color: green; color:red; }
.tit1 { color: red; }
.tit2 { color: green; }
// 处理后的代码
._a {color:green;}
._b {color:red;}

但是经过本插件复用了 PropertyValue 后,导致 ._b{color:red;} 出现在了 ._a{color:green;} 后面了,此时标题的颜色也就变成了 red ,从而可能不符合开发者预期。

因此需要注意在编写仅类选择器 CssRule 的 ClassName 时,不能依赖类选择器先后顺序来定优先级,可通过兄弟选择器来将优先级提的更高,从而不受先后顺序影响,如下代码示例。这样就能确定标题颜色一定是 green 。

// 兄弟选择器来提高优先级
.other { color: green; color:red; }
.tit1 { color: red; }
.tit1.tit2 { color: green; }

四、使用指南

4.1 使用

4.1.1 安装插件

本样式方案被集成在该 Taro 插件 taro-plugin-split-class 中,安装本插件。源码见仓库 taro-plugin-split-class。

npm install -D taro-plugin-split-class

4.1.2 关闭cssModules功能

在 Taro 配置文件中,使得 mini.posetcss.cssModules.enable = false ,确保 cssModules 功能关闭,如下代码所示。

// config/index.js
{
    mini: {
        postcss: {
            cssModules: {
                enable: false
           }
        }
    }
}

4.1.3 配置本插件

在 Taro 配置文件中, plugins 配置中加入本插件 taro-plugin-split-class 。本插件支持配置类名转换白名单(实现功能类似 : global,见 2.4)classNameWhite,比如常用的 iconfont 是不需要转换的。

plugins: [
    ['taro-plugin-split-class', {
      classNameWhite: ["iconfont", /^ifont-/]
    }]
]

4.2 语法要求

a. 样式文件命名需以 .module.xxx 结尾,如 index.module.scss,该样式文件方可被本插件转化处理。

b. 在 JS 文件中,将样式文件作为一个对象引入,并将类名作为对象的键进行使用。如下代码所示,使用 className={styles.box} 而不是 className="box" ,其中 box 为定义在样式文件的中类名。

// 如下
import styles from './index.module.scss'
<View className={styles.box}></View>
// 而不是
import './index.module.scss'
<View className="box"></View>

c. 本方案支持所有选择器包括父子选择器、伪类选择器、兄弟选择器等等。但请尽可能的使用仅类选择器来定位元素,这样做可以便于插件尽可能复用 PropertyValue 从而更好的缩减 Size。本方案解决了类名冲突问题,因此开发者不需要担心因类名命名简单而导致的类名冲突。

// 如下仅类选择器的CssRule
.box {
    display: flex;
    flex-direction: column;
    align-items: center;
}
.tit {
    display: flex;
    font-size: 40px;
    color: red;
}
// 而不是父子选择器
.box {
    display: flex;
    flex-direction: column;
    align-items: center;
    .tit {
        display: flex;
        font-size: 40px;
        color: red;
    }
}

d. 特殊类名不变

有时候我们希望一些特殊的 ClassName 不变,在 JS 文件中,不从 styles 取类名即可,如下代码中的 extra 。

import styles from './index.module.scss'
<View className={styles.tit + ' extra'}>标题</View>

但是在样式文件中默认所有 ClassName 都会被拆分或者压缩。如下代码示例, extra 被处理成 -a 。

// 原类名
.extra.tit {
color: blue;
}
// 新类名
.-a.-b {
    color: blue;
}

因此需要特殊标识符让插件感知到不需要处理该 ClasName。本方案提供了类似 cssModules 的 :global 的解决方案,有两种使用方式,一是 :global(.extra) ,被包裹的类名不会被替换。

// 编译前
:global(.extra).tit {
  color: blue;
}
// 编译后
.extra.-a {
    color: blue;
}

二是以 :global 开头,后续所有的类名都不会被替换。

// 编译前
:global .extra1 .extra2 { color: red;}
// 编译后
.extra1 .extra2 { color: red;}

4.3 打包效果展示

4.3.1 开发环境

使用本插件后,原类名会被替换或拆分成更短且更多的新类名。这样处理后的新类名可读性很差,开发者不能很好的定位到原类名代码。因此在开发环境下,会在更短且更多的新类名前会加上[文件夹_文件名_原类名]。保留了原类名相关信息,便于开发者查找原类名。如下图代码所示,原类名为 box ,经过插件拆分和缩短后的新类名为 _a _g _h -c ,在新类名前加上了 index_indes-module_box ,最终展示的完整类名为 index_index-module_box _a _g _h -c 。

干货 | 瘦身50%-70%,携程 Taro 小程序样式 Size 缩减方案,taro,小程序,前端,html,css

4.3.2 生产环境

在生产环境了,不需要考虑新类名可读性,因此直接会直接将类名完全替换为新类名。如下图代码所示, box 直接被替换成 _a _g _h -c 。

干货 | 瘦身50%-70%,携程 Taro 小程序样式 Size 缩减方案,taro,小程序,前端,html,css

五、方案分析

5.1 实践效果

5.1.1 页面改造前后对比

在使用本样式方案对某个页面进行改造后,改造前后 Size 对比如下。可以发现样式文件缩减了 44KB,缩减了将近 70% 的 Size,JS 文件有这 2kb 的增长。


JS文件  样式文件  总和
 使用前 54kb 63kb 117kb
 使用后 56kb 19kb 75kb

使用前编译后文件 Size 如下图:

干货 | 瘦身50%-70%,携程 Taro 小程序样式 Size 缩减方案,taro,小程序,前端,html,css

使用后编译后文件 Size 如下图:

干货 | 瘦身50%-70%,携程 Taro 小程序样式 Size 缩减方案,taro,小程序,前端,html,css

5.1.2 重构页面横向对比

最近我们项目重构了两个大型订单详情页面,本小节以这两个页面重构后的代码为例,分析编译打包前后的 Size 并进行横向对比。

整理出如下表格:


样式编码字符数 打包后实际Size
未使用本样式方案的订单详情页1 3620 86kb
使用本样式方案的订单详情页2 6615
73kb

两订单详情页代码组织结构类似,因此将它们进行横向对比。未采用本样式方案的订单详情页 1 的样式编码字符数为 3620,打包后实际 Size 为 86kb。若订单详情页 2 未使用本样式方案,打包前样式编码字符数为 6615,则预期打包后实际 Size 为 6615 / 3620 \* 86kb = 157kb,但订单详情页使用了本样式方案实际打包后为 73kb,相对于 157kb,缩减了 50% 左右的 Size。

以下为未使用本样式方案的订单详情页 1,该目录下样式文件包括了 50 个样式文件,共计 3620 个字符,最终打包出来的样式文件的 Size 为 86kb。

干货 | 瘦身50%-70%,携程 Taro 小程序样式 Size 缩减方案,taro,小程序,前端,html,css

干货 | 瘦身50%-70%,携程 Taro 小程序样式 Size 缩减方案,taro,小程序,前端,html,css

以下为使用了本样式方案的订单详情页 2,该目录下样式文件包括了 96 个样式文件,共计 6615 个字符,最终打包出来的样式文件 Size 为 73kb。

干货 | 瘦身50%-70%,携程 Taro 小程序样式 Size 缩减方案,taro,小程序,前端,html,css

干货 | 瘦身50%-70%,携程 Taro 小程序样式 Size 缩减方案,taro,小程序,前端,html,css

5.2 Size 缩减效果分析

以上两个实践效果,相较于项目中原样式写法方案,使用本方案后,主要从以下三个方面节省了 Size。

a. 本方案解决了样式冲突问题,编写样式代码时可以不再用父子选择器的方式来进行样式作用域隔离,减少了祖先选择器的冗余。如下使用了 sass 预处理器的样式代码所示,我们可以发现在最终编译生成的代码中, .box .item 冗余了三次,而且若继续在 .box .item 下每新增一个叶子节点 .item* , .box .item 都会冗余一次。因此项目中使用父子选择器这种方式来隔离作用域,会导致大量的祖先选择器冗余。

// 编译前代码
.box {
  .item {
  .item1 {}
  .item2 {}
  .item3 {}
  .item4 {}
  }
}
// 编译后代码
.box .item .item1 {}
.box .item .item2 {}
.box .item .item3 {}
.box .item .item4 {}

b. 将原 ClassName 直接缩短成更短的 ClassName,直接减少了字符数。这种方式较为直接,但优化效果有限。

c. 本方案尽可能拆分样式文件中仅类选择器的 CssRule,生成并复用 PropertyValue ClassName,尽可能减少了 PropertyValue 的重复冗余。虽然在 JS 文件中 ClassName 被替换成更短但更多的 PropertyValue ClassName,有一定的 Size 增加,如在实践效果 1 中,实践后 JS 文件有 2KB 的增长。但是相比于样式文件 Size 上的缩减效果可以忽略不计。

5.3 Size 增长分析

随着样式文件越多,采用本样式方案的项目,样式文件 Size 增长幅度将增长会越缓慢。本方案要求以仅类选择器的方式为主,少量场景使用其他选择器为辅的方式进行编写样式代码。随着项目中样式代码越来越多,仅类选择器 CssRule 经过本插件处理拆分生成的可复用的 PropertyValue CssRule 会越来越多。此时,在按要求新写仅类选择器 CssRule 使用到某个 PropertyValue 时,可复用的概率会更高。高概率的每一次复用都会节省一部分 Size,使得最终编译打包后生成的样式文件 Size 增长曲率逐渐放缓。

六、总结

针对 Taro 项目 React 框架小程序,本文介绍了一种新的样式解决方案,该方案被集成为一个 Taro 插件的形式,可以在在较少改变现有开发体验的条件下,缓解样式代码的冗余问题。

本样式方案学习借鉴了 cssModules 样式方案的语法规则以及原理,解决了样式冲突的问题,并且在此基础上从缩减 ClassName 长度和缩减 PropertyValue 两个方面实现了 Size 上的缩减,最终样式文件的瘦身效果可以达到 50%-70%。这有利缓解官方包 Size 的限制,便于业务的高速发展。

七、vscode 插件推荐

本方案基本语法跟 cssModules 一致,因此可以直接借助现有的 cssModules 插件,提升开发体验。

7.1 CSS-Modules-transform 插件

该插件支持让项目现有 JS 代码快速转成 cssModules 语法,将原类名使用方式,一键替换成本方案要求的类名使用语法,如 classname="a1" => className={styles.a1} 。需要注意的是,一键替换只支持非运行时的语法,运行时的语法还是需要手动替换。可以高效提高现有样式方案转化效率。

7.2 CSS Modules 插件

CSS Modules 插件支持自动补全和类型定义,提高开发体验。

八、文章参考

  • GitHub - css-modules/css-modules: Documentation about css-modules

  • cssModules插件 

【推荐阅读】

  • Flutter 地图在携程的最佳实践

  • 携程火车票iOS项目开发体验优化实践

  • 携程机票App KMM iOS工程配置实践

  • 携程机票跨端 Kotlin DSL 数据库框架 SQLlin

 “携程技术”公众号

  分享,交流,成长文章来源地址https://www.toymoban.com/news/detail-673355.html

到了这里,关于干货 | 瘦身50%-70%,携程 Taro 小程序样式 Size 缩减方案的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 干货 | 深度学习在携程搜索词义解析中的应用

    作者简介 携程旅游研发部大数据与AI研发团队,为旅游事业部提供丰富的AI技术产品和技术能力。 一、背景介绍 搜索是电商最重要的门面之一,大部分用户通过搜索来找到他们想要的商品,因此搜索是用户表达意图最直接的方式,也是转化率最高的流量来源之一。绝大部分的

    2024年02月06日
    浏览(41)
  • 干货 | 提前在开发阶段暴露代码问题,携程Alchemy代码质量平台

    作者简介 Lyan,携程资深后端开发工程师,负责自动化测试框架及平台类工具开发,关注Devops、研发效能领域。 一、背景 随着敏捷开发,DevOps开发模式的流行,代码质量分析作为研发质量保证体系的重要组成部分,不仅能有效的降低因频繁迭代带来的故障风险,而且对整个工

    2023年04月11日
    浏览(37)
  • 干货 | 携程客服机器人ASR引擎的负载均衡实践

    作者简介 玉修,携程技术专家,专注于电话音视频通信、智能客服机器人等领域。 一、前言 携程拥有庞大的呼叫中心,涉及上万客服人员,覆盖机票、酒店、火车票、度假等产线的售前售后业务,每天的电话业务量超百万通。近年来,通信技术、人工智能技术和智能终端等

    2024年02月03日
    浏览(39)
  • 干货 | 成本低误差小,携程基于 Kafka 的 Serverless 延迟队列的实践

    作者简介 Pin,关注 RPC、Service Mesh、Serverless 等云原生技术。 一、背景 随着上云项目的不断推进,大量的应用需要部署到 aws 上,其中有很多应用都依赖延迟队列的功能。而在 aws 上,我们选择以 Kafka 作为消息队列,但是 Kafka 本身不支持延迟队列,这就需要思考如何基于

    2024年02月13日
    浏览(45)
  • Taro+Vantui项目公共样式配置

    最近用Taro+Vantui从0-1开发向程序的项目,以下是我总结我在项目中遇到的问题 如何搭建一个项目,可以参开vantUI首页引导进行配置链接如下: https://antmjs.github.io/vantui/main/#/quickstart 样式配置, 2.1 项目目录 config-index.js 2.2.mini-webpackChain 代码如下

    2024年02月13日
    浏览(34)
  • 【CSS】CSS 文本样式 ① ( font 字体设置 | font-size 字号大小设置 | font-family 字体设置 | Unicode 编码字体名称 )

    在 CSS 中 , 字号大小 设置 语法如下 : 上述代码的含义是 , 将 HTML 页面所有的 p 标签字号都设置成 16 像素 ; font-size 属性值 的单位 推荐使用 px 像素 , 也可以使用下面的 长度单位 : px : 像素 , 强烈推荐使用 ; em : 相对 当前 对象文本 的大小 ; in : 英寸 , 绝对长度单位 ; cm : 厘米

    2024年02月02日
    浏览(54)
  • 微信小程序+Taro 混编,Taro 使用微信原生 behaviors

    最近有一个小程序项目,因为一些原因项目架构选择了微信小程序原生+Taro 混编的方式进行开发,在开发的过程中发现 Taro 不支持使用原生的 behaviors 特性,因为混编的原因项目当中已有原生页面在使用 behaviors,所以需要一个方案在不影响其他页面的基础上使 Taro 也能使用这

    2024年02月11日
    浏览(41)
  • taro之小程序持续集成

    Taro 小程序端构建后支持 CI(持续集成)的插件  @tarojs/plugin-mini-ci 。 目前已支持(企业)微信、京东、字节、支付宝、钉钉、百度小程序 功能包括: 构建完毕后自动唤起小程序开发者工具并打开项目 上传代码作为开发版并生成预览二维码 上传代码作为体验版并生成体验二

    2024年02月12日
    浏览(47)
  • taro小程序用户头像昵称获取

    微信发布《小程序用户头像昵称获取规则调整公告》之后,无法再使用 getUserProfile 获取用户头像和昵称,因此小程序官方提供了头像昵称填写功能来完善个人资料。 对button添加 open-type=\\\"chooseAvatar\\\" bind:chooseavatar=\\\"onChooseAvatar\\\" 获取头像 对input添加 type=\\\"nickname\\\" 获取昵称 新增一个

    2024年02月15日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包