上海品茶

您的当前位置:上海品茶 > 报告分类 > PDF报告下载

大淘宝技术:2022技术人的百宝黑皮书-阿里大淘宝技术2022技术年货(1276页).pdf

编号:112158 PDF 1276页 66.56MB 下载积分:VIP专享
下载报告请您先登录!

大淘宝技术:2022技术人的百宝黑皮书-阿里大淘宝技术2022技术年货(1276页).pdf

1、技术经典总结内存优化:纹理压缩技术移动域全链路可观测架构和关键技术性能优化之接口优化APM 页面加载耗时校准19条跨端cpp开发有效经验总结下一代响应式Web设计:组件驱动式Web设计Flutter 新一代图形渲染器 ImpellerHTTPS的原理浅析与本地开发实践无代码生产新模式探索HTTP3 RFC标准正式发布,QUIC会成为传输技术的新一代颠覆者吗?相关业务实践淘宝购物车5年客户端技术升级与沉淀淘宝长辈模式客户端技术实践万字总结打造淘宝极简包的轻量化框架CONTENTS目录第一部分年度精选技术栈内容02263209229终端技术篇我在淘宝做弹

2、窗,2022 年初的回顾与展望年度经典专题跨全端SDK技术演进跨桌面端Web容器演进跨桌面端之组件化实践服务端技术篇技术经典总结合理使用线程池以及线程变量mysql锁机制的再研究数据库存储选型经验总结开发规约的意义与细则如何避免写重复代码:善用抽象和组合MapStruct,降低无用代码的神器一个搞定责任链的注解stream的实用方法和注意事项响应式编程的复杂度和简化一种可灰度的接口迁移方案相关业务实践谈一谈凑单页的那些优雅系统设计大淘宝用户平台技术团队单元测试建设淘宝IOS扫一扫架构升级-设计模式的应用年度经典专题浅析设计模式3 装饰者模式浅析设计模式2 策略模式浅析设计模式1 工厂模式239

3、269284635637304424544804875055574590609676496636733DXR技术篇技术经典总结进入 WebXR 的世界虚拟数字人行业现状和技术研究 MNN2.0 发布移动端推理引擎到通用深度学习引擎相关业务实践3D技术在数字藏品中的应用 商品 3D 建模的视觉定位和前景分割方法 因果推断实战:淘宝 3D化价值分析小结数据算法篇技术经典总结因果推断:效应估计的常用方法及工具变量讨论倾向得分匹配(PSM)的原理以及应用 ODPS SQL优化总结 大淘宝技术数

4、据模型治理阶段性分享 SIGIR2022 流行度偏差如何利用?探索解耦域适应无偏召回模型相关业务实践多模态技术在淘宝主搜召回场景的探索 淘宝逛逛ODL模型优化总结 淘宝Push智能文案生成年度经典专题冷启动系统优化与内容潜力预估实践基于特征全埋点的精排ODL实践总结7337457537607677828498708788878999059841生成式重排在内容推荐中的应用实践无尽流场景优化总结音视频与图像技术篇技术经典总结CVPR2022|开源:基于间距自适应查找表的实时图像增强方法ACL2022|自监督文本表示新框架ArcCSE大淘宝技术斩获NTIRE视频增强和超分比赛

5、冠军(内含夺冠方案)短视频无尽流前端开发指南相关业务实践全景封面视频生成技术在淘宝的应用移动端人脸风格化技术的应用基于机器学习的带宽估计在淘宝直播中的探索与实践技术质量篇淘宝直播端到端音视频评测方案首次公开我在阿里做测试,入职5个月的回顾与总结前端质量之灰度监控的有效实践驱动页面性能优化的3个有效策略大淘宝技术2022资讯重点 第14个天猫双11,技术创新带来消费新体验淘宝自研标准化协议库XQUIC正式开源!上海交大牵手淘宝成立媒体计算实验室:推动视频超分等关键技术发展国际顶会OSDI首度收录淘宝系统论文,端云协同智能获大会主旨演讲推荐92697899399399393994695095996

6、9电商直播高画质开播指南正式发布,6步快速搭建一个高清直播间技术人的经验总结新手项目经理入坑指南前端架构师的一些思考和总结在阿里做前端程序员,我是这样规划的如何快速理解复杂业务,系统思考问题?关于程序员的职业操守,从匠艺整洁之道谈起技术人的金句系列“从幼稚到成熟,是从不负责任到承担责任的过程”|技术人金句系列终端技术篇项目:mobx项目:xstate项目:d3第二部分技术人生与学习成长系列第三部分GitHub上的推荐学习项目995995995995995995995996996996996996996996993993993993994994994994994994994项目:VScode项目

7、:ice项目:koajs项目:nextjs项目:vue-element-admin项目:Android studio项目:openstf项目:BetterCodable项目:SwiftDate项目:SwifterSwift项目:mirai Auto.js服务端技术篇项目:yolov3项目:CS-Notes项目:jeecg项目:rocketmq项目:Spring Framework项目:Apache VFS项目:spring-framework项目:Netty项目:nocalhost项目:istio项目:transmittable-thread-local项目:resilience4j项目:sp

8、ring项目:guava997997997997997997997998998999999999999999999999001000音视频技术篇项目:Urho3D项目:Cocos2dx项目:x265项目:HM项目:vlc、Ijkplayer、exoplayer项目:videojs项目:flvjs项目:transfer_learning_music项目:music-audio-tagging-at-scale-models数据与算法篇项目:FastText项目:Deep-photo-styletransfer项目:ranking项目:deepctr项目

9、:opencv项目:mmf项目:detectron2项目:openpose项目:chainer项目:pix2pixHD项目:stylegan项目:StyleGAN2项目:tensorflow项目:caffe0033100310053DXR技术篇项目:filament项目:cocos2d-x项目:taichi项目:glumpy项目:raytracing项目:计算几何库项目:Threejs项目:mmcv技术质量篇项目:pytorch-handbook项目:ChromeDriver项目:Jvm-Sandbox:项

10、目:skywalking项目:jacocoOSDI 2022Walle:An End-to-End,General-Purpose,and Large-Scale Production System for Device-Cloud Collaborative Machine Learning第四部分 2022大淘宝技术A类顶会论文精选61SIGKDD 2022SGGG:Self-adaption Generative Gating Graph model for Personalized Micro-video RecommendationTIP

11、2022Progressive Language-customized Visual Feature Learning for One-stage Visual GroundingACM MM 2022CoHOZ:Contrastive Multimodal Prompt Tuning for Hierarchical Open-set Zero-shot RecognitionACL 2022A Contrastive Framework for Learning Sentence Representations from Pairwise and Triple-wise Perspecti

12、ve in Angular SpaceCVPR 2022Ray Priors through Reprojection:Improving Neural Radiance Fields for Novel View ExtrapolationGEN-VLKT:Simplify Association and Enhance Interaction Understanding for HOI Detection 81211AdaInt:Learning Adaptive Intervals for 3D Lookup Tables on Real-time Image En

13、hancementSIGIR 2022User-Aware Multi-Interest Learning for Candidate Matching in RecommendersCo-training Disentangled Domain Adaptation Network for Leveraging Popularity Bias in RecommendersICIS 2022Short-Video Marketing in E-commerce:Analyzing and Predicting Consumer Response年度精选技术栈内容第一部分技术人的百宝黑皮书20

14、22版大淘宝技术出品01第一部分年度精选技术栈内容伴随着时代和商业的快速发展,天猫淘宝的底层技术基础设施得到了深厚的积累,同时也支撑了云计算的大规模发展。未来,大淘宝技术将通过持续的技术创新和突破,让商家更好的做生意,让用户享受更好买、好逛、好玩的线上体验。本篇章将分享我们基于淘宝等真实的消费场景,在终端技术、服务端技术、3DXR技术、算法技术等多个技术栈的实践经验,包含点点滴滴的细节技术改变,以及完完整整的技术解决方案,期望与大家真诚交流和共同进步,一起探讨未来技术与消费的新形态。101年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品内存优化:纹理压缩技术

15、作者:楚奕出品:大淘宝技术终端技术篇相比普通格式图片,纹理压缩可以节省大量显存和 CPU 解码时间,且对 GPU 友好。背景游戏开发中纹理是内存占用大户,移动设备因为内存有限,问题更加明显。据统计,淘宝互动小程序性能卡口 70%以上都是因为内存超标,而内存超标的主要原因则是图片素材过多、过大等。我们知道传统的图片文件格式有 PNG、JPEG 等,这种类型的图片格式无法直接被 GPU 读取,需要先经过 CPU 解码后再上传到 GPU 使用,解码后的数据以 RGB(A)形式存储,无压缩。推荐语:今年淘宝在终端技术上做了三个很重要的探索:一、前端和移动端在技术上开始融合,例如技术架构、工具体系的设计

16、上都进行了贯通设计。二、基于Web的研发模式+增强的跨平台容器/引擎+原子化能力的Native原生架构,使前端和移动端在业务迭代上具备同等交付能力,提升效率。三、前端技术深入到业务领域,打破过去局限于技术本身(多样性和深入度)的探索上,使技术能够真正给业务带来价值。期待这些尝试能够为终端领域带来新的变化。阿里巴巴资深技术专家 舒文推荐语:过去的一年里,淘宝用户时长及浏览深度增长对性能体验的诉求愈发强烈,业务加速创新对交付效率的要求提升,对既有有研发模式的挑战更大,都推动了淘宝终端技术体系不断演进。本篇重点分享在用户体验改善、研发效能破障、架构体系演进等方面的背后思考与创新实践,希望为大家带来一

17、定启发与帮助。阿里巴巴资深技术专家 弘禹201年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品而纹理压缩顾名思义是一种压缩的纹理格式,它通常会将纹理划分为固定大小的块(block)或者瓦片(tile),每个块单3简介WebGL扩展名格式ETC1WEBGL_compressed_-texture_etc1ETC1WEBGL_compressed_-texture_etc1ASTCPVRTCS3TCWEBGL_compressed_-texture_astcWEBGL_compressed_-texture_pvrtcWEBGL_compressed_-text

18、ure_s3tcASTC(Adaptive Scalable Texture Compression)是目前最强大的纹理压缩格式,由ARM&AMD研发。ASTC同样是基于block的压缩方式,但块的大小却较支持多种尺寸,比如从基本的4x4到12x12;每个块内的内容用128bits来进行存储,因而不同的块就对应着不同的压缩率;相比ETC,ASTC不要求长宽是2的幂次方。PVRTC(PowerVR Texture Compression),专为 PowerVR 图形核心系列设计,IOS平台都支持,它使用2张双线性放大的低分辨率图,根据精度和每个像素的权重,融合到一起来呈现纹理;PVRTC 2-b

19、pp把一个84的像素单元组压成一个64位的数据块,压缩效果比较差;PVRTC 4-bpp把一个44的像素单元组压成一个64位的数据块;PVRTC压缩要求图片的大小必需是正方形而且边长必需是2的幂次方。S3TC(S3 Texture Compression)基本思想是把4x4的像素块压缩成一个64或128位的数据块,有损压缩。S3TC算法有五种变化DXT1-DXT5,一般在桌面设备上面使用,详见wiki。ETC(Ericsson Texture Compression)是Khronos 开放标准,专利来自于瑞典爱立信公司,它在移动平台中广泛采用,是一种为感知质量设计的有损算法,它基于人眼对亮度而

20、不是色度更敏感这一事实,在每个block定义四种不同的亮度偏移,即四种不同的颜色可用,可以认为这些颜色就是一个局部调色板,ETC会把4x4的像素块压缩成一个64或128位的数据块。ETC有两种压缩格式:ETC1和ETC2。纹理长宽必须是2的幂次方;ETC1基本所有Android机型都支持,但是缺陷是不支持Alpha通道;ETC2是ETC1的扩展,向下兼容ETC1。支持Alpha,但是需要开启OpenGL ES 3.x。01年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品4压缩纹理素材生产如上所示,设计师产出png/jpeg等素材后,可以通过工具生成.ktx格

21、式的压缩纹理素材,随后就可以在项目中直接使用了。不同格式的压缩纹理生产工具也不一样(PVETextTool、Adreno Texture Tool、.),而为了在各个平台中都能使用,通常需要生成不同格式的压缩纹理,社区有一些工具做了二次封装,可以生成多种格式的压缩纹理,如texture-compressor等。KTX文件格式KTX(Khronos texture)是一种通用的纹理压缩存储格式,OpenGL(ES)、Vulkan等均支持,KTX文件中包含了纹理加载所需的所有参数及数据,比如format、type、宽高等等,更多信息见wiki。如下是一个ktx文件的内容:01年度精选技术栈内容终端

22、技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品5基于这个格式,可以实现KTX Loader,用于解析KTX资源,生成纹理(通常游戏引擎会自带)。如下所示,读取KTX文件到ArrayBuffer然后解析拿到元信息:/KhronosTextureContainerconstructor(arrayBuffer,facesExpected,baseOffset=0)this.arrayBuffer=arrayBuffer;this.baseOffset=baseOffset;/Test that it is a ktx formatted file,based on the firs

23、t 12 bytes,character representation is:/,K,T,X,1,1,r,n,x1A,n /0 xAB,0 x4B,0 x54,0 x58,0 x20,0 x31,0 x31,0 xBB,0 x0D,0 x0A,0 x1A,0 x0A const identifier=new Uint8Array(this.arrayBuffer,this.baseOffset,12);if(identifier0!=0 xAB|identifier1!=0 x4B|identifier2!=0 x54|identifier3!=0 x58|identifier4!=0 x20

24、|identifier5!=0 x31|identifier6!=0 x31|identifier7!=0 xBB|identifier8!=0 x0D|identifier9!=0 x0A|identifier10!=0 x1A|identifier11!=0 x0A)return;/load the reset of the header in native 32 bit uint const dataSize=Uint32Array.BYTES_PER_ELEMENT;const headerDataView=new DataView(this.arrayBuffer,this.base

25、Offset+12,13*dataSize);const endianness=headerDataView.getUint32(0,true);const littleEndian=endianness=0 x04030201;this.glType=headerDataView.getUint32(1*dataSize,littleEndian);/must be 0 for compressed texturesthis.glTypeSize=headerDataView.getUint32(2*dataSize,littleEndian);/must be 1 for compress

26、ed texturesthis.glFormat=headerDataView.getUint32(3*dataSize,littleEndian);/must be 0 for compressed texturesthis.glInternalFormat=headerDataView.getUint32(4*dataSize,littleEndian);/the value of arg passed to pressedTexImage2D(,x,)this.glBaseInternalFormat=headerDataView.getUint32(5*dataSize,littleE

27、ndian);/specify GL_RG-B,space after the header for meta-data6223242526272829303年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品6this.pixelWidth=headerDataView.getUint32(6*dataSize,littleEndian);/level 0 value of arg passed to pressedTexImage2D(,x,)this.pixelHeig

28、ht=headerDataView.getUint32(7*dataSize,littleEndian);/level 0 value of arg passed to pressedTexImage2D(,x,)this.pixelDepth=headerDataView.getUint32(8*dataSize,littleEndian);/level 0 value of arg passed to pressedTexImage3D(,x,)this.numberOfArrayElements=headerDataView.getUint32(9*dataSize,littleEndi

29、an);/used for texture arraysthis.numberOfFaces=headerDataView.getUint32(10*dataSize,littleEndian);/used for cubemap textures,should either be 1 or 6this.numberOfMipmapLevels=headerDataView.getUint32(11*dataSize,littleEndian);/number of levels;disregard possibility of 0 for compressed texturesthis.by

30、tesOfKeyValueData=headerDataView.getUint32(12*dataSize,littleEndian);/the amount of space after the header for meta-data .36373839404142434445var ext=gl.getExtension(WEBGL_compressed_texture_etc);var texture=gl.createTexture();gl.bindTexture(gl.TEXTURE_2D,texture);pressedTexImage2D(gl.TEXTURE_2D,0,e

31、xt.COMPRESSED_RGBA8_ETC2_EAC,512,512,0,textureData);12345601年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品7技术人的百宝黑皮书2022版大淘宝技术出品01年度精选技术栈内容终端技术篇/技术经典总结8结论:1.相比jpeg等图片格式,纹理压缩通常体积会更大,这会导致IO时间变长;2.不同格式的纹理压缩体积也不一样,压缩率高体积虽然降下来,但是素材质量会降低,使用时需要权衡;3.纹理压缩格式GZip压缩效果不明显;素材大小1024x1024:技术人的百宝黑皮书2022版大淘宝技术出品01年度精选技术栈

32、内容终端技术篇/技术经典总结9技术人的百宝黑皮书2022版大淘宝技术出品01年度精选技术栈内容终端技术篇/技术经典总结下载时间&内存测试机型:pixel4、iPhone11ProMax游戏引擎:pixi.js压缩纹理在小程序实际场景中的性能表现批量加载JPEG纹理内存增长情况1001年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品批量加载ASTC纹理内存增长情况不同纹理格式GPU上传时间结论:纹理压缩格式相比普通纹理内存优势巨大,可以减少50%以上内存占用,但与此同时,素材下载时间会延长;结论:纹理压缩格式GPU上传时间几乎可以忽略不记,相比普通纹理具有巨大

33、的优势,也可以抵消一部分压缩纹理下载的耗时;纹理上传GPU时间11小程序Canvas纹理压缩实现方案小程序下,我们是基于 OpenGL ES API 封装 WebGL API,纹理压缩也不例外,由于WebGL扩展中支持的纹理压缩格式在OpenGL ES中都有对应实现,比如 WEBGL_compressed_texture_astc扩展对应到GL的扩展名为 GL_KHR_texture_compression_astc_ldr等,因此只需要根据扩展名称映射到OpenGLES实现即可,比较简单,这里不再展开。总结纹理压缩在现代计算机图形中占据重要定位,现如今主流移动设备GPU都已支持纹理压缩,在实

34、际场景中可以充分利用此能力优化游戏应用以带来更好的用户体验。参考1.http:/sv-journal.org/2014-1/06/en/index.php?lang=en#82.https:/ -mobile-graphics-world/5.https:/ in无线到如今,集团移动技术发展十余年,历经几个关键阶段,第一阶段,解决大规模业务并发研发的痛点,定义了Atlas(容器化框架,提供组件解耦、动态性等支持)架构;第二阶段,建设ACCS(淘宝无线全双工、低延时、高安全的通道服务)长连双工加密网络能力,补齐端到端互 操作移动服务能力追赶行业;第三阶段,面向业务特性建设Weex、小程序等动态化

35、研发框架,移动技术进入动态化跨平台时期。中后期通过移动小组机制进行各BU拉通和能力共建。自此,移动基础设施基本成型,各个领域各自沉淀若干组做到能力复用,App基本形成上层业务、中间研发框架或容器、基础能力三层的架构。我们团队作为无线端侧基础设施的承建方,过去重点是负责集团移动端的基础能力建设,近年来,团队重点深入淘宝业务场景展开性能优化,通过体验优化项目横向剖析App架构和及相关调用链路,感受到集团App普遍存在如下共性问题:(图1 淘宝App架构挑战)13以上是从APP结构的角度对当前客户端在运维排查、度量监控、全链路优化等方面的不足进行的一些思考,也是我们后续的发力方向。可观测体系监控到可

36、观测性的演变可观测性是一套理念系统,没有对技术实现的具体要求,重点是通过引入该理念,将理念应用到我们的业务迭代和问题洞察中。传统的运维可能只能给我们带来最顶层的告警和异常的概况,当需要更深层次的错误信息定位的时候,往往会通过建群拉人,然后先通过人肉找寻问题的特征,甚至是某个模块的开发承担起分析各个模块的依赖关系等的工作,问题处理基本涉及3个角色以上(业务、测试、开发、架构、平台等)。01年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品运维排查效率低下:首先是监控阶段,多数问题无监控或者监控上报后的信息无法支撑更有效的分析,需要依赖日志进行问题排查;其次是没有

37、日志的问题,发生异常时并不会主动上传日志,需要手动捞取,用户不在线更是拉取不到日志;拉取到日志后,还会继续遇到日志读不懂的问题问题;跟服务端有关的链路,还会遇到服务端鹰眼日志只保存5分钟的问题,经过这样一轮下来,基本时间已经过去半天.端到端追踪不完整:一个完整的业务链路,流量会穿越端到端多层,以一次下单为例,通过客户端所触发的网络请求到达服务器之后,会经过若干客户端模块处理、触发N次后端应用调用以及历经移动网络的不稳定性,试想一下,这些调用中有哪些出问题会影响这次下单交易,有哪些步骤会拖慢整个处理流程、请求没返回不清楚是服务端问题还是网络问题,假如各调用全链路性能定义不清,意味着各层问题得不到

38、充分暴露,这些因素都是需要考虑的,加上端侧天然异步调用,导致各阶段度量和全链路打通存在重大挑战,目前现状就是客户端各层没有统一调用规范,并且缺乏拓扑结构,无法还原调用链路,导致端到端无法追踪。优化缺少统一口径:过去因为各研发框架性能口径自闭环,不管是客户端原生技术,还是跨平台技术都是面向技术视角统一采集通用的技术口径,这种情况会天然导致各业务实现和表现差异巨大,通俗说就是不接近用户体感,会导致线上的数据难以反应真实情况及优劣趋势,长久以来,淘宝的体验也一直在劣化,每年基本都要靠运动式方式来搞体验优化,无法常态化保持。移动Paas流程赋能成本:大量的SDK组件输出集团各BU后,基础能力嵌入到不同

39、的App宿主环境后,同样会遇到上面提到的几类问题,对各BU同学来说,基础设施更是黑盒,如果问题涉及到基础设施,排查过程更加艰辛,加上没有现有的工具可以自助诊断问题在哪,遇到问题只能过来咨询,各种拉群拉人,导致答疑成本居高不下。1401年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品相比传统的监控,可观测性能够通过结合数据,并且将数据有机联系在一起,产生更好的连接,帮助我们更好的观察系统的运行状况,快速定位和解决问题。监控告诉我们系统的哪些部分是工作的,而可观测性告诉我们那里为什么不工作了,下图2说明了两者之间的关系,监控侧重宏观大盘展现,而可观测性包含了传统

40、监控的范畴。从上图来看,核心还是观察各个模块以及关键调用和依赖等的输出,基于这些输出来判断整体的工作状态,业界通常会把这些关键点总结为Traces、Loggings、Metrics。可观测性关键数据(图2 监控和可观测的关系)(图3 可观测性关键数据)1501年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品结合Traces、Loggings、Metrics的定义和淘宝现有情况,做了一些解读:因此,我们需要围绕以上这些问题对移动技术领域全链路进行定义,并建立起相关领域级的分析能力和好的评价标准,才能更深刻的洞察移动端的问题所在,才能在问题排查和性能度量领域持续

41、服务好集团各App以及跨域的问题。全链路可观测性架构上述可观测体系理念在后端有一些实践落地,但回归到移动领域的特性和现状,有种种问题如下:Loggings(日志):基于现有TLOG(无线端到端日志系统)日志通道,展现的是App运行时产生的事件或者程序在执行的过程中间产生的一些日志,可以详细解释系统的运行状态,如页面跳转、请求日志、全局CPU、内存使用等信息,多数日志是没有实现串联的,现在引入结构化的调用链路日志后,日志在调用链场景结构化后其实可以转变为Trace,支撑单机排查。Metrics(指标):是聚合后的数值,偏宏观大盘使用,对于问题定位缺乏细节展示,一般有各种维度、指标,Metrics

42、数据量一般很大,需要针对场景做一些采样控制。Traces(追踪):是最标准的调用日志,除了定义了调用的父子关系外(一般通过TraceID、SpanID),一般还会定义操作的服务、方法、属性、状态、耗时等详细信息,通过Trace能够代替一部分Logs的功能,长期看通过Trace的聚合也能得到每个模块、方法的Metrics度量指标,但日志存储大,成本高。调用规范的问题:与云端的差异是端侧完全异步,异步API极其丰富,且没有统一调用规范。多技术域的问题:研发框架数量众多,能力对外黑盒,如何串联存在大量难以感知的成本。端云差异的问题:端侧的海量分布式设备,意味着可观测模式的挑战与服务端也有本质差异,l

43、ogging与metrics在服务端可以基于一套体系完全上报实现,但单机埋点和日志量差异极大,这也是端侧埋点系统和日志系统分离的原因,端侧则需要实现如何兼顾海量设备的单机问题排查和大数据下的指标趋势定义。端云关联的问题:端到端现实一直是割裂状态,以端侧为视角如何更好感知后端状态,如何做关联,如怎么持续推进serverRT(后端请求调用耗时)从IDC(互联网数据中心)到CDN覆盖,端侧全链路标识如何让后端也感知。1601年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品(图4 全链路可观测架构定义设想)数据层:定义指标规范和采集方案,基于Opentracing(

44、分布式跟踪规范)数据上报。领域层:围绕问题发现到问题定位、性能持续优化体系、技术升级沉淀几方面演进。平台层:沉淀集团&竞对视角的比对,结合线上线下指标,引入厂商视角,驱动App性能提升。业务层:全链路视角,打通端到端,除了客户端同学,还可以服务不同技术栈跨域的研发人员。回顾全链路可观测项目的目标,我们设定为“打造全链路可观测体系,改善性能并驱动业务体验改善,提升问题定位效率”,后续章节会重点讲解每一层的实践。移动端opentracing可观测架构全链路构成1701年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品(图5 端到端情况、详情场景分层图)场景定义:一

45、次用户操作为一个场景,如点击、滑动都是单独的场景,场景也可以是多个单个场景的组合。能力分层:不同场景,有业务类,框架类、容器类、请求类的调用,可以对每个领域进行分层。阶段定义:不同分层有各自的阶段。如框架类有4个本地阶段,而请求类可以包含后端服务端处理阶段。用户动线:一次动线由若干场景组成。单场景+单阶段的组合全链路单场景+若干分层+若干阶段组合的全链路若干场景+若干分层+若干阶段组合的全链路 .端到端现有链路长,端侧存在各类研发框架和能力,虽然后端调用链路明确,但从全链路视角看,并没有与端侧打通。以用户浏览详情动线为例,一次首屏打开,会触发奥创、MTOP(无线网关)、DX三个模块不同的调用时

46、序,不同的模块有各自的处理过程,不同阶段有不同的耗时和状态(成功、失败等);接着继续看滑动,可以看到模块的调用时序组合又不一样,因此不同场景下可以由若干要素随机组合,需要根据用户实际场景,划分若干维度来定义全链路:全链路,就是把复杂的大调用分解为有限个结构化的小调用,并且可以衍生出各种case:Falco-基于OpenTracing模型全链路为了支持Logs+Metrics+Tracing 行业标准,引入分布式调用规范opentracing协议,在上述的客户端架构上进行二次建模(后续简称为Falco)。OpenTracing 规范是 Falco 的模型基础,以下不再列举,完整可参考OpenTr

47、acing设计规范,https:/opentracing.io/docs/overview/。Falco定义了端侧领域的调用链追踪模型,主要表结构如下:1801年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品(图6 Falco数据表模型)(图7 Falco关键实现)span公共头:黄色部分,对应OpenTracing规范的Span基础属性。scene:对应OpenTracing的baggage部分,会从根span往下透传,存放业务场景,命名规则为业务标识_行为。比如详情首屏为ProductDetail_FirstScreen、详情刷新为ProductDeta

48、il_Refresh。layer:对应OpenTracing的Tags部分,定义了层的概念,目前划分为业务层、容器层和能力层。处理业务逻辑的模块归属业务层,命名为business;提供视图容器归属容器&框架层,如DX、Weex都是,命名为frame-workContainer;仅提供一个原子能力的模块,归属能力层,命名为ability,如mtop、picture,层可应用于对同层同能力的不同模块进行横向性能对比。stages:对应OpenTracing的Tags部分,表示一次模块调用包含的阶段。每一层基于领域模型划分了关键阶段,目的是让同层的不同模块具备一致的对比口径,如DX和TNode对比,

49、可以从预处理耗时、解析耗时、渲染耗时衡量彼此优劣。比如预处理阶段名为preProcessStart,也可以自定义。module:对应OpenTracing的Tags部分,更多的是逻辑模块。比如 DX、mtop、图片库、网络库。Logs:对应OpenTracing的Logs部分,日志仅记录到TLog,不输出到UT埋点。Falco-关键要点19技术人的百宝黑皮书2022版大淘宝技术出品01年度精选技术栈内容终端技术篇/技术经典总结(图8 Falco领域问题模型)端侧traceID:满足唯一性、生成快、可扩展、可读、长度短等原则生成。调用&还原抽象:由traceID和span多级序列号一路透传,明确

50、上下游关系。端到端串联:核心解决云端串联的问题,端侧ID透传到服务端,服务端存放和鹰眼ID的映射关系;接入层返回鹰眼ID,端侧全链路模型存在鹰眼ID,通过这样的双向映射关系,我们能知道一个未返回的请求究竟是因为在网络阶段没有成功、还是没有到达接入层、或者是业务服务没有返回,从而将耳熟能详、粗粒度的网络问题变得可定义和可解释分层度量:核心目的是让同层的不同模块具备一致的对比口径,支撑框架升级后的性能横向对比,思路为抽象客户端领域模型,如以框架类为例子,虽然框架不同,但一些关键调用和解析是一致的,因此可以抽象成为标准阶段,其它类似。结构化埋点:首先采用列式存储,利于大数据集的数据聚合操作和数据压缩

51、,减少数据量;其次,业务+场景+阶段沉淀到一张表中,方便关联查询。基于Falco的领域问题沉淀:包括复杂问题的关键定义、追踪问题的线索型日志、某些特殊诉求的埋点。所有领域问题的信息被结构化沉淀到Falco,领域技术开发者也可以基于沉淀的领域信息持续开展分析能力的建设,只有实现数据的有效性供给和领域性解释合一,才能定义和解决更深层次的问题。1.2.3.4.5.6.基于Falco的运维实践运维的范畴极为广泛,围绕问题发现、问题接手、定位分析、问题修复关键流程,从海量设备的指标观测、告警,到单机排查、日志分析等,大家都知道要这么做,里面每个流程都涉及很多能力的建设,但实际执行起来很难做,各方也不认可

52、,淘宝客户端一直以来存在指标准确性和日志拉取效率低下的问题。如APM性能指标为例,淘宝App过去很多指标不准,业务同学不认可,不能指导实际优化。本章节会从重点分享下淘宝App在指标准确性和日志拉取效率方面的相关优化实践。20技术人的百宝黑皮书2022版大淘宝技术出品01年度精选技术栈内容终端技术篇/技术经典总结(图9 问题扭转用户动线以及运维系统)宏观指标体系以端性能横向战役为契机,基于用户体感的体验,APM开启了相关升级工作,核心涉及启动、外链以及各业务场景下的可视可交互指标,如何做到让指标对应的终点更贴近用户体感,主要有以下一些工作:以启动为例,APM 在 校准后,包含了图片上屏等阶段后,

53、数据虽然上涨了,但更符合业务方诉求8060算法的升级:视觉有用的元素提取出来计算(如图片和文字),剔除用户不能感知的元素(空白控件、兜底图),如制定视图可视规范,满足图片库、鱼骨图等自定义控件打标H5领域:支持UC 页面元素可视可交互以及前端 JSTracker(事件埋点框架)回溯算法,与H5页面可视算法打通深入复杂的场景:制定自定义框架可视规范,打通 Flutter、TNode(动态化研发框架)并校准等各类研发框架,8060算法交由各研发框架来实现。外链领域:打通H5页面口径,重新定义外链离开等负向动作。21技术人的百宝黑皮书2022版大淘宝技术出品01年度精选技术栈内容终端技术篇/技术经典

54、总结(图10 校准后启动数据趋势)(图11 校准后外链前后口径数据对比)(图12 单机排查问题定位核心功能)单机排查体系对于问题排查,目前核心还是基于TLOG,本次仅围绕用户问题排查动线中日志上报、日志分析、定位诊断关键环节遇到的问题(无日志、日志看不懂、定位难等),介绍运维排查体系为提升问题定位效率做的努力。以外链为例,打通H5后,新口径也出现了上涨,但更符合体感基于此战役,已实现打通若干研发框架可视指标和校正工作。2201年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品提升日志上传成功率,从几个方面保障在排查问题时有日志供应过来,一是内置日志主动上传能力

55、,在核心场景或问题反馈多时机触发,提高日志触达率,如舆情反馈、新功能上线发生异常时;二对TLOG能力进行升级,涉及到分片策略、重试、日志治理等优化,解决以往用户反馈较多日志上传的时效问题;最后是收集各类异常信息,作为快照,通过MTOP链路旁路上报,辅助还原现场。提升日志的定位效率,首先对日志做分类,如区分出页面日志、全链路日志支持快速筛选过滤;接着是打通各个场景的全链路调用拓扑结构,目的是可以快速看出问题发生在哪个节点,以便快速分发处理;最后结构化错误、慢、UI卡等问题,原则是将领域问题的解释权交给领域,比如卡顿日志有几类,如APM冻帧、ANR、主线程卡顿等;业务类有请求失败、请求RT大于xx

56、时间、页面白屏等,通过各领域的能力 对接来提升问题的快速诊断定位能力。全链路追踪能力建设,鹰眼(分布式跟踪系统在阿里后端的实现)接入业务众多,日志量大,不可避免要做日志的采样,对于没有命中采样的调用,缓存只有5分钟,需要想办法在5分钟内通知鹰眼保持更久的时间。第一阶段,后端解析服务会解析出调用链的鹰眼ID,通知鹰眼服务存储对应的trace日志,成功通知后可以存3天;第二阶段感知网关发生异常,取出鹰眼ID,通知鹰眼存储将存储前置;第三阶段,类似场景追踪,获取核心场景的鹰眼trace日志,尝试放在摩天轮平台上存储。第一阶段已经上线,可以做到关联跳转鹰眼平台,一般从问题发生到排查都过了5分钟,因此成

57、功率不高,还需要结合2、3阶段进一步提升成功率,正在规划开发中。平台能力的建设,基于端侧全链路日志做解析,在可视化方面,通过结构化展示全链路日志内容,方便快速部分节点的异常;还有就是基于结构化日志,对全链路日志中的耗时异常、接口报错、数据大小异常等问题进行快速诊断。通过“全链路可视化”功能(图10),可以看到H5页面spanID为0.1的network状态为“失败”,导致页面打不开。通过“全链路诊断”耗时异常功能(图11),可以看到大量network耗时分布在2s、3s+,有的甚至8s+,network阶段发生在请求调用阶段(传输),与海外用户访问到阿里的CDN节点慢相关。以上是今年在运维做的

58、一些尝试,目的是希望可以通过技术升级,在排查领域用技术赋能代替流程赋能。下面接着继续给大家展示下淘宝的实践和集团其它app接入的效果。全链路运维实践淘宝卡顿问题排查内部同事反馈在海外用淘宝App,出现卡、部分页面打不开等现象,经过上诉排查过程,提取到TLOG日志后。23技术人的百宝黑皮书2022版大淘宝技术出品01年度精选技术栈内容终端技术篇/技术经典总结(图13 全链路可视化功能)(图14 全链路卡顿诊断功能)24(图15 饿了么全链路视图-冷启全链路)(图16 饿了么全链路视图-店铺全链路)01年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品饿了么主链路

59、接入冷启全链路店铺全链路25(图17 App性能指标体系)01年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品指标定义和规范:贴近用户的感受,围绕用户点击到内容呈现到滑动页面的操作动线来定义相关指标,重点采集页面打开、内容上屏、点击响应、滑动等技术场景,如内容展现有页面可视可交互、图片上屏指标,滑动有滑动帧率(手指)、冻帧等指标来衡量。指标度量方案:原则是不同领域的指标交由对应领域负责,以卡顿指标为例,可以是厂商的口径(苹果MetricK-it)、也可以是自建的口径(APM的主线程卡顿/ANR等)、还可以是不同业务域的自定义指标(场景全链路),如MTOP请求

60、失败、详情头图上屏等。指标组成:由线上集合指标和线下集合指标组成,基于线上和线下数据和相关规范,立足用户视角和竞对情况牵引APP体验优化。基于Falco的优化实践新指标体系现在重点介绍下我们怎么围绕Falco可观测模型,从端到端全链路视角构建线上性能基线,用数据驱动淘宝App体验持续改善,首先就是数据指标体系的构建,主要有如下几点:26(图18 APM相关指标定义方案)(图19 场景全链路-详情首屏定义)01年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品APM为例定义了滑动相关的指标如下:场景全链路为例某个具体业务下,对于用户的一次交互行为,从发起响应到结

61、束响应,从前端到服务端到客户端的完整调用链路,详情基于场景全链路下的详情首屏指标:还有其他等等.可以看到,整个数据体系是多元化的,后续整个性能体验数据会有一个标准的输出,敬请期待。27(图20 淘宝App全链路优化技术方案)01年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品数据拷贝多:现有网络层机制,网络库存在hook拦截处理,基于NSURLConnection+URL Loading System 转发到网络库进行网络传输,涉及多次数据拷贝,中转拦截处理非常耗时。线程切换多:线程模型过于复杂,完成一次请求频繁切换线程。异步转同步:原有请求使用一个队列 N

62、SOperationQueue 来处理任务,底层维护的这个队列把请求和响应绑在一起,使得发送之后要等待响应结果回来才会释放,HTTP Operation 占住完整的一个HTTP收发过程的全部IO,违背了网络请求的并行性,operation queue容易打满阻塞。新指标体系下的优化FY22 平台技术围绕全链路视角,以体验为出口,深入业务开展摸排优化,围绕指标定义并拆解问题域,面向用户真实体感开展各大专项优化。我们自底向上一一介绍,通用的网络层策略优化,如何围绕请求周期,从连通性-传输层-超时策略提升;面向用户体感的有技术策略升级,如网关和图片的优化;面向业务场景的技术改造,会场框架的预处理预加

63、载、安全保镖的轻量化实践,甚至是业务上的体验分级,如上海品茶信息流低端机下不启用端智能,下面会重点介绍相关实践。请求精简提速-极简调用实践以MTOP请求作为一个场景,链路主要涉及MTOP到网络库的交互,通过对全链路线程模型现状分析,从MTOP发起到网络层接收到会几点会导致请求慢:28(图21 线程模型优化前后-极简调用)(图22 极简调用AB优化幅度)01年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品简化线程模型:跳过系统URL Loading System hook机制,完成收发数据线程切换,减少线程切换。避免弱网阻塞:数据包Sending 与 Receiv

64、ing 拆分处理,空口长RT不影响 I/O 并发容量;汰换废弃API:升级老旧NSURLConnection 到直接调用 网络库API。以上几点问题,在大批量请求、系统资源竞争激烈场景下下(冷启动,几十个请求一拥而上),更为明显。改造方案,通过MTOP直接调用网络库接口来获得较大性能体验提升 数据效果:可以看到,在系统资源更为紧张环境下,如低端机上优化幅度更为明显。弱网策略优化-Android网络多通道实践在WIFI信号差、弱网环境下,有时候多次重试对成功率提升效果并不明显。系统提供了一种能力,允许设备在WIFI环境下将请求切换蜂窝网卡的能力。网络应用层可以利用该技术,减少请求的超时等一类错误

65、,提升请求的成功率。29(图23 Android多通道网络能力优化+用户合规授权)01年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品方案前提:当前Wi-Fi网络环境是否支持蜂窝网络。触发时机:当请求发出超过一定时间未返回数据后,触发切换蜂窝网络重试的请求,原先流程的请求不中断,使用优先返回的通道的请求响应,晚返回的会取消。时间控制:根据特定场景Orange配置,后续还需要灵活根据网络强弱来动态调整。产品形态&合规上:使用时给用户透出文案“正在同时使用WIFI和移动网络改善浏览体验,可在设置-通用里关闭”,弹出策略为 每次启动首次功能触发。在Android

66、21之后,系统提供了新的获取网络对象的方式,即使设备当前具有通过以太网的数据连接,应用程序也可以使用此方法来获取连接的蜂窝网络。所以,当用户设备同时存在WIFI和蜂窝网络的情况下,可以在特定策略下将不同请求同时调度到以太网和蜂窝网两个网卡通道上,实现网络加速。核心改动点:数据效果:在网络资源竞争剧烈的情况下,WiFi+蜂窝双通道网络场景下,长尾和超时率优化较为明显,AB数据,上海品茶API,P99/P999分位性能分别提升23%/63%,错误率减少1.19,上海品茶图片,P99/P999分位性能分别提升12%/58%,错误率减少0.41。30(图24 图片设备分级规则)01年度精选技术栈内容终端技术篇

67、/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品第一阶段,业务分级需要丰富的策略库和判断条件来实现分级,我们将在核心组件上沉淀这部分通用能力,帮助业务快速的实现业务分级能力。第二阶段,随着大量的业务都接入了分级能力,积累了大量的业务分级策略以及AB数据,那么可以去做单点业务分级策略的推荐&最优化,实现大量相似的业务可以快速复用,提升效率。技术策略分级-图片分级实践不同设备性能千差万别,业务的复杂度也越来越高,很多业务无法在低端设备上让用户体验到应有的效果,反而会带来卡顿等不良的体验。以往会通过“延迟、并发、预加载”等手段来优化性能,但只是规避了问题,核心链路仍然要要直面关键的调用耗时。

68、所以,我们需要对业务做体验分级,基于对业务流程的分级处理,让高端设备体验最完美复杂的流程,低端设备也能顺滑的使用核心功能,理想是期望实现 用户体验&业务核心指标 的双高,退一步来说,让部分功能有损(不影响核心业务指标)的情况下,让性能体验更佳,初步的设想是希望分2步走来实现:传统CDN适配规则会根据网络、view大小、系统等因素动态拼装获取最佳的图片尺寸来减少网络带宽、位图内存占用,提升设备图片加载体验,本次设备分级视角,并且会基于UED给出的规范,实现压缩参数可配置,扩展原有CDN适配规则,实现不同机型的图片分级策略,通过该能力,可以让图片的尺寸进一步缩小,加快图片上屏。31(图25 安全免

69、签架构变化)01年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品网关协议升级:协议升级支持免签,对外提供设置免签接口,若业务API设置免签,携带头到网络库。AMDC调度服务:稳定性考虑,目前短期会先通过AMDC(无线网络策略调度服务)调度到线上安全生产环境,因此AMDC调度模块会根据描述标识判断是否返回客户端免签vip,功能稳定性后,会灵活调度到线上主站环境。验签模块迁移:安全延签能力前置在AServer接入层,基于运维成本考虑,能力会从Aserver统一迁移到安全,后续Aserver不会有延签模块,安全会根据API/header特征 决定启用验签等功能。M

70、TOP免签错误重试:免签情况下,MTOP层遇到非法签名请求失败会触发降级老链路,保障用户体验。轻量化链路架构-安全免签实践外链拉端链路从启动到海关请求再到落地页加载(主请求仍是MTOP),涉及多次安全加签,加签属于CPU密集型任务,低端机长尾明显,拉端耗时过长会导致流量跳失,FY22 S1 在巨浪业务上,拉端链路做了很多性能优化,优化性能可以带来跳失率的降低,目前性能大头海关请求,海关请求安全加签耗时占比高,因此希望跳过安全加签,业务可以根据情况使用,提升进端的流量价值,链路涉及到MTOP、Aserver(统一接入层)、安全多方改造:3201年度精选技术栈内容终端技术篇/技术经典总结技术人的百

71、宝黑皮书2022版大淘宝技术出品总结&展望总结本文主要阐述了面对移动端现有挑战,如何通过实现调用链路Tracing、标准Logging及场景化追踪完成可观测能力的建设,并基于全链路视角和新可观测能力,打造全链路运维体系和性能持续优化体系,补齐移动端长久缺失的调用链追踪能力、解决复杂调用场景下问题的快速定位、改变过去拉群人肉排查的低效过程,开始了流程赋能到技术赋能的转变,并围绕该能力构建全链路Metrics指标,打造全链路性能指标体系,深入业务场景展开治理,升级平台技术能力,用数据驱动业务体验改善和体验的长效追踪。不足虽然淘宝App陆续在接入各类场景,但离15分钟内定位出问题还有不小的差距,相关

72、的卡点还较多,如日志上报成功率、服务端日志获取的有效性、问题定位效率的提升、接入源头的数据质量检验产品化&技术化、领域技术方对问题的认识和持续沉淀结构化信息,最后就是整个产品的用户体验,需要持续优化。展望延续阿里巴巴移动技术小组的移动原生技术理念,我们要做好技术做好体验,需深入移动域腹地,直面东西向多研发框架、南北向端到端全链路等领域挑战。18年体验优化一期,我们在请求领域就引入类似理念并开展尝试,直到如今寻求到合适的结构化理论基础,并通过立足移动端特性开展深入实践,持续做厚领域问题的定义和解决模型。希望打造出移动域可观测技术体系、形成架构沉淀。参考资料1.可观测性技术大会 https:/ h

73、ttps:/opentracing.io/docs/overview/3.万字破解云原生可观测性 https:/ APISIX https:/ 是什么 https:/ APM 分析报告 https:/ Relic APM https:/ https:/ 简析 https:/ https:/ 分布式追踪系统 https:/ Request:主要包括,鉴权、网络传输、服务端处理、Network SDK的数据处理等。3.Data Parse:业务上的数据解析,如json解析等的操作,以及线程间的切换等耗时。4.UI Refresh:主要是视图布局,渲染的操作。5.First Item Render:

74、第一张卡片的渲染时间。从上面数据上来看,客户端的耗时主要是:1.请求前的参数绑定过程2.请求后数据解析3.数据上屏的图层布局以及渲染4.异步请求过程中的线程不断切换造成切换耗时客户端上这些操作往往在整个链路上占比较小,且过程优化空间较小;然而大头往往在这两个方面:网络传输和服务端处理。方案降低ServerRT(服务端处理耗时)通常降低服务端处理耗时,是由服务端小伙伴来优化,当然优化过程中需要端上一起协助完成,大致了解一下服务端耗时的几种处理方案;主要有这几种方式:降低网络传输时间接口加缓存:合理设计临时缓存、持久缓存可以提高接口性能内部接口并发请求:通常一个复杂的接口需要调用下游几个业务的接口

75、,如果合理的进行并发请求,将会收到很好的效果异步化:如写日志,更新缓存等不会影响接口准确性的非核心流程,可以采用异步方式进行处理,不阻塞主计算逻辑处理数据批量处理:接口存在较大量计算,可以通过批量分批次(分而治之)方式来解决大量数据计算耗时问题sql加索引:数据库SQL是最常见的性能瓶颈,如SQL子查询、不合理索引设计、全表扫描、大量数据返回、大SQL等,通过监控平台查看慢查询SQL可立即找出影响接口性能瓶颈关键点1.2.3.4.5.3501年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品虽然现有阶段大多数用户网络已经很不错了,但是还是有很多场景下,网络耗时

76、占比还是非常高,尤其长尾数据中,网络耗时往往是最大的占比,所以网络耗时的优化依然是非常重要;当然端上的小伙伴在这个阶段可参与的空间也更多。主要有哪些方式呢?接口多段返回通常一个接口承载了较多的内容的话,其内容就会无限的进行膨胀,如果将埋点,日志,反馈等非主线的数据进行多段返回的话将会有很大的收益,此方案主要结合接口组成进行分析;当然,此方案改动量也比较大,成本也比较高。更换协议大多数我们接口使用的是TCP协议,相比来说如果更换UDP协议,接口返回速度会快不少,详细原因可以翻一下资料学习一下,这里不再多说。目前也已经有成熟的方案,比如阿里的XQUIC,有感兴趣的可以了解一下,具体的收益我这里也还

77、在测试中。缩小网络包为何缩小网络包会降低网络传输时间呢?客户端和服务端网络通信时数据传输过程如下图所示:3601年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品数据包越大,则在光纤传输时所需的时间就会越久,因此接收方等待数据包的时间也会更长,最终会导致应用层等待数据时间变长。还有,由于TCP采用的滑动窗口机制来提升传输性能,窗口的大小受接收端处理速率和网络拥塞情况影响,因此如果传输的包越小,则可以在尽量少的窗口周期完成数据的传输,减少响应的等待时间,反之,响应等待更长。从上面几个方式来看,业务客户端能够做的一部分其实是缩小网络包的大小,那么我们下面介绍一下缩

78、小网络包研究。收益缩小接口网络数据包方案与收益 缩小网络包,是否真的会对网络的传输有效果呢?我们对数据包的大小与网络传输时长做了一个线下的实验,以下是实验的数据:3701年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品其他条件不变,我们将一页返回数据改变后的数据;可以看出网络传输时间与数据包的大小是有着正相关的关系的。减少网络包大小有哪些措施呢?更优的压缩算法不同的压缩算法,压缩算法是不一样的:图片来源于网上大佬的图片但是,压缩算法的调整需要考虑方面很多,如果仅仅是网络时间的收益在很多场景下可能成本较高,暂未考虑。3801年度精选技术栈内容终端技术篇/技术经

79、典总结技术人的百宝黑皮书2022版大淘宝技术出品减少返回数据个数减少返回数据个数,服务端的同学已经在投入,但是遇到了一个问题,数据个数的减少就需要增加请求的次数,机器资源的成本就会升高,需要申请机器的资源;那就比较尴尬了,本身是优化,却让成本来买单。精简返回字段在原有的请求数据上通过精简字段,减少数据包的大小。这样既能降低数据包,成本又不增高。如何做呢?下面来研究一下。精简数据报文 做一个实验一个接口的分页接口数据包大小在1.5M左右,Server使用的是gzip(best模式)的压缩方式,我进行压缩后的大小为106KB左右。通常其他接口数据包大小压缩后普遍在10KB以下,所以可以看出分页接口

80、横向对比来看,数据包大小是非常严重的。这也是为什么会选择精简数据报文作为优化手段一大原因。分析精简数据报文需要根据业务的场景来看,我这里来举一个我这边实践的例子:从数据包上分析,业务A的数据占比59.8%,而且该业务数据元素字段重复率非常高,来看一下去除该业务后的数据包大小:从数据比对来看,不同的卡片有大约18处的不同,其占比:占比=1-(5350/17439)0.693那么,此时就有一个问题了,重复的数据,经过压缩后还会占包大小吗?所以我就用服务端的压缩方式对数据做了个压缩:原始数据1472672降低率精简后60758759.8%3901年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝

81、黑皮书2022版大淘宝技术出品压缩后降低率依然有46.9%。拿到这个结果后,如何做呢?数据查找表将重复的业务数据在第一页的数据中建立字段的查找表,然后通过端上进行合并操作,具体方式:原始数据1472672降低率精简后Gzip压缩7851695%精简后60758759.8%原始数据Gzip压缩14789290%数据表明,针对重复字段的精简,压缩后依然是有效的。4001年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品但是,与服务端的同学对方案时,发现请求的第一页数据放置查找表,服务端不容易实现,因为数据在下游。调整方案,将数据查找表改放置在每一页数据中,这样服务

82、端更改就非常少了,实现也比较简单。但是数据放在每一页,压缩后还会有收益吗?来看一下实验的结果:采用压缩方式:gzip的压缩方式压缩比:best模式(系统缺省值6)方案1:将负反馈数据查找表放在第一页数据中:优化前后:降低45KB降低率:1-61/106 42.2%方案2:将负反馈数据查找表放置于每一页数据的头部:优化前后:降低43KB降低率:1-63/106 40.5%实验发现,查找表的数据仅仅占用2KB,优化依然有效。4101年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品优化效果 精简报文在原有的数据包下,线下实验,精简字段会将数据包从106KB降低至6

83、3KB;线下的实验可以得到接近90ms的优化;缩小返回数据个数缩小接口返回数据的个数,从50个降低至20个,数据大小大约降低63KB,网络传输耗时减低107ms;结论1.数据包的大小对于接口的性能、响应以及失败率都有影响2.在一定场景下,数据中的重复字段对压缩后数据包依然有较大的影响。注:1.网络传输使用的是服务端的压缩包,所以大小要看压缩后的包大小2.精简报文有很多同学可能都试过,实现后发现收益很小,所以需要先衡量包的大小会不会对网络传输造成影响,如果仅仅是几KB的优化,从上面实验可以看出,基本收益不大,如果是上百KB,收益肯定是有的。团队介绍我们是大淘宝技术-用户产品技术,团队主要负责电商

84、核心基础链路业务和平台的研发,包含:手机淘宝上海品茶、信息流、NewDetail、商品详情、购物车、全域触达、分享购物车、消息平台等电商核心基础能力及创新型业务。这里有世界一流的技术产品,有超大的电商基础场景,有百亿级别的数据、有超过百万QPS的高并发流量,有丰富的业务场景,服务于10亿级的消费者,这里有巨大的挑战等着你的到来。4201年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品APM 页面加载耗时校准作者:千诺出品:大淘宝技术在最新的 APM 自动化页面加载耗时计算中,剔除了对用户页面加载体验无效的元素,聚焦页面加载体验中的核心元素,既给了业务相对的自由度

85、,又达到了一定的加载体感准确性。背景APM 的全称叫做 Application Performance Monitor,属于应用性能监控部分。在手淘的 APM 中有一项特殊的数据,叫做页面可视耗时,不同于业界常规的技术视角阐述数据,我们更倾向于从用户体验交互进行阐述。以 Activity 实现的页面为例,在页面加载过程中,用户关心的是从点击开始到最后页面完全呈现,直至用户可以进行交互的一个过程,而不是单纯 Activity 的 Lifecycle 耗时,更不是技术视角的一个阶段数据。更逼近用户体验的数据是我们在页面加载上的追求。接下来我将从淘宝 APM 如何从用户角度实现可视计算的历史进行介绍

86、,并深入详解淘宝对页面加载耗时校准所做一些努力与改变。从0到1:可视计算页面可视耗时可以拆解成起点与终点,起点争议相对较少,使用的是 Activity onCreate 时间、Fragment onFragmentPreAttached 时间以及页面跳转时间,下面主要针对可视终点进行讨论:为什么要引入可视计算?4301年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品在 APM 中,对于页面打开耗时统计,常见有三类:Lifecycle、首帧、自定义埋点。监控 Lifecycle 是 Android 天然的一套监控耗时的方案,奈何生命周期的耗时只是页面加载过程中

87、的一个阶段,具有一定的技术需求观测性,但是正如文章开头所言,它其实不是我们追求的用户体验上的页面加载时长。从 Android API 19 之后,Android 在系统 Log 中增加了 Display 的 Log 信息,它是 Activity 完成首帧的时间,可以看得出来,它也是 Google 比较重视的一个点,但它还是页面加载过程中的一个分阶段监控点,不是我们的目标结束点。除此之外,Google 还为我们提供了 reportFullyDrawn 接口,当业务认为渲染完成时进行调用。因为业务各自不一的实现往往导致首帧距离真正的页面加载完成有相当一段距离。当然不只是 Google 意识到这一点

88、,FaceBook 也在这方面使用上做了些有趣的尝试。reportFullyDrawn 接口与我们常说的业务埋点其实是一回事,这样的方式统计出来的数据是相对不错与精准的,但是仍会面临几个问题:业务埋点带来了标准的不统一每一个页面的实现都是不一样的,每一个业务方对自己的可视终点有不一样的定义。有的人认为页面第一张图片出来了就是可视,有些人认为页面数据请求回来了就是可视,有些人认为第一帧上屏就是可视,一千个人心中有一千个哈姆雷特,这也导致埋出来的数据往往千差万别,甚至会出现肉眼看见更慢的页面数据更好的情况。4401年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品

89、框架复杂,在现有基础上改动成本有些过高当前淘宝上海品茶会有 N 多个模版,并且模版间还存在组合关系。淘宝上海品茶是根据模版下发进行渲染数据,如果说对模版改造有些不太现实。同时,现阶段的淘宝,业界中能见到的跨端框架,在淘宝都能看到影子,让所有框架改造一个统一的可视标准,让所有业务方手动打入可视时间有一些不切实际。业务与框架侧都不具有全局视角,导致埋点不准确往往业务方将数据请求回来交给容器渲染时就认为可视了,可却忽略了容器处理数据需要时间,数据上屏需要时间,容器将图片 URL 交给图片库进行加载亦需要时间。对于业务方而言,上诉耗时,对他是透明并不感知的,对于框架而言,只是进行一次渲染,并不知是页面加载还是

90、刷新页面。基于上诉问题,我们将解决方案放在业务无入侵、统一可视终点标准上,并最终提出了 8060 算法。可视算法初步实现8060 可视算法规则很简单,主要是将屏幕范围内的 View,对 X、Y 轴进行投影,当覆盖 X 轴长度的 80%、Y 轴的 60%就认为是可视。4501年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品为了将可视计算性能进一步提升,我们决定异步计算可视终点。异步计算可视是 APM 中比较巧妙的实现,因为可视算法涉及到 UI,Android 开发同学都知道,对 UI 的操作不是必须在主线程中实现,只需要保证操作的线程和 UI 的创建线程保持一

91、致即可,那么 Activity 界面的 UI 正常情况下都是在主线程创建的,这是否意味着可视算法只能在主线程中执行呢?答案显然是不一定。其实 Android 系统需要保证的是 UI 的状态,通过对线程的保护,可以很好的保证 UI 状态的一致性。如果多线程对 UI 进行写操作,那么会导致 UI 的状态被破坏;但是如果是多线程读操作呢,多线程读 UI 的状态并不会破坏 UI 的状态,只会导致一个问题,即在读的过程中读到一个不稳定的状态,导致程序异常,比如说 NPE,APM 在尝试异步 UI 可视算法的起初,就遇到了 NPE 的一些问题。不过这到不是一个很严重的问题,因为当你读到了一个不稳定的状态时

92、,恰恰说明 UI 的状态还不稳定,意味着 UI 在变化。抛弃本次计算,重新开始计算,直到有一次完整的页面计算。这个算法其实来源于读写锁的设计思路,如果读不会导致数据变化,那么在 UI 线程在读操作的时候异步线程也可以同时的读 UI,并不会对 UI 的状态导致破坏,程序依旧能正常运行。异步线程只需要保护好自己的运行状态,能正确处理一些异常即可。可视算法初步演变算法就此而止步了吗?其实并没有,我们认识到元素是有差异的,不能同一标准而视之,同时我们在计算方式也在做新的尝试。在手淘中,又孵化出另一种计算方式:将所有合格 View 的面积累加起来,计算出来的面积占整个屏幕的面积占比就是加载比率,当加载比

93、率超过 80%,就认为页面可视了。4601年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品针对 View 不再是无差别计算,我们有了更细的规则:View 在全部或者部分在屏幕范围内,且 Visibility 必须为 View.VISIBLE只针对 View 进行计算,ViewGroup 不在计算范围之列,且不是 ViewStub如果是 ImageView,Drawable 必须为 BitmapDrawable、NinePatchDrawable、AnimationDrawable、PictureDrawable如果是 TextView,必须要有文字如果是 E

94、ditText,判断是否已经聚焦,如果聚焦,整个页面直接加载完成其他 View 默认加载完成1.2.3.4.5.6.4701年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品为了更为接近用户体验,我们决定对所有核心链路上的页面加载耗时进行校准(这里的用户体验终点即页面呈现完成)。其中心是对页面视图的理解:什么样的视图是用户关心的?什么视图是影响用户体感加载耗时的?从这个角度上,校准的核心动作就呼之欲出了:提取视觉有用的有效元素出来计算,剔除用户不能感知的无效元素。算法的迭代算法的迭代主要内容是解决在计算时,提取视觉有用的有效元素和剔除用户不能感知的无效元素问题

95、。何为有效元素?我们认为在一个页面上,最重要的是上面展示给用户的图文信息,除此之外,就是外加的一些操作元素,主要包括按钮和输入元素。当这些元素出现并占满屏幕大部分的时候,我们就可以认为,我们内容已经完整呈现给用户了。从1到2:Native页面校准经过 APM 前期的发展,基础的页面加载耗时已经有了,但是准确性上还有待提高。4801年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品通过观察发现,我们还发现页面上很多元素并不是一直是无效或者有效的,比如说常规页面需要上屏的一张图片,图片库需要先加载默认图,等到图片库网络请求完成后才上屏,只有上屏了的图片才是有效元素

96、,这一部分可以跟标准图片库打通,并在手淘中自定义图片库中推行 APM 标准即可(少数)。除此之外的元素,我们都将其默认视作无效元素,之前的算法,全部认为是有效的,所以才会导致可视终点过于靠前。例如在手淘上海品茶,下发的模版中会产生大量无效控件,例如透明控件、底色控件。将不能识别的元素默认视作无效这一举动无疑会将计算的成功率拉低,但是会提高我们数据的准确性。同时基于双端能力对齐的想法,并没有在 View 面积之和的计算上进行修改,而是基于X、Y 轴投影的算法上进行修正:将所有的合格有效 View 对 XY 轴分别进行投影,同时将有无效标记的 View 对 XY 轴分别进行投影,当合格的投影减去无效

97、View 投影,分别覆盖 Y 轴的 80%,X 轴的 60%,那么页面加载完成。现在投影算法已经是 APM 里面的推荐算法。利用此算法进行上海品茶校准前后的终点对比图4901年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品支持 View 打标计算时候,会识别有效元素和无效元素的标记,这个标记是什么?在手淘中,哪些又做了这些标记呢?页面元素铺满屏幕不等于加载完成。我们发现很多页面为了追求更好的用户体验,会生成鱼骨图、页面打底图、图片打底图,同时页面为了追求更为完美的展示效果,自定义 View 也是页面上的常规操作。为了支持各种各样的 case,APM 采用 Vie

98、w tag 的方式进行解决,APM 中提供三个 tag 进行选择:在手淘中,需要打标的主要包括:鱼骨图、自定义图片库、自定义View(继承于 ImageView、TextView 不需要打标)。而这一部分需要打标的 View 出现频次较低,改动较少,故而在成本较低情况下,可以大大拉高准确度。这个变动毫无疑问是巨大的,也给 APM 在与业务低耦合的情况下,带来了更大的灵活性,例如,详情打开后会有一个全局遮罩的鱼骨图,对鱼骨图打标后,然后配合图片库打标,详情的页面加载准确性大幅提升/*当前状态是无效的View,但是仅仅表示当前状态,有可能变成有效,例如 ImageView*/String APM_

99、VIEW_VALID=valid_view;/*当前状态是有效的View*/String APM_VIEW_INVALID=invalid_view;/*需要完全忽略的无用 View,这个 View 完全是计算的噪点,例如鱼骨图*/String APM_VIEW_IGNORE=ignore_view;11125001年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品通过线下测试可以发现,详情的鱼骨图遮罩时间较长,在遮罩过程中会进行页面加载,如果不对鱼骨图进行打标,那么 APM 计算出来的加载时长与用户体感加载时长差距较大。下图是详情页面校

100、准前后的线上数据,我们可以发现 7 月到 8 月线上数据有一个非常明显的数据跃迁:通过给 View 打上是否合法的 tag,除了给 APM 带来了灵活性,也给业务带来了更大的自主性。对于高度复杂的业务来说,依旧存在自定义页面的结束时间的诉求,但是这种自定义结束时间并不是直接给 APM 塞一个时间戳,而是在自身页面加载逻辑完成之时,给 View 一个标记,标记此 View 完成了加载。例如,对于直播来说,他们需要的页面加载耗时,并不是直播页面的首帧,而是等待指定的直播小组件加载完成才算完成。如此高度定制的需求只需要做两步就可以完成:1.在创建 View 树的时候,在根 View 上打上非法标记2

101、.当直播小组件加载完成,将根 View 上的非法标记改成合法标记这是线上数据,APM 在校准上线后,发现更为符合业务方诉求与预期:设置页面加载阈值是否任意一个页面都适合同一加载阈值呢?答案当然不是的。5101年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品页面的布局、机型的适配直接影响着页面加载的比例,所以页面加载的上限在不同的页面中,也应该是不同的。在线下测试中发现,有些页面加载在某些手机上勉强了达到 80%的阈值,有些手机上一直达不到,造成大量数据计算不成功。基于以上考虑,APM 提供了设置单个页面加载阈值的口子,通过配合校准的各种改造,页面的加载时长准

102、确性大幅度提高,同时 Android 的计算成功率也飙升。errorCode=0 表示计算成功,由 12%上升到 78%自定义页面根 ViewAPM 计算的根结点默认是页面上的 DecorView,往下遍历的根结点是否是合理的呢?存在修改的可能吗?是存在的,自定义页面根 View 可以更细粒度的控制页面。对于页面的理解一定是 Activity 或者 Fragment 吗?不是的,我们既然讨论的时候用户体感加载时长,那么我们应该更多的从用户视角去考虑这件事情。例如,逛逛页面上有两个 tab,基于用户角度,我们更愿意理解成两个页面,推荐页面和关注页面。以逛逛关注页面为例,点击关注 tab 时候创建

103、了页面,整个关注页面也只是整个页面的一部分,下图为校准后的效果:5201年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品在 APM 中提出了 Page(页面)的概念,每一个 Page 有一个对应的 pageRootView,使用 pageRootView 来进行页面加载比率计算。当我们仔细去观察页面的 View 树结构时,还发现自定义页面根结点带来了更大的灵活性,对于异常 case 也有了更多的处理手段,这里举一个我们在校准过程中遇到的例子,逛逛上海品茶加载校准:逛逛的上海品茶是一个 Fragment,按道理说可以直接进行度量,但是在校准的时候发现:逛逛上海品茶(推荐)

104、有一个全局背景图。当尝试使用打标解决的时候才发现,逛逛业务定义了自身框架的 DSL,整个页面使用的是 DSL 进行编写(类 RN 原理),所有 ImageView 都是相同的 View,并没有任何特殊性,在端侧根本不感知这个背景图。这就意味着打无效标的办法不能用了。那么还有其他低成本的办法吗?当然有的,查看逛逛上海品茶的布局,发现全局背景图在整棵 View 树非常靠上的位置,与真正有效的 View 节点并没有关联,那么只需要将有效的子 View 树的根结点作为计算的起点就可以了。53注:在原始 APM 计算逻辑中,是使用整棵 View 树的根节点来进行向下遍历计算的01年度精选技术栈内容终端技术篇

105、/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品最后的方案:更换逛逛上海品茶的页面根结点(pageRootView)。下面是逛逛上海品茶的校准效果,如果没有进行校准,那么当背景图出现的时候就是页面加载的结束点,而且二刷也没完。通过打标解决了二刷问题,通过修正页面根 View 解决背景图问题,由于页面 ImageView 存在动画,所以加载完成后会有一个渐显的动画,当前 APM 认为这个渐显动画不影响可视点:5401年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品从1到2:H5 的标准在 H5 等场景下,WebView 的进度条并不一定代表真实的加载进度,导致

106、 APM 的页面加载无痕算法在 H5 场景下准度很差。为此,我们引入 JSTracker(前端框架层)进行计算,与此同时,在 Android 中,UC 内核自主计算的可视时间也被引入其中。UC 内核计算的可视时间原理又是什么呢?在页面加载的过程中,记录所有的渲染帧,在页面加载结束之后,回溯检查每一帧,图片渲染面积首次达到最大值的那一帧记为可视时间,而 JSTracker 计算原理类似,不同的是,JSTracker 是在前端框架层进行计算。5501年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品前端自定义终点除了 JsTracker/T2 的页面加载终点之外,

107、还有没有其他办法来体现自身业务的自定义页面加载终点呢?有的。APM 与前端框架定下了此规范。对于前端 H5 来说,如果需要自定义页面终点,首先需要通过一种方式告诉容器,自身是需要自定义终点的,告诉的方式就是:增加 APM 规定的 HEADER 标签。容器读取到了这个 HEADER 标签,表明当前 H5 页面遵守规范,需要自定义终点,将会通过 APM 提供的 JSBridge 提供页面加载的终点。此外,APM 也提供埋入参数和阶段数据的 JSBridge。在大促会场场景下,使用此方案支持了性能优化结果产出,其产出的结果中,除了页面可视之外,还包括秒开率,系统耗时,H5 容器框架耗时,前端耗时等指

108、标,结合 AB 产出对比数据结果,同时结合设备分级数据细化在不同手机等级下的数据。挑战:多容器内嵌页面在手淘中有各种各样的跨端容器框架,如 weex 等。存在一个页面上多种容器并存的情况,容器与容器之间,数据如何兼容,APM 提出了自身的仲裁方案。在店铺一个页面中,有可能存在多种框架混合使用的情况,举个例子,可以用 WebView 实现一个广告推荐,可以用 Weex 渲染出整个页面。如果每一个容器直接将自己的页面加载时间点通过一个接口直接打进来,APM 选取哪一个作为页面真正的加载结束时间戳呢?如果选取最小的时间戳,如果对应的 View 不是页面主要元素,那么这个值比体感加载时长小,如果选取最

109、大的时间戳,就有可能偏慢。其实在 Native 角度,每一个容器只是 View 树上的一个节点,APM 只需要关心这个子 View 是否加载完成,然后使用页面加载算法计算(8060算法),就可以知道整个页面是否加载完成。5601年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品那么问题就简化成如何知道这个子 View 是否加载完成。当前 APM 支持对 View 打标,当 View 没有加载完成的时候,就会打上没有加载完成的 tag,完成页面加载就会打上完成的 tag。由于容器知道自己的加载状态,就只需要在合适的时候,给自己的 View 打上合法的 tag 即

110、可。由于 APM 在遍历 View 树的时候,一旦发现 View 打上了 tag,就不再往下遍历,直接确定了当前 View 的状态,起到了数据仲裁的效果。写在最后对于 APM 页面加载耗时校准而言,目前 APM 还只是向前走了一小步。在最新的 APM 自动化页面加载耗时计算中,剔除了对用户页面加载体验无效的元素,聚焦页面加载体验中的核心元素,既给了业务相对的自由度,又达到了一定的加载体感准确性。团队介绍淘宝Android体验技术团队,以打造极致的移动用户体验为愿景,立志于研发体验相关技术、中间件,以及提供产品化解决方案,一站式为淘宝及其他移动应用核心场景体验赋能。团队在应用级优化有丰富的经验,

111、并深耕于系统级能力,目前已有多个成熟技术方案服务于大促会场,应用启动,外链拉端等,已建立全链路的线上性能监控体系,探索非确定性性能问题的监控及排查能力,我们长期招聘志同道合的伙伴,欢迎有志人士加入。5701年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品19条跨端cpp开发有效经验总结作者:鹿慕出品:大淘宝技术跨多端开发避坑指南前言细想,专门从事跨多端开发已两年有余,前段时间因为组里跨桌面端项目需要回归windows下开发了整整2个月,怎么形容这两个月呢,嘿嘿,各种“肆无忌惮”的写法,终于不用在写一行代码考虑后面n个端的行为了,劳动力、效率得到大幅度解放,但

112、是随着windows发版结束后,我负责mac的适配相关工作,在这个阶段,发现很多不合规的奇技淫巧(原定2个工作日的适配quota,大概进行了一周),作为一个略有想法的cpp程序员,遂产生了想写一个跨多端开发避坑指南的想法,想起过去看的Scott Meyers的Effective C+.努力写xx条有效使用cpp开发跨端的经验,期望看完此文可以帮助大家在如何保持同一份cpp代码在多个平台编译和构建上行为一致上有一丝丝帮助。跨多端开发下的复杂性,究其本质大多是因为两个原因引发的1.多系统下平台差异2.多编译器下行为不确定性下面主要讲解的也将从这两个方面入手。同时,在拜读了多份cpp程序员开发宝典里

113、,还是觉得 Google C+Style Guide是最有效的,最直接的避坑宝典,依旧推荐给大家:https:/google.github.io/styleguide/cppguide.html下面进入正文C+VERSION 的选择C+version选择可以说对于跨终端开发是至关重要的,跨端开发一个比较难的点在于多平台下,如何很好的支撑平台差异点,随着C+版本的升级,越来越多的新feature在标准库中得到支持,这也就是意味着开发者可以更少的关注平台差异点,因此这里建议选择最新的稳定版本,截止到目前推荐使用C+17.5801年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版

114、大淘宝技术出品禁止在一个单独的编译中重复包含文件的现象出现可以通过两种方式有效的避免此类情况1.#pragma once,需要特别注意 这是一个非标准但是被广泛支持的前置处理符号,在主流的编译中clang,ms等 均已支持。路径和头文件路径分隔符的问题在windows中路径的识别对于正反斜杠均支持,但是在linux中,只能是/,此外,在linux中对于路径是严格区分大小写的,对于windows则忽略大小写。建议:1.对于路径均需严格保证大小写与实际路径的匹配2.在代码中禁止对路径使用“”,请用“/”代替。此举,将在你从win到mac适配过程中,节省大量的工作量。C标准库的头文件包含在Windo

115、ws下某些C标准库的头文件不用显式包含,但是在linux下需要显式包含。因此在跨端开发中,应在.c和.cpp文件中尽量包含这个文件中需要的头文件,并且这也是C语言标准从C99以后的标准要求。2.使用#define的方式#pragma once#include.123#ifndef FOO_BAR_BAZ_H_#define FOO_BAR_BAZ_H_.#endif /FOO_BAR_BAZ_H_1234565901年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品代码文件格式在跨终端开发中,特别是包含中文的部分,除非你的代码都是英文注释,否则很难避免在多平台

116、下(特别是windows与类unix平台下的开发)交叉开发带来的中文乱码问题。建议:全部使用UTF-8 BOM编码格式。关于内联函数定义:当函数被声明为内联函数之后,编译器会将其内联展开,而不是按通常的函数调用机制进行调用。参考定义,自然他的优点,在函数体比较小的情况下,内联该函数可以令目标代码更高效,通常情况下,应该鼓励在函数比较短时使用内联。关于内联函数,或许很多非跨端程序员或认为不足为重,其实这里有几个非常值得在跨端开发被重视的问题:综上在跨端开发中因尽量避免使用内联,这里给出几个可以衡量的准则(经验值?):过度的内联,会导致程序臃肿,特别是对于移动端,一方面c+代码的体积问题一直不能很

117、好的得到解决,另一方面也会使得程序变慢。在导出头文件中非恰当的使用内联,会导致在跨模块开发中带来意向不到的结果。这里举个例子,在提供跨终端SDK时,通常会提供导出头文件,但是如果在导出头文件里不恰当的内联,将使得编译从当前单元跨越到另外一个模块,可能会引发一系列问题尽管编译器对内联函数都有或多或少优化,但是不同编译器不尽相同,实践下来良好的内联使用习惯依旧能帮助大家,譬如,我们在移动端的某个cpp项目中,通过去内联,减少了一定的包大小,实践证明编译器在择优选择的过程中不一定会完美契合。关于内联的编译器优化可以参考:https:/isocpp.org/wiki/faq/inline-functi

118、on1.2.3.行数超过10行禁止使用内联(google 建议)在非get函数里禁止使用内联(经验值,这一条争议会比较大,但在我看来只有在get某成员变量值时使用内联是有必要的,其他都没有必要且可能会带来“惊喜”)内联函数务必要有适当的修饰符(const)析构函数如果有自定义内容,禁止使用内联(google 建议,通常析构函数远比你想想的做的要多)1.2.3.4.6001年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品关于基础类型定义请使用基础类型定义,禁止使用自定义基础类型。看过团队的几个代码库,在基础类型的使用上有些同学甚至三方库也非常喜欢自定义,譬如C

119、HAR的定义char的定义需要显示是unsigned还是signed。需要注意的是,char在标准中不指定为signed或unsigned,不同的编译器可能会有不一样的结果,在发生隐式转换时可能会有超出期望的结果,譬如,char强转int时,发现在x86平台下是按照有符号处理的,但是在ARM32下被当成了无符号导致问题,ARM64正常有符号,当然你可以通过指定CFLAG+=fsigned-char 来解决,但是此类问题应当在规范时就被避免掉。关于宽字符的问题你需要知道的:在Windows中,wchar_t占两个字节,Linux中占四个字节,这里有几个问题1.导致体积占用大小不同。2.程序移植带

120、来困难3.隐式转换结果不符合预期在进行跨模块开发以及代码融合时,这些基础类型的自定义经常会出现歧义,redefine等等,或许你会说这样的定义应该要有自己的#define保护,但是大多数程序员不会这么做,这里强烈不建议自定义基础类型,标准库提供的已经足够简略和通用,请方便自己开发的时候同时照顾下团队同学。typedef std:int8_t int8;typedef std:int16_t int16;typedef std:int32_t int32;typedef std:int64_t int64;typedef std:uint8_t uint8;typedef std:uint16_

121、t uint16;typedef std:uint32_t uint32;typedef std:uint64_t uint64;01年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品跨端开发应避免wchar的普遍使用,以避免宽窄字符转换带来的开销以及额外的问题,应普遍使用utf-8作为主要的编码,这也是主流的思路。即时是特殊场景也可以用使用utf16,避免使用wchar。简而言之,除非必要,否则请不要使用。应该限定字符串数组在保存为字节流时,使用编码为uft-8请在字符串前加u8,特别是包含中文的部分,习惯在vs下开发的同学也需要额外注

122、意,vs默认的文件编码是gb2312,这会有概率导致字符串可能会不小心被保存为gbk编码格式。同时u8仅限在字符串前使用,在字符前使用是没有任何意义的,即时在ms上会编译通过,在clang下会提示避免连续两个尖括号的定义例如在Windows下这么写没问题,那么在某些平台下可能编译不过,提供两种方式:1.可以在连续两个尖括号符号之间留一个空格,即2.也可以typedefC+11标准里已经解决了此问题,如果确认编译器版本已经支持了这个特性(参考:https:/isocpp.org/wiki/-faq/cpp11-language-miscIn C+98 this is a syntax error

123、 because there is no space between the two s.C+11 recognizes such two s as a correct termination of two template argument lists.),此条可以忽略,但是通常两个的情况也意味着嵌套使用,typedef后通常阅读性也会得到提高。int pos=targetID.rfind(u8_);/error:use of undeclared identifier u8.1std:vectorstd:vector vec1std:vectorstd:vector vec;16201年度

124、精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品对于平台差异的代码部分处理跨端开发难免出现平台差异性代码,对于这部分的处理,对于简短的部分建议使用if def的方式区别,对于功能性的、代码较多的建议使用分文件开发,xxxx_win.cpp,xxxx_mac.cpp,xxxx_linux.cpp,可以参考chromium的代码在大量使用这种方式。同时对于差异性代码部分,应保持除非必要否则不定义的原则,因尽可能保持跨端的代码处理方式,过多的平台差异性将势必导致维护性变的很差。应避免使用非标准的编译器支持的关键词Assert的使用Assert在pc时代是作为一个广泛(

125、甚至是烂泛)使用的警告处理方式,在移动端以及类unix系统中,debug下表现通常会比windows更加猛烈些,通常是阻塞式的处理,特别是移动端会导致程序继续运行不下去,不像windows弹个框给你一个continue的选项。因此在跨端开发中应避免直接使用assert,可以考虑使用重定义后的assert,同时合情合理使用重定义后的assert。c+标准关键词参考:https:/ NDEBUG#define ALOG_ASSERT(_Expression)(void)0)#else#define ALOG_ASSERT(_Expression)do .这里可以额外做error级别日志输出,是否进

126、行assert阻塞式处理。if(HandleAssert()assert(_Expression);while(false)#endif116301年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品关于继承Composition is often more appropriate than inheritance.When using inheritance,make it public.google的这个定义应该还是非常准确的,通常组合比继承更合适,即时要使用也必须是publice的方式。应尽量保持“is a”的情况下使用继承,如果你想

127、使用私有继承,你应该替换成把基类的实例作为成员对象的方式。对于重载的虚函数或虚析构函数,使用 override,或(较不常用的)final 关键字显式地进行标记.在部分clang编译器下,编译器要求务必显示声明,否则会报错,ms则没有此类要求。关于Static变量感兴趣的小伙伴可以研究一下c+的特性“Dynamic Initialization and Destruction with Concurrency”,其中里面有定义静态、动态变量析构的顺序,线程生命周期的对象全部在静态变量之前析构,静态变量按照后构造的先析构的栈式顺序释放。实际在实践中发现apple的clang编译器和运行时库对c+

128、11的这个特性支持,未实现静态变量析构的多线程安全。因此在目前阶段,如果有用到全局静态变量时需要考虑到析构多线程安全的问题,否则线上在个别平台会发生crash。一个比较简单的思路:从全局静态变量替换为局部静态变量且不释放,直到进程被kill。这里还有一个变相的好处:把加载时机从load变成了此代码段真正运行时。eg:old:static std:recursive_mutex&m_mutex;new:static std:recursive_mutex&mutex()static std:recursive_mutex&mutex=*(new std:recursive_mutex();ret

129、urn mutex;01年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品关于模板模板的出现极大的方便了程序员,在未进入跨终端领域之前,虽了解它的一些诟病(代码膨胀&不合理的使用带来的性能损耗),也一直认为是一个非常棒的feature,随着移动端对包大小的要求越来越严格,模板的使用在跨终端上被限制,需要更为合理的使用,否则将膨胀的非常厉害。在漫长的去模板化过程中有些经验值可以输出,供大家参考。最后再插一嘴,模板对于使用者确实是极大的方便,但是在跨终端领域似乎对于模板的构建者有着更为严格的要求,需要着重考虑如何避免被膨胀,此外对于性能的要求

130、也更为严格,c+11里有不少提供模板性能的方式,&配合std:forward实现完美转发,等等,有兴趣的可以看下Effective Modern C+。以上也适用于 宏。关于编译器跨端开发势必要了解多种平台下的编译器,这里面主要代表是clang、ms(也成vs)、gcc等等,编译器的主要区别,这里不做主要的介绍了,可以去google下clang的前世今生,以及几种编译器的区别,和对应的使用平台。clang作为一款飞速发展的编译器,除了编译速度有飞速的提升外,错误提示也非常明确,这里强烈建议跨端开发者,如果有可能优先进行clang作为主要的默认编译器进行开发,良好的错误提示将提高极大的效率,同时

131、clang的代码检查将更为严格和规范,这也利于代码进行跨平台编译。在涉及到移动端的跨终端开发里,应尽量避免使用模板,除非它带来足够多的收益,比如json序列化,通篇用cjson的方式替换,从开发体验和代码膨胀比上来看,替换就显得不值得,比如自定义std标准容器,看似省了不少膨胀,但是代码的维护性和可读性降低了很多,同样不值得替换。尽可能选择小的模板编译单元,比如原来一个模板类,改为类里的模板函数通常情况下模板可以以各种方式被除去,这里不是说在裸写一遍模板换实参的方法。应尽可能的减少模板膨胀的速度,换句话说如果有可能应该尽量限制模板被特化的可能,譬如,我们的日志序列化,对于任意struct或者c

132、lass在实现了ToString()方法后均可以实现日志自动化输出,任意类型在进入到LOG_IMPL中都会生成一份具体类型的实体,经过略微改造后,限制需要被序列化的类型需要显示继承IOBJECT的接口类,改造后,在同样进入到LOG_IMPL中所有的类型只会有一份类型(IOBJECT*)实例化,此举在实践过程中大约减少了我们五分之一的包大小。在多重继承中,特别是公共模块基类如果包含模板,去模板的收益一般会比较大,因尽量限制基类中出现模板,除非必要,否则应以任何方式替换。1.2.3.4.5.6501年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品这里再再插一句,

133、之前在知乎上看过一篇文章对比各种编译器,在比较clang与gcc时,排在第一次位的不是我们通常说的编译速度和错误提示以及更小的编译产物(这些都是普遍知道的),是 license,gcc的GPL的限制让BSD许可下的以LLVM为代表的飞速发展,如果不是这个限制相信今天以LLVM为代表的的一系列编译器都是属于gcc。所以“做技术的同学不要以为技术牛就可以打天下,精准的市场地位有时候可以解决很多问题”,这句话说的还挺好的,与君共勉。关于转换层如果做跨模块开发,请坚守一个原则,转换层不要做任何业务代码逻辑以及特殊定向代码逻辑。转换层也成语言胶水层,是c+到oc,c+到java,以及其他,彼此相互语言转

134、换的代码层。通常wrapper坚守原则后,维护性会得到大幅度提升,专注于c+代码的即可,对于语言转换层,业界也有不少自动化转译的工具,诸如Djinni。结束在通往跨端开发的路上,我渐渐的从一个小白到逐渐羽翼丰满,除了要感谢团队给的机会外,非常感谢这一路上很多同学、特别是跨部们的同学帮助,感谢,比心另外团队目前也在搞基于跨桌面端的研发框架支撑相关工作,也会很快出炉,敬请期待。最后回归主题,跨端cpp开发闭坑指南远不止这些,欢迎一起补充添加。鸣谢。团队介绍我们是淘系技术部终端体验平台跨终端团队,业务上负责为千万级商家打造最高效的一站式工作台千牛,为淘宝上亿商家和消费者提供稳定高效的端到端消息IM服

135、务;技术上深耕C+跨终端及PC桌面端技术(Win-dows&Mac),为商家,消费者提供稳定,可靠,高效的客户端产品。欢迎志同道合的小伙伴,毛遂自荐,团队欢迎你,简历投递邮箱:wdw159603alibaba-6601年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品下一代响应式Web设计:组件驱动式Web设计作者:大貘出品:大淘宝技术自从著名设计师 Ethan Marcotte(beep)在 A List Apart上发表了一篇名为 Responsive Web Design的文章之后,响应式网页设计(RWD,即 Responsive Web Design)

136、的身影就出现在了公众面前。自此就有了响应式 Web 设计这个概念。从提出这个概念到今天已经有十多年的时间了。在这十多年来,CSS 也发生了巨大的变化,新增了很多新的特性,近两年尤其如此,近两年尤其如此(详细请参阅2022 年的 CSS一文)。这些变化,对于响应式Web设计的开发也有较大的改变。Una Kravets(Una)大神,在2021的Google I/O 大会上的分享,提出 新的响应式:组件驱动式 Web 设计。Web 生态即将进入响应式 Web 设计的新时代,并转变我们对其含义的看法,也为会Web设计带来新的变化。组件式驱动 Web 设计(或开发)也被称为是下一代响应式 Web 设计

137、(或开发)。如果你对这方面话题感兴趣的话,请继续往下阅读。文章链接:响应式Web设计的发展历程既然要聊响应式Web设计,那么我们就花一点篇幅和时间简单地了解一下其发展历程。众所周知,自从 Tim Berners-Lee 创建第一个 Web页面(大约在1991年8月份左右)到90年代末,Web页面都是非常简陋的:Responsive Web Design(地址:https:/ 年的 CSS(地址:https:/ CSS 的到来才慢慢地有了美感,Web页面看起来开始像我们今天使用的网站:正如上图所示,越往后,Web 的 UI 越来越丰富,越来越漂亮。这也让 Web 开发人员不得不在布局、设计和排版

138、等方面花费更多的时间。虽然 Web 开发人员为 Web 布局花费不少时间,但在这个过程中,也积累了很多不同的布局方法。在早期,Web 开发人员主要采用 固定宽度 和 流式布局 两种布局方案来实现 Web 页面的布局。特别是流式布局,自 Glenn Davis提出和推广之后,可谓是轰动一时,并且长期以来,都认为流式布局就是响应式Web布局。流式布局(Liquid Layout)可以调整Web页面尺寸以适应不同的显示器分辨率或浏览器窗口的大小。来看一个流式布局的简单示例:Liquid Page Layout Example?nickpettit?CodePen(地址:https:/codepen.

139、io/nickpettit/pen/dyZwVg)(地址:https:/codepen.io/nickpettit)(地址:https:/codepen.io/)6801年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品但流式布局并不是完美的。使用流式布局的Web页面上,内容可能会溢出,在较小的屏幕上文字可能会换行,在较大的屏幕上可能会有很多不必的空白。大多数流体布局在 800px x 600px到 1280px宽或更大的屏幕分辨率下看起来还不错。然而,如果我们能把它分割得更细一些,比如为 800px 1024px、1024px 1280px以及1280px以

140、上的分辨率提供不同的定制布局,那效果会更佳。同样,对于 640px 800px、320px 640px、240px 320px 以及 240px 以下的分辨率也可以定制不同的布局。大约在 2004 年的时候,Cameron Adams(themaninblue)(地址:https:/codepen.io/)在他的博文Resolution dependent layout(地址:https:/ 标签上title属性的值分别为 narrow、default 和 wide,并且在 dynamiclayout.js中有一个 DynamicLayout()函数,将会根据 标签的title属性的值来调用不

141、同的样式表:Kevin Hale 的博文 Dynamic Resolution Dependent Layouts详细介绍该技术。这种布局技术后来就以 Cameron Adams 博客文章标题命名,被称为 分辨率相关的布局。这种布局技术虽然会额外增加开发者(开发者需要为不同定制的布局提供不同样式表)工作量,但在CSS媒体查询流行之前还是很受欢迎的。它也被称为是早期的 CSS 媒体查询(通过JavaScript查询断点)。虽然这种依赖动态分辩率布局的方案可以在不同的分辨率下提供更佳的体验,但随着 2005年08月10日 Opera 软件公司推出Opera Mini(地址:https:/www.w

142、ebdesignmuseum.org/web-design-history/op-era-mini-2005)和 2007年01月09是第一台 iPhone(地址:https:/www.webdesignmuse-um.org/web-design-history/steve-jobs-introduced-the-first-iphone-2007)手机的出现,市场上不同品牌,不同分辨率的移动端以及品牌商自己的Web浏览器就越来越多。function dynamicLayout()var browserWidth=getBrowserWidth();/Narrow CSS rules if(

143、browserWidth=640)&(browserWidth 960)changeLayout(wide);67001年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品在这种环境之下,基于动态分辨率加载不同的样式表已不太现实,Web开发者不得不想出其他的方案来适应不同的屏幕尺寸。在很长一段时间,甚至到今日,为了适应不同屏幕的尺寸适配,为移动端单独创建一个网站,即 移动子域名网站。比如 Facebook的桌面版本和移动端版本,采用两个不同的域名来访问:如此一来,开发人员要开发两个版本,相应的工作量就更大了,特别对于要

144、快速响应和试错的Web应用来说,难度变得更大。Web开发人员为了能改善这种现象,在 2010 年的时候,Ethan Marcotte(beep)基于 John Allsopp(johnallsopp)的 网页设计的道(A Dao of Web Design)(地址:https:/ Web Design)(地址:https:/ Web Design,简称 RWD)的身影就出现在了公众面前。Ethan Marcotte(beep)在Responsive Web Design(地址:https:/ 流体网格(Fluid Grids)、灵活的图片(Flexible Imag-es)和媒体查询(Medi

145、a Queries)三种技术来构建一个响应式Web网站或Web应用。另外,Ethan Marcotte(beep)构建了第一个具有响应式的Web网页,可以说是响应式Web设计经典案例之一(只可惜现在打不开了):7101年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品那通过这个示例,大家对响应式Web设计是什么样的有了一个初步的了解了。其实,Ethan Marcotte 在他的文章中就提到:未来我们应该这样,随着访问网页的设备增加我们不会为每个设备单独设计,而只会做一份设计,把每个设备作为这份设计要照顾的一个方面。也就是说,每个设备上都会去追求最佳的用户体验,

146、设计会自动适应各个设备。在过去的时代,设计师精确的知道自己的媒介材质,比如一张 A4 纸张,一个名片,或者一张海报。但是在我们这个多屏时代,Web 设计必须有这样的思维,我们要为“任意尺寸”而去设计。自 Ethan Marcotte 提出响应式Web设计思路以及基于不同断点(CSS 媒体查询替代JavaScript查询设备屏幕分辨)实现不同终端设备屏幕分辨率布局已有十多年了。大家都说,每十年就会看到一个生态系统迅速的发展,其中 CSS 也不另外。尤其是这两年,CSS 新增了很多新的特性,比如大家最为期待的容器查询特性container、级联分层layer 以及 CSS作用域 scope 等。正

147、如 Una Kravets(Una)在2021的Google I/O 大会上的分享(地址:https:/io.google/2021/ses-sion/a1760fa3-879a-4e98-a616-994ca8d3aab5/?lng=zh-CN)所说:随着用户偏好查询、容器查询以及其他设备类型查询的出现(CSS新特性),Web社区即将进入响应式 Web 设计的新时代,并改变我们对其含义的看法。换句话说,下一代响应式Web设计即将到来,或者说已经来到了我们身边。响应式Web设计的现状在聊一下代响应式Web设计之前,我们就要对响应式Web设计的现状有所了解。我们分别从两种不同角色(Web设计师和

148、Web开发者)的角度来看响应式 Web 设计的现状。先从 Web 设计师的角色来聊。时至今日,虽然已是移动终端的天下,但如果要给不同终端提供设计稿的话,Web 设计师还是会依旧为不同的设备终端提供不同的设计稿。比如,为不同的设备视窗尺寸(如手机,平板和桌面端)提供不同的设计稿:7201年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品在上图中,设计师为卡片(Card)提供了三种不同的 UI 效果。虽然卡片在不同设备视窗下有着不同的UI效果,但他们构成的元素是相同,都有卡片容器、卡片缩略图、卡片标题 和 卡片描述等:我们来看下简化后的不同版本的设计线框图,如下所

149、示:7301年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品作为Web设计师,你已经使用了多个版本的布局来展示同一个组件三种不同状态下的UI变化。可以说把足够多的信息传递给了Web开发者!到这一步,Web 设计师已给 Web 开发者提供了具有响应式的Web设计稿。接下来,再从另一种角色(Web开发者)来看响应式Web设计的现状。对于 Web 开发者而言,要实现上图中三种状态下的卡片UI效果非常简单。借助 CSS 媒体查询特性,在不同断点下调整CSS样式规则即可:这种方式只能适合于同一组件独立存在于不同版本下。就示例的设计稿来看,在桌面端有两种效果的卡片,为了

150、满足该设计效果,我们需要额外添加一些类名,在不同状态下为卡片处理不同的UI效果:/*Mobile First*/.card display:flex;flex-wrap:wrap;gap:10px;/*Tablet*/media(min-width:700px).card gap:20px /*Laptop and Desktop*/media(min-width:1024px).card position:relative .card_thumb position:absolute;inset:0;62232425267401

151、年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品CSS样式代码可能会是像下面这样:/*Mobile First*/.card display:flex;flex-wrap:wrap;gap:10px;/*Tablet*/media(min-width:700px).card-vertical gap:20px /*Laptop and Desktop*/media(min-width:1024px).card-featured position:relative .card-featured.card_thumb position:absolute;inse

152、t:0;62232425267501年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品看上去是不错,但问题是,只有当视窗宽度大于一个特定的值时(常指的分辨率断点值),相应的组件变体才会生效,比如当视窗宽度大于700px时,.card-vertical卡片UI效果才生效;当视窗宽度大于1024px时,.card-featured卡片UI效果才生效。换句话说,如果要在平板端看到.card-featured卡片效果就无法看到,因为它的媒体查询在 1024px 或更大的视窗宽度下才会生效。不仅如此,We

153、b的内容是动态的,有的时候输出的内容可能和设计预定的卡片数量不相符合,那么在这种情况之下,要么会有一个空的空间,要么卡片会扩展以填补容器的剩余(或可用)空间。比如我们这个示例中,在视窗宽度为 700px 或更大的视窗宽度中,.card-vertical 和.card-featured 都有可能出现这样的场景。针对这样的场景,Web设计师可能更希望有额外的UI效果给卡片。这部分我们放到下一节来聊。简单地说,目前的响应式 Web 设计主要方案还是利用 CSS 媒体查询特性在不同的终端上提供布局的切换。虽然他能满足 Web 页面布局大部分场景,但也相对丧失了一些其他能力,比如说将响应式的样式注入到组

154、件本身的能力。换句话说,基于视窗宽度查询构建的响应式Web页面,尤其是响应式组件,其能力是有限的。7601年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品CSS 媒体查询的不足在上一节中我们一起探讨了 Web 开发者可以借助于 CSS 媒体查询特性来查询视窗宽度(或设备其他特性)为 Web 页面在不同终端提供差异化的布局。但也暴露出很多不足之处,甚至是明显的能力不足。就拿前面示例来说,卡片组件有三种差异化的UI效果,这些差异化的UI效果是取决于浏览器视窗宽度,也就意味着卡片组件不能根据其父容器宽度去调整 UI 风格。这就限制了开发者 只能在视窗宽度大于某个特

155、定值时(断点)使用一个组件的特定样式。例如视窗宽度到达 700px 或大于700px时,卡片组件从默认的.card(水平)状态切换到垂直(.card-verti-cal)状态。也就是说,如果我们想在小于700px宽度的视窗下,使用垂直状态(.card-vertical)卡片效果是不行的:7701年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品另外一点就是当服务端吐出的数据和设计师预设的数量不一致时,最终的Web效果有可能不是设计师期望的。比如只有一张卡片、两张、三张或更多,而设计稿中包含三张,这种情况之下,Web开发的实现的效果可能会像下图这样:正如上图所示

156、,如果只有一张卡片数据吐出的时候,整个卡片宽度会扩展与容器宽度相等(拉伸)。此时,卡片宽度太宽导致用于卡片上的缩略图被拉抻,有可能会使缩略图变得模糊。事实上呢?这只是Web开发者的一厢情愿,设计师真正的意图可能是像下图这样:在这种场景之下,使用 CSS 媒体查询特性实现起来会比较棘手,但使用 CSS 容器查询特性,就会容易地多,我们可以通过查询卡片父容器来决定如何显示卡片去解决这些问题。如果用一然话来概述的话:虽然 Web 开发者可以使用全局的视窗信息来设置组件的样式,但组件仍然不能拥有自已的样式,而且当我们的设计系统基于组件而不是基于页面时,那么媒体查询就无能为力!7801年度精选技术栈内容

157、终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品庆幸的是,生态系统正在改变,而且这两年尤其突出。比如说,我们一直期望的容器查询特性就如约而至。如果我们将组件自身的响应式样式思路从查询视窗转换到查询其祖先容器,是不是前面的问题就可以轻易解决。除此之外,早期的CSS媒体查询只能查询视窗宽度和媒体特性,但不能查询用户对设备喜好的设置。不过,这两年CSS媒体查询特性也有巨大的变化,我们除了查询媒介(设备)特性之外,也可以查询用户偏好设置。正如 Una Kravets 所言:Web生态再一次让CSS腾飞,这些新的特性将会让响应式Web设计注入新的能力。我们也将进入响应式设计的新时代,并

158、转变我们对其含义的看法。下一代响应式Web设计当媒体查询被运用于 CSS 中时,“响应式Web设计”(Responsive Web Design)一词就被 Ethan Marcotte 在 2010年创造出来。从那时起,Web设计师和开发人员就开始使用响应式Web设计的方法来设计和开发一个沉浸式的Web页面或Web应用,以实时适配当今看上去无底洞的终端设备。今天,当我们提到响应式Web设计时,首先想到的是Ethan Marcotte(beep)的 Responsive Web Design(地址:https:/ 流体网格(Fluid Grids)、灵活的图片(Flexible Images)和

159、媒体查询(Media Queries)三种技术来构建一个适应不同屏幕尺寸或不同移动终端设备的 Web 页面。7901年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品Web 开发者使用 CSS 媒体查询来改变整个页面的布局,并从上到下调整移动手机、平板电脑和桌面端的设计尺寸。这种方法很有效,而且效果很好,但它有一个明显的缺陷,即 整个屏幕同时响应,或者说整个页面同时响应。虽然该响应方式确实对用户的体验有一些较大的影响,但不能响应个别用户的需求,也缺乏将响应式注入组件本身。好消息是,生态系统正在改变,而且进步非常迅速。Web 设计师和Web平台的工程师正在开始用

160、一种新的响应式技术方案来构建Web页面,这种方案被称为组件驱动式Web设计(Component-Driven Web Design)。组件驱动式Web设计我们今天使用的响应式 Web 设计方法很快就会被认为是过时的,就像我们从90年代最初的基于表格的HTML开发过渡到现在的感觉一样。Web 设计师现在要克服的挑战是,目前的响应式 Web 设计方法本质上是一种一刀切的方法,把整个页面和用户体验当作一个整体,没有任何个性化。基于视窗的媒体查询(CSS 媒体查询)给我们提供了许多媒体查询的能力,但缺少为我们的Web设计提供精细度的能力,并创造一个对用户、他们的环境和他们在页面上采取的行动来说是独特的

161、体验。我们也缺乏将响应式样式注入组件本身的能力。这里所说的组件是Web上的元素,可以由其他设计元素的集合或分组组成。如果我们把组件看成是由积木组成的,并把这个概念应用到像幻灯片、卡片或内容块这样的常见UI元素的构造中,就会更容易理解,在不久的某一天,我们可能会把响应式设计样式注入单个组件或积木中,以定制和调整用户的体验,而不是把一套固定的样式和规则应用于整个页面的布局。我们可以使用全局视窗信息来控制元素的字体大小和最大宽度等样式,或者调整这些组件的背景图像和布局,但它们仍然无法控制拥有自己的样式。当我们的响应式设计系统是基于组件的,而不是基于页面的时候,这种限制就更难了。好消息是,全世界的We

162、b设计师和开发人员正在努力改变响应式Web设计的生态系统。尽管为了改变我们对响应式设计的思考方式以及组件如何适应其周围环境,需要进行基本的设计思维过程的改变,但响应式设计专业人员处理响应式Web设计的方式正在快速变化。8001年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品现在为创新之火推波助澜的是CSS和灵活布局的快速发展,比如添加了一些新的查询规则、Flexbox 和 Grid布局。这里所取得的进步正在迅速迎来一个新的响应式Web设计的时代,而这个时代就在地平线之外。CSS生态快速的发展,即将彻底改变响应式 Web 设计的概念!现在,在我们被引入响应式

163、Web 设计这个激进的新概念的十多年后,我们又一次见证了响应式设计生态系统的演变,即 CSS新增的特性将直接基于组件而不是基于页面注入样式响应能力。这种能力被称为 组件驱动Web设计(Component-Driven Web Design),基于组件驱动的开发将会成为一种真正流行的开发模式。为了理解这种开发模式的转变,并为即将到来的变化浪潮做好准备,让我们看看在响应式Web设计运动中我们可以期待的变化,以及这可能会如何改变我们对待响应式设计的概念。响应用户的需求你可能对基于视窗可视区域大小的媒体查询(通过 min-width、max-width、min-height、max-height、or

164、ien-tation 和 aspect-ratio 等)比较熟悉,比如:media(max-width:45rem)/*视窗小于 45rem*/media(min-width:45rem)/*视窗大于 45rem*/年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品也意味着这些新增的媒体查询特性允许你根据用户的偏好来调整用户的体验。现在很多设备提供了一些用户偏好的设置。比如在 Mac 电脑上,用户可以根据自己喜好做一些设置:CSS媒体查询提供了一些用户喜好的查询特性,这些特性可以识别出用户在系统上的偏好设置,帮助Web开发者构建更加健壮和

165、个性化的 Web 体验,特别是对于那些具有可访问性需求的用户。这只是 CSS 的 media 最基础的一部分规则,事实上,media 规则大约包含了 24 个可供查询的特性,其中大约19个查询规则得到较好的支持,详细的可以阅读图解CSS:CSS媒体查询(地址:https:/ww- Media Queries Level 5(地址:https:/www.w3.org/TR/mediaqueries-5/#mf-user-preferenc-es)规范中的第十一部分,能够让你根据用户自身的特定偏好和需求来设计 Web 体验。8201年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书202

166、2版大淘宝技术出品使用prefers-reduced-motion媒体查询用于检测用户的系统是否被开启了动画减弱功能。比如下面的这个示例,将会展示一组令人心烦的动画,不过当你开启了系统的“减少运动”后就能看到动画减弱的效果了。示例效果演示的是prefers-reduced-motion媒体特性如何让animation停止,其实CSS的transition也可以实现动画效果,加上并不是所有设备对动效都有一个很好的性能支持(毕竟动效是较耗性能的),因此,我们可以像下面这样来写CSS:prefers-reduced-motionWeb页面或应用难免少不了用一些动效来点缀,但有些用户不喜欢这些动画效果

167、,甚至对于少数用户来说,这些动效会让他们身体不适。这就是为什么现在大多数设备都支持一种方法让用户根据自己的喜好来做设置。.pulse animation:pulse 2s infinite;media screen and(prefers-reduced-motion:reduce).pulse animation:none;123456789media screen and(prefers-reduced-motion:reduce),(update:slow)*animation-duration:0.001ms!important;animation-iteration-count:1!

168、important;transition-duration:0.001ms!important;年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品这段代码强制所有使用animation-duration或transition-duration声明的动画以人眼难以察觉的速度结束。当一个人要求减少动效体验,或者设备有一个刷新率较低的屏幕,比如电子墨水或廉价的智能手机,它就能发挥作用。但需要注意的是,使用动态减弱并不意味着“没有动效”,因为动效在Web页面中传达信息能起到至关重要的作用。相反,你应该使用一个坚实的、去除非必须的动效基础体验去引导

169、这些用户,同时逐步增强没有此项偏好设置的其他用户的体验。如果你对减弱动效效果这方面技术感兴趣的话,还可以阅读:这段代码强制所有使用动画持续时间或过渡持续时间声明的动画以人眼无法察觉的速度结束。当用户要求减少动画体验,或者设备屏幕刷新率较低时,比如廉价智能手机,它就能工作。另外,Eric Bailey 在他的文章Revisiting prefers-reduced-motion,the reduced motion media query(地址:https:/css- prefers-reduced-motion 和 update 结合在一起使用:media screen and(prefers

170、-reduced-motion:reduce),(update:slow)*animation-duration:0.001ms!important;animation-iteration-count:1!important;transition-duration:0.001ms!important;1234567Revisiting prefers-reduced-motion,the reduced motion media query(地址:https:/css- Pause,Stop,Hide”with prefers-reduced-motion(地址:https:/hidde.bl

171、og/meeting-2-22-pause-stop-hide-with-prefers-reduced-motion/)(地址:https:/hidde.blog/meeting-2-22-pause-stop-hide-with-prefers-reduced-motion/)1.2.8401年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品而 color-scheme 这个 CSS 属性和的name为theme-color是相同的。它们都是让开发者更容易根据用户的喜好设置来控制Web应用或页面的主题,即允许开发者根据用户喜好设置添加特定的主题样式。其实

172、color-scheme 属性和 相应的标签与prefers-color-scheme相互作用,它们在一起可以发挥更好的作用。最重要的一点是,color-scheme完全决定了默认的外观,而prefers-color-scheme则决定了可样式化的外观。假设你有下面这样的一个简单页面:页面上中的CSS代码,把元素的背景颜色设置为gainsboro,如果用户更喜欢暗色模式,则根据prefers-color-scheme媒体查询,将的背景颜色设置为darkslategray。通过 元数据的设置,页面告诉浏览器,它支持深色(dark)和亮色(light)主题,并且优先选择深色主题。根据操作系统是设置

173、为深色还是亮色模式,整个页面在深色上显示为浅色,反之亦然,基于用户代理样式表。开发者没有额外提供 CSS 来改变段落文本或页面的背景颜色。fieldset background-color:gainsboro;media(prefers-color-scheme:dark)fieldset background-color:darkslategray;Lorem ipsum dolor sit amet,legere ancillae ne vis.Lorem ipsum Lorem ipsum 6223248501年度精选技术

174、栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品 prefers-color-scheme你可能知道了,macOS系统和iOS13之后,苹果设备具备DarkMode效果(地址:https:/ww- Users Motion Preferences(地址:https:/ With Reduced Motion For Motion Sensitivities(地址:https:/ Web Animation:The WCAG on Animation Explained(地址:https:/css- Animations in React(地址:https:/ 来定制不同

175、外观主题时,还可以和theme-color 以及 color-scheme 结合起来使用。这将能控制系统应用的(比如浏览器)主题颜色:使用 prefers-color-scheme 查询特性可以让你对用户是否打开了设备上Dark Mode来做出响应。换句话说,给Web页面或应用添加Dark Mode只需要几行代码即可。首先我们默认加载的主题是亮色系,我们可以在:root 中声明亮色系所需要的颜色,比如:然后通过媒体查询prefers-color-scheme:dark为暗色系重置所需要的颜色::root -text-color:#444;-background-color:#f4f4f4;12

176、34media screen and(prefers-color-scheme:dark):root -text-color:rgba(255,255,255,.8);-background-color:#121212;1234568701年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品请注意,元素的背景颜色是如何根据是否启用了深色模式而改变的,它遵循了开发者在页面上提供的内联样式表的规则。它要么是gainsboro,要么是darkslategray。上图是亮色模式(light)下,由开发者和用户代理指定的样式。根据用户代理的样式表,文本是黑色的,背景是白色

177、的。元素的背景颜色是gainsboro,由开发者在内联的式表中指定的颜色。上图是暗色模式(dark)下,由开发者和用户代理指定的样式。根据用户代理的样式表,文本是白色的,背景是黑色的。元素的背景色是darkslategray,由开发者在内联样式表中指定的颜色。按钮元素的外观是由用户代理样式表控制的。它的颜色被设置为ButtonText系统颜色,其背景颜色和边框颜色被设置为ButtonFace系统颜色。现在注意元素的边框颜色是如何变化的。border-top-color和border-bottom-color的计算值从rgba(0,0,0,.847)(偏黑)切换到rgba(255,255,255

178、,.847)(偏白),因为用户代理根据颜色方案动态地更新ButtonFace。同样适用于元素的color属性,它被设置为相应的系统颜色ButtonText。8801年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品看上去不错,但这也引出另一个新的概念,系统颜色(地址:https:/drafts.csswg.org/css-color/#css-sys-tem-colors)。8901年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品有关于系统颜色这方面的不在这里详细阐述,如果你感兴趣的话可以阅读:prefers-reduced

179、-data不是每个人都能幸运地拥有快速、可靠或无限的数据(流量)套餐。你可能有过出差旅行的经历,也可能碰到了手机数据不够用,那么访问一个重图片的网站是很糟糕的(虽然说现在流量对于大家来说不是很大的事情,花钱总是能摆平的)。不过,一旦prefers-reduced-data得到支持,那么这个头痛的事情就可以避免了,也可以帮用户省下一定的费用。因为,该特性可以让用户跳过大图或高分辨率的图像。当用户在设备上开启了“Low Data Mode”(低数据模式),会加载占流量更低的light.avif图像,可以帮助iPhone上的应用程序减少网络数据的使用:.image background-image:

180、url(images/heavy.jpg);media(prefers-reduced-data:reduce).image background-image:url(images/light.avif);123456789系统偏好设置的那些事儿(地址:https:/ High Contrast Mode,Forced Colors Mode And CSS Custom Properties(地 址:h t t p s:/w w w.s m a s h i n g m a g a z i n e.c o m/2 0 2 2/0 3/w i n d o w s-h i g h-c o n-tr

181、ast-colors-mode-css-custom-properties/)Styling for Windows high contrast with new standards for forced colors(地 址:h t t p s:/b l o g s.w i n d o w s.c o m/m s e d g e d e v/2 0 2 0/0 9/1 7/s t y l-ing-for-windows-high-contrast-with-new-standards-for-forced-colors/)Operating System and Browser Access

182、ibility Display Modes(地 址:h t t p s:/w w w.a 1 1 y p r o j e c t.c o m/p o s t s/o p e r a t i n g-s y s t e m-a n d-b r o w s-er-accessibility-display-modes/)1.2.3.4.9001年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品插个题外话,上面提到的这三个媒体查询特性主要是运用于 CSS 中,但它们还可以和 HTML 的 元素的 标签元素结合起来使用。可以根据用户对设备的偏好设置来选择不同的图片源:

183、617181991.contrast background-color:#0958d8;color:#fff;media(prefers-contrast:high).contrast background-color:#0a0db7;01年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品 prefers-contrastprefers-contrast媒体查询主要用于检测用户是否要求系统增加或减少相邻颜色之间的对比度。比如一些喜欢阅读电子书的用户,在阅读与文本背景对比度相差不大的文本时会遇到困

184、难,他们更喜欢较大的对比度,利于阅读。其他与用户偏好有关的媒体特性从W3C规范中不难发现,规范中提供了六个有关于用户偏好的媒体查询特性:比如像下面这个示例:92/SCSS.c-dialog_content background-color:var(-dialog-color-background);box-shadow:0 1rem 2rem 0#00000099;outline:var(-dialog-border-width)solid var(-dialog-border-color);padding:var(-dialog-padding-outer);width:min(90vw,3

185、8rem);z-index:1;media(forced-colors:active)-dialog-border-width:var(-size-300);11121301年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品我们来看一个 forced-colors 的示例,该示例来自于 Eric 的 Windows High Contrast Mode,Forced Colors Mode And CSS Custom Properties一文:在forced-colors媒体查询特性中重新定义了-dialog-border-width

186、的值。这样做的原因是一个非常有意思的调整。它把细的焦点框(outline)变成了一个粗的。这样调整有助于显示模态框的外部边界,并传达它是漂浮在页面其他内容之上的信息。强制色彩模式删除了模态框的盒子阴影(box-shadow),所以我们不能在这种专门的浏览模式下依赖这种视觉效果:提取使用 forced-colors 的示例代码:Modal dialog with Forced Color mode tweaks?smashingmag?CodePen(地址:https:/codepen.io/smashingmag/pen/zYPVjPa)(地址:https:/codepen.io/smashi

187、ngmag)(地址:https:/codepen.io/)9301年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品响应容器的需求CSS的媒体查询引发了一场响应式设计的革命,为开发者提供了一种方法来查询用户代理或设备环境的各个方面,比如视窗的大小或用户偏好来改变 Web 页面的风格。直到现在,媒体查询还做不到让元素的样式能根据一个最近的容器的大小来改变样式风格。也正因此,大家一直期待的容器查询来了。如果你对上面提到的媒体查询特性感兴趣的话,可以深入阅读下面这几篇文章:Media features(地址:https:/web.dev/learn/design/m

188、edia-features/)CSS媒体查询新特性(地址:https:/ 容器查询都是大家期待的一个特性,在这几年的CSS发展报告中,他一直位居第一:自 2010 年 Ethan Marcotte首次提出 响应式Web设计(RWD)(地址:https:/ CSS 媒体查询特性(通常是视窗宽度、媒体设备特性等)来为Web页面定制不同的表现形式,比如可以根据用户浏览内容的设备特性来呈现不同的布局、不同的字体大小和不同的图片等。9501年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品但对于 Web 设计师或Web开发者来说,在现代Web设计或布局中仍然缺少一特性,

189、页面的设计不能够响应其容器的宽度(或其他特性)。也就是说,如果Web开发者能够根据容器宽度来改变UI样式,那就更好了。容器查询将在很大程度上帮助 Web 开发者更好的完成他们的工作,在为Web开发基于组件代码时,其遗漏(容器查询特性的缺失)是一个巨大的限制。正因此,有关于容器查询的特性在社区中的探讨就没有停止过。早在2019年底,ZachLeatherman在寻找容器查询起源(地址:https:/ Andy Hume的基于 JavaScript 的选择器查询和响应式容器的解决方案(地址:https:/ 年,Mat Wilto Marquis在响应式图片社区小组引入了 元素,将响应式图片带到了响

190、应式 Web 设计的世界,他在Container Queries:Once More Unto the Breach(地址:https:/ali- Web 设计的文章之后的几年里,Web设计师和开发人员的工作越来越集中在组件上,而不是整个页面,这使得媒体查询不那么理想。从那时起,虽然有很多人主张使用媒体查询,但容器查询向前推进的速度还是不够理想。L.David Baron在Thoughts on an implementable path forward for Container Queries(地址:https:/ CSS 的工作原理,组件中的样式会影响其大小。任意打破这个循环,既会产生奇

191、怪的结果,又会干扰浏览器的工作,还会增加浏览器优化的成本。除了 David Baron 之外,2018年6月,Greg Whitworth在荷兰阿姆斯特丹举办的 CSS Day+UX Special(地址:https:/noti.st/events/elQrNX/css-day-ux-special)活动上的主题分享Over the moon for container queries(地址:https:/noti.st/gregwhitworth/UDul7E/over-the-moon-for-container-queries)中也解释了容器查询在Web平台上推进慢的相关原因。更重要的是

192、,Greg Whitworth还提供了使用9601年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品新的 JavaScript API 和 CSS 的新技术来实现容器查询的特性。David Barrrron 也提出了一个可以避免这种困境的策略(地址:https:/ Suzanne在David Baron的策略基础上提出了container方法(地址:https:/ 方法通过对被查询的元素应用大小和布局的限制来实现。任何具有尺寸和布局限制的元素都可以通过一个新的 container规则进行查询,其语法与现有的媒体查询类似。这个提议已经被 W3C 的 CSS 工作

193、组采纳(地址:https:/drafts.csswg.org/css-contain-3/),并已经添加到 CSS Containment Module Level 3(地址:https:/www.w3.org/TR/css-contain-3/)模块中。有关于该功能的相关问题和各网格平台推进进度,可以点击这里查阅(地址:https:/ CSS Containment Module Level 3 还是 FPWD 版本,规范中所描述的语法不是最终版本,直到写这篇文章,其语法规则还在变,因此文章中所展示的语法有可能会变以及相关的示例有一天就无效了:97 Must Try Best Brownie

194、s in Town High quality ingredients and best in-class chef.Light,tender,and easy to make Order now 01年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品 什么是容器查询CSS 容器查询最大的特点是:容器查询允许开发者定义任何一个元素为包含上下文,查询容器的后代元素可以根据查询容器的大小或计算样式的变化来改变风格!换句话说,一个查询容器是通过使用容器类型属性(container-type或container)指定要能的查询类型来建立的。适用于其

195、后代的样式规则可以通过使用container条件组规则对其进行查询来设定条件。容器查询为响应式设计提供了一种更加动态的方法。这意味着,如果你将此卡片组件放在侧边栏或放在页面主体内部的网格中,则该组件本身根据容器而不是视口进行响应式的信息展示。首先,把卡片放到一个容器元素中,比如.card_container:98/*Default*/.card /./*CSS Container Queries*/.card_container 1234567代码可能像下面这样:01年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品也就是说,当卡片组件被放在一个容器中时,代表

196、着它被包含在该容器中,比如上面代码中的.card_container。这也意味着,我们可以使用 CSS 的 container来查询.card_container 的宽度,并在container 对.card 设置不同的样式规则。从而达到设计师真正的意图:比如,容器宽度(.card_container)分别在 400px、550px 和 700px 时为.card设置不同样式:99/*containers width 400px*/container size(width 400px).card /./*containers width 550px*/container size(width

197、550px).card /./*containers width 700px*/container size(width 700px).card /.8952728293001年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品Untitled airen CodePen(地址:https:/codepen.io/airen/pen/ZEvoBYL)(地址:https:/codepen.io/airen)(地址:https:/codepen.io/)10001年度精选技术栈内容终端技术篇/技术经典

198、总结技术人的百宝黑皮书2022版大淘宝技术出品拖动卡片右下角的滑块,改变.card_container 容器大小,你可以看到卡片组件(.card)UI效果的变化:container规则,其工作方式与使用media的媒体查询类似,但相反,container查询父容器以获取信息,而不是视口和浏览器的UserAgent。容器查询的使用到目前为止,CSS 容器查询的语法规则已经经历了多个版本更新,上面示例中展示是最新的使用方式。下面这几篇文章中可以索引到其每个版本的使用方式的差异:接下来,通一个容器查询卡片的示例来向大家展示如何使用 CSS 容器查询。定义一个包含性上下文要使用 CSS 容器查询特性,

199、首先要定义一个包含性上下文(Containment Context)。这个有点类似于使用 Flexbox 和 Grid 布局(定义Flexbox 或 Grid 上下文使用的是 display 属性),只不过,定义一个包含性的上下文使用的不是我们熟知的 display 属性,而是一个新的CSS属性,即 container。在一个元素上显式使用 container 可以告诉浏览器以后要针对这个容器进行查询,以及具体如何查询该特定的容器。比如,上面演示的示例中,我们在.card_container 元素上(.card的父容器)显式设置了 container-type 的值为 inline-size:

200、上面的代码告诉浏览器,可以基于.card_container容器的内联轴(Inline Axis)方向尺寸变化进行查询。也就是说,当.card_container容器宽度大小变化到指定的某个值时,其后代元素的样式就可以进行调整。container-type 是 container 属性中的一个子属性,另外,还可以显式使用 container-name 来命名你的容器,即给一个包含性上下文指定一个具体的名称:初探CSS容器查询(地址:https:/ container和 container(地址:https:/ container-type:inline-size123101.card_cont

201、ainer container-type:inline-size;container-name:card;/*等同于*/.card_container container:inline-size/card;123456789container containerName size(width 45rem)/*应用了包含性上下文后代元素的 CSS*/container size(width 45rem)/*应用了包含性上下文后代元素的 CSS*/123456701年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品如果一个容器查询被应用到一个没有定义的包含祖先元素

202、上,查询将无法应用。也就是说,无论是 body 还是 html 元素,都没有默认的回退包含上下文。另外,定义包含上下文名称时不能是 CSS 的关键词,比如 default、inher-it、initial 等。注意:container-name 可以省略,如果省略将会使用其初始值none,但 container-type 不可省略,如果省略的话则表示未显式声明包含性上下文!定义一个容器查询现在我们知道使用 container(或其子属性 container-type和container-name)对一个元素显式声明包含上下文(对一个元素应用包含性)。有了这个包含性上下文之后,就可以使用 CSS

203、 的 规则container来对应用了包含性元素进行查询,即对容器进行查询。container 规则的使用和 media 以及 supports相似:这种方式对于同一个上下文中有多个包含性上下文时非常有意义,可以更明确地知道哪些查询会影响元素。你可以使用简写属性container,只不过需要在 container-type 和 container-name 之间添加斜杠分割符/:.card_container container-name:card12310201年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品这两种方式都是正确的使用姿势,第一个示例中的 c

204、ontainerName 指的是 container-name 显式声明的包含性上下文的名称。如果在container 中没有指定查询的容器名称,那么这个查询将是针对离样式变化最近的声明了包含性上下文的元素进行查询。比如:表示这个查询将是针对.card 元素最近的显式声明了包含性上下文的元素进行查询。代码中的size()函数是容器查询中的新语法规则。这也是容器查询语法变化之一,即 对查询类型进行了更明确的规定。因为规范已经提高到不仅可以根据尺寸(size)属性查询,还可以根据样式(style)属性进行查询。container size(width 30em).card border-radiu

205、s:20px;12345103container style(-card:large)/*CSS Style*/container size(width 30em)and style(-card:large)/*CSS Style*/123456701年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品到写这篇文章的时候,还没有浏览器支持对样式进行查询。另外,示例中用于 container 的查询条件(width 30em)相当于(min-width:30em)。使用数学表达式要比使用 min-width或max-width更易于理解,自 Media Queri

206、es Level 4(地址:https:/www.w3.org/TR/mediaqueries-4/#mq-range-context)开始,在 media 规则中,也可以使用我们熟悉的数学表达式,比如=、=等来替代以往不易于理解的min-和max-:上面示例代码中同时出现 container 和 container,但他们并不是指的同一个属性,前者是一个CSS属性,后者是一个CSS代码块。而且两者有本质的区别:正如 Terrible Mia(容器查询规范设计者)在 Twitter 上分享的一样,可以使用 style()函数对样式进行查询:container 是 container-type

207、和 container-name 的简写属性,用来显式声明某个元素是一个查询容器,并且定义查询容器的类型(可以由container-type指定)和查询容器的名称(由container-name指定)。container(带有规则),它类似于条件CSS中的media或supports规则,是一个条件组规则,其条件是一个容器查询,它是大小(size)和(或)样式(style)查询的布尔组合。只有当其条件为真(true),container规则块中的样式都会被用户代理运用,否则将被视为无效,被用户代理忽略。1.2.10401年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘

208、宝技术出品如果你对这方面讨论感兴趣,可以阅读 Ahmad Shadeed 的 The State Of Mobile First and Desktop First一文。(地址:https:/ Web 设计的出现以及移动终端设备越来越多,在设计中也有移动端优先(Mobile First)还是桌面端优先(Desktop First)的争执:10501年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品我们通过 CSS Grid 来完成卡片的布局。先从最窄的开始,添加下面CSS代码:如上图所示,我们从左往右来实现卡片不同状态断点下的UI效果。先从最窄的卡片开始(最左

209、侧,Default状态)。构建这个卡片组件,所需要的 HTML 结构如下:Container Queries Rule Lorem ipsum dolor,sit amet consectetur adipisicing elit.Quis magni eveniet natus nulla distinctio eaque?Order now 12345678.card display:grid;gap:1rem;margin:5vh auto;border-radius:0.5rem;box-shadow:0 0.25rem 0.5rem-0.15rem hsla(0 0%0%/55%);

210、background-color:#fff;.card_thumbnail max-width:100%;aspect-ratio:16/9;height:auto;object-fit:cover;border-radius:0.5rem 0.5rem 0 0;.card_title font-weight:700;font-size:clamp(1.2rem,1.2rem+3vw,1.5rem);padding:0 20px;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;.card_describe 1234567891

211、062232425262710601年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品尝试调整上面示例中视窗的大小:媒体查询 vs.容器查询通过上面的示例的介绍,我想你对容器查询特性已经有了一个较清晰的认识了。从使用角度来看,容器查询和媒体查询是非常的相似,那么有人可能会问,有了容器查询是不是就不再需要媒体查询特性了呢?在回答这个问题之前,我们简单的来看两者的差异。众所周知,媒体查询查询的浏览器视窗宽度(当然还有其他查询特性),而容器查询查询的是组件其父容器(具有包含性上下文的祖先元素)的宽度(或样式)。下图可能可以

212、清晰的阐述两者的差异:107.card_container container:inline-size;12301年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品正如上面的效果所示,卡片组件可以随着其容器(.card_container)宽度自动变化,在窄屏下效果看上去还不错,但在宽屏下,效果看上去有点怪怪的。不过不用担心,这仅是最初的效果。我们期望的是通过容器查询的特性,在容器不同断点下改变卡片组件的布局。按照前面所介绍的,我们需要先创建一个包含性上下文,即在.card_container 上使用 container 显式声明该元素是一个包容性上下文。co

213、lor:#666;line-height:1.4;padding:0 20px;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3;overflow:hidden;.card_button display:inline-flex;justify-content:center;align-items:center;border:none;border-radius:10rem;background-color:#feca53;padding:10px 20px;color:#000;text-decoratio

214、n:none;box-shadow:0 3px 8px rgb(0 0 0/7%);transition:all 0.2s linear;font-weight:700;justify-self:end;margin:0 20px 20px 0;cursor:pointer;.card_button:hover background-color:#ff9800;28293033738394044748495055710801年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品Untitled ai

215、ren CodePen(地址:https:/codepen.io/airen/pen/MWrXNGM)(地址:https:/codepen.io/airen)(地址:https:/codepen.io/)可以在上面示例中尝试拖动卡片右下角滑块改变卡片容器宽度,你将看到的效果如下:有了这样一个卡片组件之后,如果将其放在不同的位置,即使是同一页面,同一视窗断点下,也会根据其容器断点自动匹配最为适合的布局(或UI效果)。比如:Untitled airen CodePen(地址:https:/codepen.io/airen/pen/WNdKgMK)(地址:https:/codepen.io/aire

216、n)(地址:https:/codepen.io/)效果如下:10901年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品就我个人认为,两者不是谁替代谁的关系,更应该是两者共存的关系。容器查询特性的出现,我们可以不再局限于视窗断点来调整布局或UI样式,还可以基于容器断点来调整布局或UI。换句话说,媒体查询是一种宏观的布局(Macro Layout),可以用于整体页面布局;而容器查询可以调整组件的每个元素,创建了一种微观的布局(Micro Layout)。容器查询解决的是什么问题?众所周知,响应式设计的概念的核心是 CSS 媒体查询的出现,它允许开发者根据浏览器视

217、窗的尺寸来设置各种样式规则。也正因此,响应式设计和CSS媒体查询开启了更多的 Web 布局解决方案,以及多年来围绕响应视窗尺寸创建的最佳实践。而且,近些年来,设计系统和组件库也得到了更广泛的普及。对于更多开发者而言,更大的期望是:一次建成,随地部署!这也意味着一个单独开发的 Web 组件可以在任何情况下工作,以使建立复杂的界面更加有效和一致。只不过,这些组件会组合在一起,形成一个Web页面或Web应用界面。目前,在只有媒体查询的情况下,往往需要额外的一层来协调跨视窗大小变化的组件的突变。在这些情况下,你可能不得不在更多的断点下使用更多的类名来设置不同的样式规则。甚至更惨的是,即使这样做仍然很多

218、情况之下也无法达到最理想的UI表面。很多时候,响应式Web设计不是关于浏览器视窗尺寸而是关于容器的尺寸大小,比如:11001年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品庆幸的是,CSS容器查询的出现,使我们超越了只考虑浏览器视窗尺寸的范围,并允许任何组件或元素对定义的容器尺寸做出响应。因此,虽然你可能仍然使用响应式来给Web页面布局,但Web页面的任何一个组件都可能通过容器查询来定义自己的样式变化。然后,它可以根据它是在一个窄的还是宽的容器中显示,来调整它的样式。容器查询使我们不再只考虑浏览器视窗尺寸大小,而是允许任何组件或元素对定义的容器尺寸做出响应!

219、也就是说,有了CSS容器查询,你就能以一种非常精确和可预测的方式定义一个组件的全部样式。11101年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品 设计时考虑容器查询虽然响应式设计给Web设计师带来了更多的可有性,但响应式设计还是有很多的局限性。对于Web设计师而言,更期待的是能够根据组件容器尺寸来提供不同的设计风格。依旧拿卡片组件来举例:也就是说,CSS容器查询特性来了之后,作为一名Web设计师,在设计Web页面(或组件)时,就需要基于容器尺寸考虑如何设计。这样一来,可以向Web开发人员提供组件的细节和变化,Web开发人员也可以基于这些细节进行编码(进行开

220、发)。不过,这并不意味着容器查询特性之后响应式设计是就失去了意义。在未来,容器查询和响应式设计是共存的,简单地说,Web设计师在设计组件时可能会将组件分为以下几个部分:1.基于视窗(CSS媒体查询)2.基于容器(CSS容器查询)3.通用型(不受影响的组件)比如:11201年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品在未来,Web设计师给Web开发者投喂的设计稿可能就会像下图这样了:或许因为容器查询的到来,设计师在设计Web的时候,也可能会做出相应的调整。投喂给Web开发的设计稿也可能会和以往的模式有所差异。那么这个时候,Web开发者就需要具备正确理解设计

221、师的意图了。比如,Web设计师可能在未来的设计中会提供向下图的卡片组件设计:作为Web开发人员,看到上图设计效果,需要改变以往对设计图意图的理解,不能继续执着于基于视窗尺寸来调整组件UI。11301年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品上图是基于视窗的一种开发模式,需要为卡片组件设置不同的类名,并且基于视窗尺寸,在相应的类名下调整卡片组件UI。有了容器特性时,我们可以基于现代的Web布局技术,比如Flexbox或Grid布局,让卡片组件基于其容器来调整其UI:正如上图所示,可以基于视窗大小采用CSS媒体查询特性,Flexbox或Grid布局等技术改

222、变卡片容器.card_con-tainer的大小,从而让卡片组件根据其容器尺寸大小做出相应响应。拥有一个能根据其父容器尺寸做出响应(UI调整)的组件是非常有用的,正如你看到的,我们可以只构建一个组件,就可以满足不同视窗布局下的设计诉求!容器查询不应该让组件变得复杂化组件是有由很多个元素组合在一起构成的:11401年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品虽然容器查询特性到来,可以让组件根据其容器尺寸来做出响应,但要记住的是,做出响应变化应该要有一个度。如果过度设计的话,对于Web开发人员而言,与其使用容器查询特性来实现UI响应,还不如重新构建一个独立的

223、全新组件。拿用户信息组件(UserProfile)为例,组件内部结构保持不变,或者至少不会增加新的结构,只需稍加调整,比如调整布局就可以实现不同的UI效果,或者让内部元素显示隐藏切换等。在这种情景之中,采用容器查询特性才能显现其魅力:作用域样式为了完善容器查询特性,CSS 工作组还在积极讨论作用域样式(Scoped Styles)(地址:https:/css.odd- CSS 中另一个与容器查询同样被受期待的特性,级联分层,即 layer 也可以用来解决命名冲突,样式冲突的问题。该特性已得到了 Safari 和 Chrome 浏览器支持。如果你对该话题感兴趣的话,可以阅读初探 CSS 的级联层

224、(?layer?)(地址:https:/ /*targeting the scope root*/.light-theme:scope.tab /*contextual styles*/1111601年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品大致主要分为两种类型,双屏可折叠设备(如 Microsoft Surface Duo)和单屏可折叠设备(如 Huawei Mate XS):在多屏幕或可折叠设备上,Web应用或Web页面在这些设备上的打开姿势也将会有所不同,应用可以单屏显示,也可以跨屏显示:换句话说,我们的应用或页面要具备这种

225、跨越屏幕的能力,也要具备响应这种跨越的能力,以及还可能需要具备逻辑分隔内容的能力等。11701年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品可以说,多屏幕或折叠屏设备开启了更广阔的屏幕空间以及用独特的姿势将用户带入到另一个世界。针对于这种设备,除了用户之外,对于UI设计师,用户体验师和Web开发人员都需要重新面临解锁前所未有的Web体验。这也将是近十年来,Web开发带来最大的变化之一,以及开发人员所要面临的最大挑战之一。在这里我们针对多屏幕和折叠屏设备的响应,就称之为响应外形的需求。这也是响应式 Web 设计的一部分。由于可折叠设备相对来说是新型设备,面对

226、这些新型设备时很多开发者并没有做好相应的知识储备,甚至是不知道从何入手。事实上呢?有些Web开发者已经开始在为我们制定这方面的API,除了文章开头提到的三星(Sam-sung)的 Diego Gonzlez,英特尔(Intel Corporation)的 Kenneth Rohde Christiansen之外还有微软(Microsoft)的 Bogdan Brinza、Daniel Libby和Zouhir Chahoud。只不过对于Web开发者来说,现在这些制定的规范(CSS相关的特性)和Web API(JavaScript API)还很新,不确定因素过多,甚至差异性也比较大。到目前为止主

227、要分为两个部分。其中一个部分是可用于双屏幕和折叠屏的WebAPI(地址:https:/ww- Bogdan Brinza、Daniel Libby和Zouhir Chahoud一起制定的,更适用于“有缝”的折叠处设备;另一部分是目前处于W3C规范ED阶段的 屏幕折叠 API(地址:https:/w3c.github.io/device-pos-ture/),它更适用于“无缝”的折叠设备。argyleink在Github上发起了一个使用CSS媒体特性来检测折叠屏的讨论(地址:https:/ screen-spanning 这个特性可以用来帮助Web开发人员检测“根视图”是否跨越多个相邻显示区域,

228、并提供有关这些相邻显示区域配置的详细信息。11801年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品也可以使用 screen-fold-posture 和 screen-fold-angle 两个媒体查询来对无缝设备进行查询:还可以使用 horizontal-viewport-segments 和 vertical-viewport-segments 查询视口的数量:horizontal-viewport-segments 和 vertical-viewport-segments是最新的两个查询特性,它们将替代最初的screen-spanning这个媒体查询

229、特性!除此之外,还可以通过一些折叠姿势来进行查询:11901年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品/有缝折叠media(spanning:single-fold-vertical)/CSS Code./无缝折叠media(screen-fold-posture:laptop)/CSS Code.除了CSS媒体查询之外,还引入了六个新的CSS环境变量,以帮助开发者计算显示区域的几何形状,计算铰链区域被物理特征遮挡的几何形状:上图中展示的这六个CSS环境变量将替代以前的 env(fold-top)、env(fold-left)、e

230、nv(fold-width)和env(fold-height)。对于Web开发者来说,我们可以像下面这样来使用:12001年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品/折叠角度查询media(max-screen-fold-angle:120deg)/CSS Code./视口数量查询media(horizontal-viewport-segments:2)/CSS Code.media(vertical-viewport-segments:2)/CSS Code.62在现代布局中,将这些媒体查询特性、CSS环境

231、变量和CSS Grid布局结合在一起,就可以很轻易的满足外形响应的需求变化。比如:Stephanie 在她的最新博文Building Web Layouts For Dual-Screen And Foldable Devices(地址:https:/ -sidebar-width:5rem;media(spanning:single-fold-vertical):root -sidebar-width:env(viewport-segment-left 0 0);main display:grid;grid-template-columns:var(-sidebar-width)1fr;12

232、34567892101年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品.recipe display:grid;grid-template-columns:repeat(3,1fr);grid-template-rows:minmax(175px,max-content);grid-gap:1rem;.recipe-meta grid-column:1/4;img grid-column:1/4;.recipe-details_ingredients grid-row:3;.recipe-details_preparation grid

233、-column:2/4;grid-row:3;media(horizontal-viewport-segments:2).recipe grid-template-columns:env(viewport-segment-width 0 0)1fr 1fr;grid-template-rows:repeat(2,175px)minmax(175px,max-content);.recipe-meta grid-column:1/2;img grid-column:2/4;grid-row:1/3;.recipe-details_ingredients grid-row:2;1234567891

234、06223242526272829303373839404142122聊聊安卓折叠屏给交互设计和开发带来的变化(地址:https:/ API(地址:https:/ API(地址:https:/ CSS and JavaScript update for web developers(地址:https:/ Web Layouts For Dual-Screen And Foldable Devices(地 址:h t t p s:/w w w.s m a s h i n g m a g a z i n e.c o m/2 0 2

235、2/0 3/b u i l d i n g-w e b-l a y-outs-dual-screen-foldable-devices/)1.2.3.4.5.6.01年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品 .recipe-details_preparation grid-column:2/4;grid-row:3;43444546474849如果你对多屏或折叠屏这方面技术感兴趣的话,还可以阅读:技术的变革是永无止境的,我们将来要面对的用户终端也绝不会仅现于目前能看到的终端设备和媒介,就好比现在运用于游戏行业的 VR(虚拟现实)和 AR(增强现实)设

236、备。虽然现在 VR 和 AR 用于其他行业的场景还很少见,但我们可以预见,在 VR 和 AR 设备越来越成熟和更多的设备发布之后,我们就能看到 VR 和 AR 就像我们已经看到几十年前的触摸屏设备一样。或许有一天,你设计(或开发)的Web页面或应用就需要能在 VR 和 AR 设备上有一个较好的呈现。12301年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品上图来自于UX Case Study:Metaverse Banking VR/AR Design Concept of the Future(地址:https:/ Web 设计要响应的外形需求可能会更丰富

237、,更复杂。总结响应式 Web 设计已经将 Web 带到了今天人们所能接触到的每一个连接的屏幕上。Web设计师和创意开发者用创造性的思维、大胆的想法和某种无畏的精神探索、测试和迭代他们的想法,使在线体验更有吸引力、更容易访问和更智能,推动了设计方法的发展。就好比这里所提到的 组件驱动式Web设计。12401年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品组件驱动式 Web 设计的到来或者说 CSS 容器查询、作用域样式、级联层控制等特性的出现,这些先进的特性使我们有机会从页面布局、全局样式和用户样式中孤立组件样式,从而实现更具弹性的响应式设计。这意味着你现在可

238、以使用基于页面的媒体查询设计宏观布局,包括多屏或折叠屏的细微差异;同时使用基于容器查询给组件设计微观上布局,并添加基于用户偏好的媒体查询,来实现基于用户的独特偏好和需求的定制化体验。这就是下一代响应式 Web 设计,也就是 组件驱动式 Web 设计(或开发)。它结合了宏观布局和微观布局,最重要的是,也将用户定制化和尺寸外形都考虑到了。这些变化中的任何一个都将构成我们对web设计方式的重大转变。但它们结合在一起,意味着我们甚至在概念化响应性设计方面的一个巨大转变。是时候思考不止步于视口大小的响应性设计了,并开始考虑所有这些新方向,来获得更好的基于组件和定制化的体验。也就是说。如果我们将这些组件驱

239、动的功能纳入设计系统,并从整体上改变我们对待 Web 设计的方式,我们就可以利用这些功能以及更多的功能来改善每一个登陆你网站的访问者的用户体验。我们可以为他们提供真正个性化的体验,提高参与度和转化率,并最终提高用户对你的品牌的感知。我们不再是为用户群体设计。我们对 受众一词的理解将发生变化,因为内容和体验将为一个人而不是许多人的受众而变得高度集中。组件驱动的响应式 Web 设计将使 Web 真正的可移植,并能适应甚至还没有发明的设备。与其在今天的技术范围内追赶和设计,我们将只为用户设计。最后,希望文章中提到的概念和技术对你有所帮助。团队介绍我们是F(X)Team团队,F(x)Team,F(x)

240、指函数 F(x),是机器学习中常出现的符号,深度学习的本质也是求 f(x)的最优解,意味拥有不同特征的成员经过 fx 团队神奇作用,不断“训练”,一起找到前端智能化团队的最优解。我们致力于前端智能化领域的探索和实践,赋能淘宝、天猫、聚划算等日常与大促(如双 11)业务,是淘系前端智能化实践的领路人,也是阿里经济体前端委员会智能化方向的核心团队。我们在 D2C(Design to Code)领域开放了 Imgcook 平台,逐步释放阿里生态的前端生产力;同时我们也与 Google 的 tensorflow 团队保持长线合作,基于 tfjs-node 之上,开源了我们的前端算法工程框架 Pipco

241、ok,引领前端行业向智能化时代迈进。12501年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品Flutter 新一代图形渲染器 Impeller作者:谷鸣出品:大淘宝技术Flutter在2022年的Roadmap中提出需要重新考虑着色器的使用方式,计划重写图像渲染后端。最近该渲染后端 Impeller(叶轮)初见端倪,本文将介绍 Impeller 解决的问题、目标、架构和渲染细节。背景Flutter在过去一年多时间解决了很多Jank问题,但着色器编译导致的Jank问题一直没有彻底解决。这里我们先了解下什么着色器编译Jank。Flutter底层使用了skia做

242、为2D图形渲染库,而skia内部定义了一套SkSL(Skia shading language),SkSL 属于 GLSL 变体。在Flutter的光栅化阶段,当第一次使用着色器时Skia会根据绘图命令和设备参数生成 SkSL,然后再将 SkSL 转换为特定后端(GLSL、GLSL ES 或 Metal SL)着色器,并在设备上编译为着色器程序。而编译着色器可能花费几百毫秒,导致数十帧的丢失。定位着色器编译Jank问题可以查看trace信息是否有 GrGLProgramBuilder:finalize 调用。Flutter为了解决该问题,在Flutter 1.20 版本中为GL后端实现了SkS

243、L预热机制,支持离线收集应用程序中使用的 SkSL 着色器并保存为json文件,然后把该文件打包到应用程序中,最终用户首次打开应用程序时预编译 SkSL着色器,从而减少着色器编译 jank。随后,在 Flutter 2.5中支持了 iOS metal 着色器的预编译。Flutter gallery应用预热前后,在Moto G4上从90ms减少到40ms,在iPhone 4s上从300ms减少到80ms,性能提升很明显。在Flutter官方提供了SkSL着色器预热后,社区经常提到的一些高频问题收集如下:12601年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品

244、Q1.为什么不预编译用到的所有着色器?为了获得最佳性能,Skia GPU backend在运行时会根据一些参数(如绘图命令,设备型号等)动态生成着色器。这些参数的组合会生成大量的着色器,无法在应用程序中预编译和内置。Q2.不同设备上捕获的 SkSL shader 通用吗?理论上,没有机制保证在一台设备上捕获的 SkSL shader 在其他设备上也有效。实际上,(有限的)测试表明 SkSL shader 能表现的较好,即使在iOS上捕获的 SkSL 应用到Android设备,或者模拟器上捕获的SkSL应用到真机上。Q3.为什么不创建一个超级着色器并仅编译一次?这样的着色器会非常大,本质上是重新

245、实现 Skia GPU 功能。大shader需要更长的编译时间,从而引入更多的 Jank。但SkSL着色器预热也存在自身的缺点和局限性:1.应用包体积变大2.应用启动时间变长,因为需要预编译 SkSL shader3.开发体验不友好4.SkSL shader 的通用性无保证且不可预测以下时间线列举了Flutter在解决Jank问题上的努力和进展:12701年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品对于着色器编译Jank问题,官方经过多次尝试依然无法彻底解决,因此在2022年的roadmap中请明确提出要重新考虑使用着色器的方式,计划重写图像渲染后端。在

246、2022年计划在iOS上将 Flutter 迁移到新架构上,然后根据经验将该解决方案移植到其他平台上。最近,该图形渲染后端 impeller(叶轮)初见端倪,接下来让我们看看 impel-ler有什么独特之处。Impeller架构Impeller是为flutter量身定做的渲染器,目前处于早起原型阶段,仅实现了metal后端,支持iOS和Mac系统。工程方面,他依赖了 flutter fml 和 display list,并实现了display list dispatcher 接口,可以容易的替换skia。Impeller被flutter flow子系统所使用,因此得名。Impeller核心目

247、标:impeller软件架构可预测的性能:在编译时离线编译所有着色器,并根据着色器预先构建 pipeline state objects。可检测:所有的图形资源(textures、buffers、pipeline state对象等)都被追踪和标记。动画可以被捕获并持久化到磁盘而不影响渲染性能。可移植:没有与特定的渲染API相绑定,着色器编写一次并在需要时转换。使用现代图形API:大量使用(但不依赖)现代图形API(如Metal和Vulkan)的特性。有效利用并发性:可以在多线程上分发单帧工作负载。1.2.3.4.5.128Compiler:host端工具,包含着色器 Compiler 和 Re

248、flector。Compiler用于把 GLSL 4.60 着色器源码离线编译为特定后端的着色器(如MSL)。Reflector 根据着色器离线生成 C+shader bindings,以在运行时快速构建pipeline state objects(PSO)Renderer:用于创建buffer、从shader bindings生成pipeline state objects、设置RenderPass、管理uniform-buffers、细分曲面、执行渲染任务等Entity:用于构建2D渲染器,包含了着色器,shader bindings和pipeline state objectsAiks:

249、封装 Entity 以提供类 Skia API,临时存在,便于对接到 flutter flow1.2.3.4.01年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品impeller大致可以分为Compiler、Renderer,Entity、Aiks以及基础库Geomety和Base等几个模块。Impeller着色器离线编译impeller compiler模块是解决着色器编译Jank的关键所在。在编译阶段,首先把compiler相关源码编译为host工具impellerc binary。然后开始着色器的第一编译阶段,利用impellerc compiler

250、把/impeller/entity/shaders/目录下所有着色器源码(包括顶点着色器和片段着色)编译为着色器中间语言 SPIR-V。再开始着色的第二个编译阶段,把 SPIR-V 转换为特定后端的高级着色器语言(如Metal SL),随后(iOS上利用Metal Binary Archives)把特定后端的着色器源码(Metal着色器)编译为 shader library。同时,另外一条路径中利用impellerc reflector处理SPIR-V生成 C+shader binding,用于在运行时快速创建pipeline state objecs(PSO)。Shader bind-ing

251、生成的头文件中包括了一些结构体(有适当的填充和对齐),使得可以将uniform data和vertex数据直接指定给着色器,而无需处理绑定和顶点描述符。最后把shader library和binding sources编译进flutter engine中。12901年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品13001年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品这样所有着色器在离线时被编译为shader library,在运行时不需要执行任何编译操作,从而提升首帧渲染性能,也彻底解决了着色器编译带来的jank问题。

252、Shader Bindingsimpeller中的着色器仅需要基于 GLSL 4.60 语法编写一次,编译时转换为特定后端的着色器和binding。比如 solid_fill.vert 顶点着色器经过离线编译后生成了solid_fill.vert.metal,solid_fill.vert.h和solid_fill.vert.mm文件。solid_fill.vert:solid_fill.vert.metal:uniform FrameInfo mat4 mvp;vec4 color;frame_info;in vec2 vertices;out vec4 color;void main()g

253、l_Position=frame_info.mvp*vec4(vertices,0.0,1.0);color=frame_info.color;111213using namespace metal;struct FrameInfo float4x4 mvp;float4 color;struct solid_fill_vertex_main_out float4 color user(locn0);float4 gl_Position position;struct solid_fill_vertex_main_in float2 vertices attribute(

254、0);613101年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品solid_fill.vert.h:;vertex solid_fill_vertex_main_out solid_fill_vertex_main(solid_fill_vertex_main_in in stage_in,constant FrameInfo&frame_info buffer(0)solid_fill_vertex_main_out out=;out.gl_Position=frame_info.mvp*float4(in.v

255、ertices,0.0,1.0);out.color=frame_info.color;return out;22324252627struct SolidFillVertexShader /=/Stage Info=/=static constexpr std:string_view kLabel=SolidFill;static constexpr std:string_view kEntrypointName=solid_fill_vertex_main;static constexpr ShaderStage kShaderStage=ShaderStage:kV

256、ertex;/=/Struct Definitions=/=struct PerVertexData Point vertices;/(offset 0,size 8);/struct PerVertexData(size 8)struct FrameInfo Matrix mvp;/(offset 0,size 64)Vector4 color;/(offset 64,size 16)Padding _PADDING_;/(offset 80,size 48);/struct FrameInfo(size 128)/=/Stage Uniform&Storage Buffers=/=stat

257、ic constexpr auto kResourceFrameInfo=ShaderUniformSlot /FrameInfo FrameInfo,/name 0u,/binding6223242526272813201年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品 ;/=/Stage Inputs=/=static constexpr auto kInputVertices=ShaderStageIOSlot /vertices vertices,/name 0u,/attribute

258、 location 0u,/attribute set 0u,/attribute binding ShaderType:kFloat,/type 32u,/bit width of type 2u,/vec size 1u /number of columns ;static constexpr std:array kAllShaderStageInputs=&kInputVertices,/vertices ;/=/Stage Outputs=/=static constexpr auto kOutputColor=ShaderStageIOSlot /color color,/name

259、0u,/attribute location 0u,/attribute set 0u,/attribute binding ShaderType:kFloat,/type 32u,/bit width of type 4u,/vec size 1u /number of columns ;static constexpr std:array kAllShaderStageOutputs=&kOutputColor,/color ;/=/Resource Binding Utilities=/=2930337383940447484950515253

260、5455565758596066768697013301年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品solid_fill.vert.mm 文件仅对相应结构体进行填充和对齐校验,无实际功能。对于solid_fill.frag 同样的处理逻辑,生成了solid_fill.frag.metal,solid_fill.frag.h和solid_fill.frag.mm文件。/Bind uniform buffer for resource named FrameInfo.static bool BindFrameInfo(Command&c

261、ommand,BufferView view)return command.BindResource(ShaderStage:kVertex,kResourceFrameInfo,std:move(view);/struct SolidFillVertexShader77713401年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品Shader binding文件包含了着色器所有描述信息,如入口点,输入/输出结构,以及对应的buffer slot。运行时根据shader binding可以快速生成为pipeline state objec

262、ts。另外,bindings中输入/输出结构是有填充和对齐的,所以顶点和uniform数据可以直接内存映射。Impeller渲染流程impeller通过分别继承了IOSContext、IOSSurface和flowSurface,实现了IOSContextMetalImpeller、IOSSurfaceMetalImpeller和GPUSurfaceMetalImpeller结构对接到了flutter flow子系统中。在光栅化阶段,通过DisplayListCanvasRecorder(继承自SkNoDrawCanvas并实现了所有SkCanvas的函数)合成Layer Tree,把所有la

263、yer中的绘图命令转换为一个个的DLOps,并存储到DisplayList结构。DLOps中存储了绘图的所有数据信息,如常见的AnitiAliasOp,SetColorOp,DrawRectOp等,共有73种Ops。如下为drawRect的DrawRectOp的结构:struct DrawRectOp final:DLOp static const auto kType=DisplayListOpType:kDrawRect;explicit DrawRectOp(SkRect rect):rect(rect)const SkRect rect;void dispatch(Dispatcher

264、&dispatcher)const dispatcher.drawRect(rect);1113501年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品接下来进入impeller的渲染流程,使用DisplayListDispatcher执行DisplayList中所有Ops,在Op的dispatch()函数中调用DisplayListDispatcher的相应函数,把绘图信息转换为EntityPass结构。如果有saveLayer操作,则创建子EntityPass,形成EntityPass树形结构。同时把多个相关联的Ops转换为Entit

265、y存储到EntityPass中。每个Entity会对应一种Contents,表示一种绘图操作(如drawRect/clipPath等),共有11种Contents(参见第五小节附录impeller类图)。可见,DisplayList记录了细粒度的Op信息,结构扁平,无层次关系;转换为EntityPass后,对Ops进行了组装,根据savaLayer操作生成了有层次结构EntityPass tree,更便于后续的渲染。随后,使用RenderPass从Root EntityPass开始遍历,把EntityPass中每个Entity转换为Command结构,即从Shader Bindings生成GP

266、U Pipeline,把Polygon转换为顶点数据,设置片段着色器的颜色或纹理数据,再把顶点数据和颜色或纹理数据转换为GPU buffer设置到GPU Pipeline中。遍历完成所有的Entity Passes后,所有Com-mand都存储到了RenderPass中。然后,开始渲染指令编码阶段,根据MTLCommandBuffer生成MTLRenderCommandEncoder,遍历所有的Commands,把每个Command中的PipelineState,Vertext Buffer,Fragment Buffer设置MTLRenderCom-mandEncoder中,最后。结束编码并

267、提交command buffer。如下为Entity Passes的结构图:Canvas#saveLayer()操作会创建子EntityPass,用于离屏渲染;常见的需要离屏渲染的操作有:alpha blending,gradient,gaussian blur和expensive clipsEntityPass包含一系列Entity,每个Entity是一个绘图操作,对应于Canvas#drawXXX()每个Entity对应一个Contents,表示一种绘图类型,共11种Contents每种Contents在渲染时生成对应的Command,包含了顶点数据、片段着色器数据和GPU renderi

268、ng pipeline信息1.2.3.4.13601年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品GPU绘图过程顶点数据至关重要,需要根据绘制的形状生成顶点数据,再生成vertext buffer object(VBO)关联到渲染管线上,如下为impeller中对顶点的处理过程:以Rect类型为例,在生成EntityPass阶段会把Rect转换为Path结构,然后在创建Command阶段利用Tessellator(曲面细分器)根据Path生成顶点数据,存储到主存HostBuffer上,并把offset和length保存为BufferView关联到顶点或片段

269、着色器的PSO上。在Encode Commands阶段把整个HostBuffer上传到GPU buffer,把该次绘制的Vertext/Fragment Buffer、offset和length信息设置到对应的GPU pipeline上。Impeller渲染流程13701年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品总结以上我们介绍了impeller要解决的问题、他的目标、架构和渲染细节。目前该项目的现状如下:团队介绍阿里跨平台技术人才储备丰富,独行快,众行远,欢迎优秀的你加入【大淘宝技术-跨平台技术团队】,一起打造靠谱的跨平台方案!这里有H5容器、Wee

270、x、Flutter、小程序、游戏互动等诸多解决方案,既有技术深度也有广泛业务场景,欢迎优秀的小伙伴来一起搞事情,一起把技术做稳一起为业务提效,手淘跨平台技术团队欢迎你的加入!由此可见,flutter为了解决jank问题、提升渲染性能不惜重写图像渲染后端,决心可见一斑。期待impeller能使flutter的渲染性能更上一层楼。impeller离线编译shader为shader library,可有效提升首帧性能,避免着色器编译带来的jank问题目前仅实现了 Metal backend,支持iOS和Mac支持了73种Ops,11种Contents代码量 18774 行,目前仍依赖了一些Skia数

271、据结构,如SkNoDrawCanvas,SkPaint,SkRect,SkPicture等项目处于早期原型阶段,一些功能还不支持,如stroke、color filter、image filter、path effect、mask filter、gradient,以及drawArc、drawPoints、drawImage、drawShadow等等。issue#95434 中记录了进展和计划。整体工作量较大,相当于重写了 Skia GPU功能1.2.3.4.5.6.13801年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品HTTPS的原理浅析与本地开发实践作

272、者:陈超(揽辰)出品:大淘宝技术日常的开发过程中本地环境保持登录状态是前置条件,在校园B端业务模块的日常研发过程中,一般先通过预发环境登录,将登录态保存在的domain下,然后在本地通过Vite/Webpack Server+Nginx+host的方式构造自定义域名(一级域名与登录态的domain一致),进而做下一步的开发工作。但是目前预发/生产的域名都是https协议,本地自定义的域名默认协议是http。因此,为了读取登录态信息,需要将本地的访问地址也配置成https协议。实现的过程主要是在本地通过OpenSSL工具按照x509证书标准生成自签证书,并将这个自签证书添加到电脑的证书配置项中即

273、可(具体操作过程可以关注明天的推送)。这个配置过程引起了我对数字证书与HTTPS协议关系的好奇,因此做了下面的原理探究,下面就对这个探究的过程就一下记录,浅析HTTPS的实现原理,并将两种配置证书的方式的具体操作步骤做了记录。关键词加密算法、数字签名、秘钥交换、Wireshark、OpenSSL引言首先就需要抛出一个问题,为什么HTTP协议的网址越来越少?我们可以通过下面这个典型的HTTP数据传输流程看出它的问题 即数据在Client/Server之间不加识别的明文传输。(-http1.1-only.pcapng)13901年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版

274、大淘宝技术出品明文传输和匿名发送对象也体现了互联网信息不可靠的典型特性:1.篡改数据(伪造)破坏数据一致性;2.嗅探(偷窥)破坏数据的安全性;问题解法 如果想解决http的这两个问题,我们需要如何改良它?方案一:通过对称加密的方式传输数据场景一:客户端与服务端交互,通过约定的对称秘钥加密传输数据,在前端资源加载时,仍然可以从数据中找出想要的秘钥;场景二:客户端/服务端交互如果临时生成随机秘钥,在传输过程中仍然有被截获的风险;问题:秘钥在网络中传输容易被拦截,假设秘钥泄露,密文全会被破解且无法确定发送方是否安全;方案二:通过非对称加密的方式传输数据场景:服务端产生秘钥对,公钥交给客户端,私钥自己

275、保存,不会在互联网传输,安全性更高;问题:1.由于公钥是公开的,中间人可以篡改上行或者下行内容。该方案能解决上行数据安全性(密文传输,无法破解)问题,但是无法解决下行数据的安全性问题(公开的公钥可以解密服务端返回的密文)。此外,数据一致性问题 业务法保证,因为中间人可以假借公钥加密自己的数据给服务端,可以修改上行数据,或者中间人告知客户端的 公钥为自己的秘钥对,进行修改下行数据。2.非对称加密的效率偏低,不适合用于数据传输;方案三:先客户端/服务端间通过非对称加密协商秘钥,然后用协商的秘钥做后续的数据传输场景:先客户端/服务端双方通过约定的某种秘钥协商算法在客户端计算出秘钥K,并通过公钥加密K

276、传输给服务端,服务端通过私钥解密后,开始基于秘钥K做数据的对称加密传输。问题:1.固定的秘钥对和网络中传输的秘钥存在被窃取的可能,安全性并不牢固;2.客户端/服务端在数据传输前没有做合法性校验,无法避免中间人攻击;14001年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品方案四:先在客户端/服务端之间做认证,然后通过非对称加密协商秘钥,最后用协商的秘钥做后续的数据传输场景:在传输数据前先通过鉴别通信双方是否真实,而不是假冒的其他用户,在身份验证完毕后,基于某种高安全性的秘钥协商算法,通过非对称加密(秘钥对随机产生)的方式在客户端/服务端之间协商秘钥,双方会基

277、于协商算法的公开数据得到相同的秘钥,然后开启后续的对称加密通信。特点:1.数据传输前先做身份认证,基本可以解决中间人攻击的问题,防止篡改数据;2.使用高安全性的秘钥加密通信数据,可以有效防止数据被嗅探;结论方案四就是HTTPS解决明文传输两大问题的基本思路。其中身份认证涉及数字签名和数字证书概念,而非对称加密设计非对称加密体系。由于非对称加密的计算性能不及对称加密,所以,在经过几轮握手,协商好秘钥后,将数据传输的加密方式改为对称加密。总的来说,HTTPS就是通过数字证书+非对称秘钥体系+对称秘钥体系的组合方案来解决HTTP协议传输明文的两大问题。HTTPS141确定性:如果两个散列值是不相同的

278、(根据同一散列函数),那么这两个散列值的原始输入也是不相同的;不可逆性:故意创建产生给定散列值的消息是不可行的;散列碰撞:散列函数的输入和输出不是唯一对应关系的,如果两个散列值相同,两个输入值很可能是相同的,但也可能不同;1.2.3.01年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品HTTPS(Hypertext Transfer Protocol Secure)是基于 HTTP 的扩展,用于计算机网络的安全通信,已经在互联网得到广泛应用。在 HTTPS 中,原有的 HTTP 协议会得到 TLS(Transport Layer Security-安全传输层

279、协议)或其前任 SSL(Secure Sockets Layer-安全套接层)的加密。因此 HTTPS 也常指 HTTP over TLS 或 HTTP over SSL。(HTTPS)理论分析方案四只对信息传输的场景做了简要分析,其中有数字签名、数字证书、加密体系这些基础概念,为了方便在后续解析TLS/SSL握手过程,这里先对涉及的基础技术概念做简要的汇总介绍。散列函数 散列算法、哈希函数 定义散列函数(Hash Function)是一种从任何一种数据中创建小的数字“指纹”的方法。散列函数把消息或数据压缩成摘要,使得数据量变小,将数据的格式固定下来(散列值)。特点MD(Message Dig

280、est)摘要算法:MD算法生成的摘要消息都是128位长(32位的十六进制数字)表示,安全性排序:MD2 MD4 哈希运算(SHA-256)=文件哈希值(摘要)=签名运算(RSA,私钥加密)=数字签名;小红拥有小明对外开发的公钥(PS:小红可能不知道,小明的公钥已经被替换成中间人的公钥),在收到小明的信息后,做签名验证;公钥解密后的哈希值与待签名的文件哈希值对比,相同,则签名成立,否则签名不成立。数字签名的问题小明传输的数字签名可以被另外一个具有秘钥对的中间人替换传输的文件。相当于中间人模仿了小明的“签名”。RSA加密过程通式 ,公钥=(e,n)RSA解密过程通式 ,私钥=(d,n)秘钥对为(e

281、,d,n);14501年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品这个问题出现的核心原因在于:小明的公钥被中间人的公钥替换了,小红自己无法判断当前的公钥是否是小明的!所以,我们需要证明的是接收方拿到的公钥是发送方提供的,而不是中间人提供的。基于当前的案例,我们如何证明小红接收到的公钥就是小明发送的,而非被他人篡改的呢?这就需要有一种公开的权威的认证机制 数字证书机制。数字证书数字证书是利用非对称秘钥体系中,秘钥对的公钥和私钥是一一对应的特性,通过权威的证书签发机构(CA)签发证书预制秘钥,并将根证书预装在操作系统中,从而防止公钥被篡改。所以,数字证书可以

282、用来证明公钥是属于某个认证用户的。证书签发机构用自己的私钥对需要认证的人(或组织机构)的公钥施加数字签名并生成证书,即证书的本质就是对公钥施加数字签名。证书的产生和流转过程 14601年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品这种在数据传输过程中引入第三方来证明公钥的合法性是相对安全的,因为被信任的CA根证书都会被预装在操作系统中,这就相当于信任自己的操作系统,所以HTTPS协议在整个传输过程中,数据的一致性和安全性可以得到有效的保证。任何解决方案都不是银弹,都存在弱点或者不足。基于CA证书的通信过程也不是完美无缺的,因为CA机构本身也可能存在管理上的

283、问题,进而导致伪造证书泛滥,被有心者恶意利用,或者用户本身安全意识淡薄导致将不安全的证书安装进操作系统,导致数据传输安全问题的发生。(案例:distrusting-new-cnnic-certificateshttps:/blog.mozilla.org/security/2015/04/02/distrusting-new-cnnic-certificates/)HTTP的数据交换流程下面会基于wireshark工具,对单次HTTPS协议的网站流量进行详细的分析。HTTP和HTTPS数据交换流程对比 HTTP 数据传输过程简单,双方没有认证过程,数据明文传输产生终端证书:将发送方提供的身份信

284、息和公钥信息作为基础数据,CA基于这些数据做哈希和数字签名(CA的私钥加密)操作产生数字证书;证书合法性校验:发送方会将CA签发的终端证书通过互联网发送给接收方,接收方会基于CA预装在系统内的根证书(含CA公钥)来验证发送方提供的整证书是否合法;1.2.14701年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品 HTTPS 数据传输前要做复杂的协商过程,双方要做合法性校验,数据密文传输基于DH秘钥协商算法的信息交换流程HTTPS数据传输步骤分解TCP握手 建立链接;TLS握手或者秘钥协商过程(基于TLS版本的不同或者缓存影响,握手次数有所差异,这里只看TLS

285、v1.2的标准流程),握手目的:验证身份、交换信息、生成秘钥,为后续的通信做准备,总览图如下:1.2.(mac-https- no ico TLS use curl.pcapng)14801年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品3.TCP挥手 断开链接;TLS握手过程简析TCP建立链接和断开链接不是本次关注的重点,这里只对TLS握手协商秘钥的过程做一个简要的分析。C端代表客户端,S端代表服务端【C端-S端】告知S端,当前C端支持的协议版本(Version)、加密通信支持套件(Cipher Suites)等信息,并产生了一个随机数(5a882b)。第

286、二次握手 第一次握手14901年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品【S端-C端】告知C端,确定使用TLS协议版本号是1.2、生成的随机数(524401)、产生会话ID、确定加密通信的套件为TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384。通信套件(Cipher Suite)解析:1.生成秘钥:密钥协商算法使用ECDHE;2.数据传输加密算法:握手后的通信使用 AES 对称算法,密钥长度 256位,分组模式是 GCM;3.身份验证:签名算法使用RSA;4.完整性校验:摘要算法使用SHA384;TLS 的会话缓存机制 Ses

287、sionId(协议标准字段)和 Session Ticket(协议扩展字段),后续篇幅研究;第三次握手150【S端-C端】第一步:发送证书 Certificate:服务器向客户端验证身份;第二步:完成证书验证后,开始基于ECDHE做秘钥协商:公开椭圆曲线 Curve25519 蒙哥马利曲线()和曲线基点G(值为9)、S端随机产生私钥d1(存在本地)、通过私钥d1和基点G生成公钥Q1(Pubkey)。携带签名算法防止篡改公钥。常见的三种秘钥协商过程简析:基于RSA的秘钥协商(依靠非对称加密算法)SSLv2的协商机制客户端连上服务端;服务端发送 CA 证书给客户端;客户端验证该证书的合法性;客户端

288、从 CA 证书中取出公钥P;客户端生成一个随机密钥 K,并用这个公钥加密得到 K;客户端把K 发送给服务端;服务端收到 K 后用自己的私钥S解密得到 K;此时双方都得到了密钥 K,协商完成;双方开始使用秘钥K进行加密通信;01年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品151RSA的协商方式存在的问题是,加密数据在C和S端传输,如果S端的私钥泄密,则会导致加密传输的数据都会被破解,是否有更好的方式,能让对称加密的秘钥不在网络间传输,而是由双方通过统一的规则来在各自的环境内计算得到?这就是需要用到下面的DH算法来优化当前这个传输的过程。基于DH的秘钥协商(

289、依靠秘钥交换算法)客户端先连上服务端;服务端生成一个随机数 s 作为自己的私钥,然后根据算法参数计算出公钥 S(算法参数通常是固定的);服务端使用某种签名算法把“算法参数(模数P,基数G)和服务端公钥S”作为一个整体进行签名;服务端把“算法参数(模数P,基数G)、服务端公钥S、签名”发送给客户端;客户端收到后验证签名是否有效;客户端生成一个随机数 c 作为自己的私钥,然后根据算法参数计算出公钥 C;客户端把 C 发送给服务端;客户端和服务端(根据上述 DH 算法)各自计算出 K 作为会话密钥;01年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品152DH协商

290、秘钥协商算法计算性能不佳,因为协商过程中双方都需要做大量的乘法运算,为了提升 DHE算法的性能,所以就出现了现在广泛用于密钥交换算法 ECDHE算法。基于ECDHE的秘钥协商ECDHE 算法是在 DHE 算法的基础上利用了 ECC 椭圆曲线特性,可以用更少的计算量计算出公钥,以及最终的会话密钥。小红和小明使用 ECDHE 密钥交换算法的过程:这个过程中,双方的私钥都是随机、临时生成的,都是不公开的,即使根据公开的信息(椭圆曲线、公钥、基点 G)也是很难计算出椭圆曲线上的离散对数(私钥)。第三步:Server Hello done,S端已经完成向C端的消息发送;01年度精选技术栈内容终端技术篇/

291、技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品双方事先确定好使用的椭圆曲线类型以及曲线上的基点 G,这两个参数都是公开的,一般采用密码学中比较著名的椭圆曲线函数,例如本次会话用到的Curve25519曲线;双方各自随机生成一个随机数作为私钥d,并与基点 G相乘得到公钥Q(Q=dG),此时小红的公私钥为 Q1 和 d1,小明的公私钥为 Q2 和 d2;双方交换各自的公钥Q1和Q2;通过椭圆曲线特性计算得到相同的x坐标作为协商秘钥K,过程如下:小红计算点小明计算点基于椭圆曲线的特性 d1Q2=d1d2G=d2d1G=d2Q1,因此双方的 x 坐标 是相等的,所以它是共享密钥,也就是会话密钥

292、。(详细的数学原理:https:/ 第四次握手 第五次握手【C端-S端】【S端-C端】1.确认改用对称加密算法加密后续的通信数据;2.使用同样的方式传输加密后的数据并交给客户端验证。TLS 经过五次握手协商并得到加密秘钥后,双方就开始基于对称加密的方式对传输数据,这样能很好的提高数据传输的效率。客户端在本地随机生成一个私钥d2,通过私钥d2和基点G生成公钥Q2(Pubkey)。此时,双方都有对方的椭圆曲线公钥、自己的椭圆曲线私钥、椭圆曲线基点 G。于是,双方都就计算出点(x,y),其中 x 坐标值双方都是一样的。x直接作为对称加密的秘钥使用安全性低,双方为了会提高秘钥的安全性,会在x上“加盐”

293、处理,即使用先前会话产生的随机数组合产生秘钥 【5a882b+524401+x】。秘钥协商完毕,告知S端后续通信数据改用对称算法加密;对数据做摘要算法,使用秘钥加密,交给服务端验证;1.2.3.15401年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品数据传输(加密)通信双方使用“加盐”后的秘钥加密数据,并在网络间传输。如果传输中获取到秘钥协商时产生的秘钥,则可以解密已经加密的 Application Data,例如,TLSv1.3 的加密数据被wireshark解密。(https-no ico-WITH FIN TCP.pcapng)小结文章的最开始就提出

294、了HTTP协议在目前网络传输中存在的问题,然后基于两个典型问题做了合理的方案设想,最终推演出的第四种方案是更趋近于两个问题的实际解决方案的。在提出方案后,开始对其中涉及到的哈希函数、数据加密、数字签名等书面概念做了简单的总结,目的是为后续HTTPS的实际秘钥协商过程和数据传输过程做了铺垫。随后,基于wireshark工具,拦截一次HTTPS请求流量,对TLS(1.2版本)的秘钥协商过程(握手过程)做了相对细致的分析,期间也对先前TLS版本使用的秘钥协商过程做了简要的介绍,希望能够帮助你在理解HTTPS协议概念上能有所帮助。下一篇文章属于实战部分,将重点介绍HTTPS证书的配置过程,我将会以阿里

295、云证书配置和OpenSSL自签证书配置两种方式来让你的网站从HTTP转换到HTTPS。15501年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品概念汇总以上我们介绍了impeller要解决的问题、他的目标、架构和渲染细节。目前该项目的现状如下:名称解释概念传输层安全协议/安全套阶层-TLS(Transport Layer Security)/SSL(Secure Sockets Layer)openssl是一个功能丰富且自包含的开源安全工具箱它提供的主要功能有:SSL协议实现(包括SSLv2、SSLv3和TLSv1)、大量软算法(对称/非对称/摘要)、大数运

296、算、非对称算法密钥生成、ASN.1编解码库、证书请求(PKCS10)编解码、数字证书编解码、CRL编解码、OCSP协议、数字证书验证、PKCS7标准实现和PKCS12个人数字证书格式实现等功能。OpenSSL Cryptography and SSL/TLS Toolkit信息摘要也称特征值,它是将一段很长的数据信息,通过hash函数(MD5 或 sha 1等)计算,得到一串长度“较短”且“定长”的短数值,来作为这段数据独一无二的特征值。该过程不可逆。Message Digest数字签名使用用户的私钥(private key)对信息摘要进行加密,生成的信息。私钥+信息摘要=数字签名。Digit

297、al Signature数字证书由某个被信任的机构(CA)签发、认证用户身份的数字文件。CA私钥+认证用户的基础信息+认证用户的公钥=数字证书Digital Certificate证书经权威授权机构数字签名,包含公开密钥的拥有者信息以及公开密钥的文件,是权威机构颁发给网站的可信凭证。最简单的证书包含一个公开密钥、证书名称以及证书授权中心的数字签名。CRT常见于Linux系统,内容常用PEM,也有DER编码,CER常见于Windows系统,内容常用DER编码,也有PEM编码。CRT/CER(Certificate)证书标准定义证书中需要包含的内容 https:/www.ietf.org/rf-c

298、/rfc5280.txtX.509X.509证书的编码格式文本格式,以-BEGIN.开头,-END.结尾,内容是BASE64编码。PEM转为DER:openssl x509-in cert.crt-outform der-out cert.derPEM(Privacy Enhanced Mail)X.509证书的编码格式二进制格式,不可读。DER转为PEM:openssl x509-in cert.crt-inform der-outform pem-out cert.pemCER(Distinguished Encoding Rules)数字证书颁发机构/证书授权中心CA认证中心作为电子商务

299、交易中受信任的第三方,承担公钥体系中公钥合法性检验的责任。CA(Certificate Authority)证书签名请求它包含了您的服务器信息和公司信息。申请证书时需要将您证书的CSR文件提交给CA认证中心审核,CA中心对CSR文件进行根证书私钥签名后会生成证书公钥文件(即签发给您的SSL证书)CSR(Certificate Signing Request)存放私钥或者公钥的文件-KEY-可以使用一个数字证书绑定多个通用名称(即使互不相关的名称)。参加上面的手动创建CSRSAN(Subject Alternative Names)15601年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝

300、黑皮书2022版大淘宝技术出品参考资料 1.https:/ 数据结构根据场景定义。因此,要定义出场景,收敛并标准化沉淀。首先场景是基于中后台常见的产品模式和功能板块拆解,对交互形式、接口数据结构进行标准化收敛后,提取出的功能高度收敛的场景物料和场景控件。从技术上定义来看:按UI体系原子化设计的粒度划分,场景物料属于模版粒度,比如,基础查询场景包含筛选表单、操作区、展示表格、翻页器,是页面内的大区块;场景控件属于组件和模块的粒度,比如员工选择器、日期展示组件等。从能力上看场景物料和场景控件具有业务属性,内置了业务相关逻辑和API数据请求,比如:Fusion Table 是纯 UI 组件,AntD

301、 ProTable 封装了翻页、筛选等预设逻辑,查询场景物料还额外封装了接口请求处理,标准了场景所需要的接口及其数据格式即场景模型。1.2.16001年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品场景内置核心功能,并预留一些扩展能力,通过场景控件扩展场景中输入/展示/操作等 UI 组件,通过能力插件扩展条件渲染、联动执行等非 UI 型能力。场景与控件正交组合,再结合能力插件,就构成页面区块的完整功能,多个区块布局组合就构成完整页面。围绕上述核心逻辑,我们构建了完整的场景标准化体系:制定场景规范:成立场景规范小组,结合业务场景诉求,制定各场景统一的交互样式和

302、接口数据规范。建立场景沉淀机制:对于与现有场景完全不同的新场景,先按业务诉求梳理场景案例,对功能抽象分类,再经由场景规范小组评审,设计出符合规范的场景,最后开发并沉淀场景。对于与现有场景相似但有定制化诉求的,拆解出要扩充/定制的能力,同样经过小组评审后,在现有场景上进行迭代。构建场景生态体系:围绕整个大淘宝中后台域,构建整体场景标准及多业务域协同机制,统一管控及沉淀标准场景。并提供自定义物料研发套件及接入能力,以支撑更大范围业务场景。1.2.3.16101年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品数据标准化核心为模型定义,数据模型生产及数据实体生产三个

303、环节,将基于场景标准化产出的场景物料对应的API及其所需字段通过场景化搭建配置组合业务模型中的字段生成具体所需API及字段,后端根据API需求提供并绑定API实体完成页面所需API的标准化生产。模型定义,基于现有页面API结构的拆解,主要有这几部分:模型或者说标准的定义并不一定是定义本身多先进,而是大家认可并且能够遵循。因此在整个工作台维度我们成立了覆盖全域产品后端的规范小组,通过整体Review,RFC机制保障模型的标准及有效,通过每个团队的接口人推进规范落实及收集反馈持续优化。数据模型生产:有了上述三个模型,就可以在使用平台研发时,通过选择业务模型字段并关联到场景配置中,进而推导出页面所需

304、的接口定义(入参和返回值的字段结构)。技术上类似模版引擎,场景模型是模版,将业务模型字段填充到模版中的占位符,最后再套上网关模型的固定结构,就是期望的 API 数据模型。网关模型:描述工作台网关封装的数据结构,包含接口成功失败标识、错误信息、网关额外的调试信息等。网关模型固定,对工作台所有接口都有相同的结构。场景模型:描述具体场景涉及的所有接口的结构,包括场景内固定的入参、返回值字段,以及如何通过场景配置引入的业务模型字段。业务模型:描述实际业务中的概念、涉及对象及其属性,包括字段、类型、含义等。同一个业务模型可以用于多个产品页面。1.2.3.数据标准化16201年度精选技术栈内容终端技术篇/

305、技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品数据实体生产:后端按照推导出的 API 接口定义来标准化实现接口,同时我们也基于场景标准构建了通用的Java类,比如分页列表类、级联查询类等,配合一些工具函数,将 DO/DTO 快速转化成 VO,降低接口表现层的研发成本。大部分情况下比如新业务后端都相对能够较好的按照所产出的结构提供数据,但是针对一些存量接口,二方服务依赖较多的接口等情况后端改造及适配成本相对较高,我们也提供了字段组合映射能力及服务编排能力,以更低成本将非标接口快速转化成推导出的 API。无代码页面生产无代码核心目的是通过场景标准沉淀的场景物料及数据规范完全无代码生产完整功

306、能页面并驱动页面所需API数据结构的生成,以解决现有研发效能低,体验&质量难保障及前后端联调等协同问题。页面由UI、交互、数据构成,场景标准化和数据标准化保证了研发资产(场景和模型)是收敛的,已经有了 UI/交互/数据的结构化的大框架,只需要少量的研发工作就完成页面研发,而对于简单的结构化的页面研发,高效的方式就是可视化配置。从场景的角度出发,剩余的研发工作主要有场景配置、多个场景布局和联动、一些全局数据的贡献等,都可以收敛并抽象成可视化配置。全流程无代码可视化配置能降低非前端上手门槛,进一步提高交付质量和研发效率。与低代码的差异?相较通用低代码研发平台,我们基于标准场景搭建将非UI部分的交互

307、逻辑和数据对接等也进行了抽象和更深层次的能力封装,去除手写代码的负担,使得全流程无代码研发成为可能。16301年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品One more thing-中后台研发效能度量年年效能持续提升但是还是没变化?效率是中后台研发的核心目标之一,目前业界和集团内缺少兼具普遍性和实操性的效能度量方案。因此,有必要建立通用可行的中后台要能衡量对比中后台源码/低代码/无代码三种研发模式,覆盖研发及联调完整生产环节的效能度量模型及方案。以数据化方式度量项目、个人、团队的研发效能并指导未来效能提升的方向。现在方案的问题&策略核心方案标准协议:以

308、集团低代码协议和 OneAPI 2.0 协议为基础,补充场景模型、业务模型、网关模型、联动布局等协议,构成完整的无代码协议,同时支撑研发配置和运行渲染。研发资产:场景中心输入场景和场景控件,模型中心输入网关/场景/业务模型,共同作为标准的研发资产。研发配置:页面研发可以分为UI/交互/数据三个方面,从UI入手对单个场景进行配置,包括条件渲染、参数传递、全局筛选等功能配置,对多个场景组合布局,交互上配置场景间的联动关系,数据上将API推导的接口定义绑定到后端实现,就完成完整页面研发。结合实时预览和接口mock可以一边配置一边快速查看效果。构建发布:配置信息整合加工后,产出页面schema和API

309、数据模型,然后提取组件依赖,结合脚手架生成代码并更新仓库,最后构建发布到CDN。除了常规的页面应用,也支持将页面构建发布成微模块。运行渲染:使用集团低代码渲染引擎解析页面schema,渲染布局、场景和场景控件,使用联动流程调度引擎处理整个页面的联动逻辑,接口请求则由场景自行发起和处理。1.2.3.4.5.效能度量方案仅停留在代码复杂度层面,采用霍尔斯特德复杂度来度量,无法衡量项目变更的复杂度变化,无法解决中后台源码/低代码/无代码三种研发模式的效能对比。创新性地设计归一化最小作用域复杂度模型,解决变更和不同研发模式统一度量问题。大部分度量方案没有针对研发全链路更细致的度量指标。中后台效能度量方

310、案从微观和宏观的研发、联调时长出发,结合研发流程,计算过程指标和结果效能指标,并提供效率提升的分析依据和量化基准。1.2.定义效能指标及计算公式:分析拆解效能的度量指标,建立效能指标计算公式。研发效能=归一化复杂度/研发总耗时=(最小作用域差量复杂度/研发模式标准页面复杂度)/(连续研发工时+连续联调工时)。构建复杂度度量模型:改进霍尔斯特德复杂度算法,引入代码Diff、依赖分析、AST分析,搜寻差量代码的最小作用域,计算变更引入的复杂度,解决目前业内霍尔斯特德复杂度无法评估变更效能。1.2.16401年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品总结一点

311、感悟 关于低代码/无代码由于近年来各种LCDP/Low-Code概念太热各种方案及平台层出不穷,导致不少偏执的认识。部分人粗暴的把所有研发内容可视化,比如一些仅仅是把写代码的过程转化为可视化过程的产品,针对某些人群在某种程度上是降低了门槛,但在真实生产中效果有限定位尴尬。另外一种声音是完全否定,只要是听到相关名词就觉得是重复的,或者说觉得做不到、效果一定不好。很多过程的配置化、可视化确实不适合就如前面的描述。但是无法否认的是可视化方式更直观、约束更强、门槛更低,核心考量在于具体的场景,研发环节及内容抽象度及合理性,能否标准化,配置是否足够友好,目标用户及所解的命题。构建连续时长度量模型:预处理

312、源码/低代码/无代码研发和联调操作的打点数据,按时间进行阈值分隔,动态构建活跃会话窗口,计算连续研发时长和连续联调时长。标准页面归一化:对不同研发模式的页面分层采样,统计场景频次和占比,构建标准页面,用于归一化项目复杂度,解决不同研发模式语法信噪比不同导致的复杂度比较问题。完整度量计算链路:归拢中后台三种研发模式,设计度量采集、数据加工、指标汇总的完整链路,为提供效率提升的量化基准和分析方向3.4.5.16501年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品 关于新工具学习使用成本及收益对于解决问题的新工具如何考量自身学习和使用的投入产出,主要三个方面:权

313、衡取舍,成本、边际量。直白说如果需要获得的是编程技能,那用这类研发工具那是不适合的。如果你有大量的页面生产工作,并且期望高效的完成,那投入成本学习是有价值的。所以很多时候要客观理解具体的使用情况及反馈(当然是在工具真的能解决问题的前提下)。关于研发生产我们大部分时间开发其实本质就是在做某种逻辑的转换,而不是做什么设计,如何将人肉繁杂的处理过程、协同过程转为更高维度的抽象,各角色围统一模型有机协同生产,带来整体提效是需要持续探索的。而不是单一的构建一个工具、能力粗暴转移工作量,仅仅解决一个角色自身问题为出发点。一些结果完成无代码平台初步建设,实现多角色协同生产,缩减非必要的转译环节,提高页面生产

314、效能。定义场景标准,沉淀25个标准场景,场景业务覆盖率达到96%;沉淀39个场景数据及81个业务数据规范。构建统一的中后台研发效能度量方案Orca-Efficiency能够度量完整页面研发及联调过程,可度量及对比ProCode、LowCode、NoCode三种研发模式。平台全年支撑200+需求/项目迭代,覆盖大淘宝商家、商品、营销、智能人群运营全业务产品整体新需求覆盖率79%,并支撑直播域,X业务等10+产品构建。根据统一效能度量无代码模式效能相较源码提升5倍,低代码提升1倍,完整协同及生产提效68.6%。并且通过标准场景及无代码方式有效保障产品体验&研发质量。16601年度精选技术栈内容终端

315、技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品HTTP3 RFC标准正式发布,QUIC会成为传输技术的新一代颠覆者吗?作者:XQUIC项目组出品:大淘宝技术6月7日早晨(UTC时间Mon,06 June 2022 20:09),HTTP/3 标准RFC9114 由IETF标准化工作组正式发布,由此QUIC第一代协议族6大基础标准(不变量/传输框架/拥塞控制和恢复/TLS/HTTP3/QPACK压缩)全部完成RFC化,开启一段新的网络时代。在淘宝,我们从18年开始尝试QUIC,到2122年实现IETF QUIC及HTTP3标准的规模化应用,针对导购和交易核心链路场景拿到1520%

316、的网络耗时优化收益,同时沉淀自研的标准协议库实现XQUIC,并于年初开源。笔者想借由本文谈一谈对于网络7层模型中传输层的发展方向看法,以及对于底层技术发展过程中可能碰到的困难及问题提出一点可行的建议。开源仓库:https:/ 可靠传输 与 非可靠/半可靠场景的传输能力设计,包括0-RTT降低握手延迟这些基础的协议特性带来的优势,就不再多说。谈谈自研、标准与开源对于任何一项好用的技术来说,能够先应用起来并且服务好业务需求,永远是第一步。对于任何具备深度和一定壁垒的技术(碰巧网络也属于),一般我们都会经历4个发展阶段:笔者个人的观点是,每个阶段都需要投入不同的精力,对应着领域的持续深挖和人才的长期

317、培养与团队建设。选择走到哪个阶段,没有绝对的好与坏,而是应该根据实际的诉求、可持续投入情况 和 发展的观点来判断。另一方面,作为一个技术人,我们也应当充分尊重技术本身的深度,尊重愿意为了走到第三/四阶段,而投入精力、克服重重困难的技术产品和团队,而非通过一些短期包装和走捷径的方式,避免最终在技术上逐渐空心化,影响技术大环境的发展。如何维护技术环境的一片净土,使得健康的种子能够具备萌芽的条件,这也是技术管理者需要考虑和反思的。如何应用QUIC/HTTP3来提升传输性能表现这次IETF发布的RFC9114和9204分别描述的是HTTP/3.0和配套的Header压缩算法QPACK的协议机制。HTT

318、P/3.0相对于HTTP/2到底有什么本质提升?这需要从HTTP/3底层的QUIC传输机制讲起。第一阶段,用好这项技术,首先能用好并切实在业务场景下拿到收益。在当前这个鼓励开源的时代,第一步通过这个领域下已有的开源方案,来验证技术的可行性,并拿到一些初步收益来验证判断和观点,是最快的方式。第二阶段,原理理解透彻,能够充分理解透彻这项技术的底层原理和机制,并针对业务需求做出调整。在这个阶段往往大家会有两条分叉路径:在已有开源项目上继续修改并发展自己的分支;或者 筹备自研。在这个阶段是选择前者还是后者,核心依据有2个:一方面是 是对这项技术长期发展所能带来的红利,是否可以cover前期的投入;另一

319、方面是,是否具备自研能力。第三阶段,具备自研能力,如果从2到3的判断能够满足自研的前提,就会走上自研道路。因此我们可以看到绝大部分一线互联网大厂,都会对战略性的技术投入方向进行自研,同样自研也能够带来技术壁垒的积累。这一步也是第四阶段的前置门槛。第四阶段,引领前沿发展,这个阶段往往又存在两种类型(或两者兼有):通过开源逐步成为事实标准,或者是参与到行业标准的制定当中。16801年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品我们都知道,QUIC基于UDP之上的多流(Stream)传输,实现解决原来TCP大管道下的Head-of-Line问题3,同时0-RTT

320、等握手机制可以保证连接会话的快速建立和首包的加速。QUIC提供了两种传输模式,基于Steam的可靠传输,和基于Datagram的非可靠传输。基于Stream的模式下,发送方和接收方基于Steam的Offset进行流数据的重排和有序还原,并确保投递给应用层的是有序可靠数据。基于Datagram的模式则适用于实时流媒体类型的场景,针对延迟有强诉求的同时不要求数据完全可靠有序的这类场景,Datagram提供了一种数据封装和ACK通知的方式,帮助半可靠诉求的场景实现数据的快速投递,并向应用层反馈送达情况。3 TCP Head-of-line头部阻塞问题:原因是TCP是一条大的传输管道,基于TCP传输的

321、数据,由于TCP的传输机制,需要等待前面的数据包完成送达,后续的数据包才能被完成送达和向应用层投递。这在多路复用的场景下,会导致不同的流数据之间互相block,这在HTTP/2是一个没有被完全解决的问题。QUIC在丢包检测和重传机制方面也有较大革新。在丢包检测方面,QUIC提供了两大类丢包检测方式,基于packet number的阈值检测,和基于定时器的超时丢包检测。这两类机制相对于传统的TCP检测方式可以带来更快的丢包感知和恢复。在重传恢复方面,QUIC针对每一个packet分配独立的packet number,避免了过去TCP因重传包和原始包复用相同的sequence,导致的RTT测量不准

322、确的问题。准确测量的RTT,作为拥塞控制算法的一维重要输入,能够使得算法对瓶颈段拥塞状况的检测更加准确。这次发布的HTTP3 RFC,则是在QUIC基础之上,描述了HTTP请求如何通过跟QUIC steam的映射,实现完整的HTTP语义,以及针对基于UDP的多流机制设计的专用头部压缩。因此所有QUIC在UDP之上实现的传输机制革新,HTTP3都可以享受到红利。那么如何把这项革新的技术用起来呢?XQUIC针对QUIC和HTTP/3协议栈提供了完整的能力实现,并且完全符合IETF标准,并通过了IETF工作组的互通性验证4。在手机淘宝我们提供了整套的网络解决方案,包含客户端的SDK和服务端网关的能力

323、支持,各类业务场景核心关注开关和放量情况即可。对于外部开发者,可以移步到XQUIC在github的开源仓库5,开源仓库有相对完整的文档说明和RFC译文,同时后续开源版本我们也将逐步更16901年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品新IETF工作组版本的Multipath8多路传输能力,以及Tengine相关的适配版本和模块,方便外部开发者能够更方便地使用。如何解决服务端UDP性能问题相信已经在尝试应用QUIC/HTTP3的服务端开发者,或多或少都会经历UDP在内核方面的性能瓶颈问题,考虑到UDP是在近几年才随着QUIC和流媒体传输的场景的逐渐流行,

324、才被逐渐广泛地应用起来,因此内核UDP在性能方面很难与优化了三十年的TCP相抗衡,同时内核的复杂性和通用性要求,也导致一些新的高性能修改难以被迅速接收。因此,在UDP性能优化方面,我们和龙蜥社区的Anolis内核团队联合做了一版bypass内核的用户态高性能udp收发方案。17001年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品首先我们需要了解到,ebpf6有一类专门用于网卡驱动处理的filter叫XDP7,可以实现对于网卡接收和发送的packet进行劫持处理;Anolis内核团队基于XDP实现了一套UDP packet卸载和封装逻辑并封装为XUDP8库,

325、而我们则基于XUDP进行UDP packet的收取和发送,实现完全bypass内核的高性能UDP收发。这一套方案相较于Linux内核默认的UDP收发+四元组hash查找优化的方案,可以在真实场景下,再提升26.3%以上的服务器协议栈处理性能。Tengine+XUDP+XQUIC的打包处理方案,我们后续也会在Tengine社区提供开源版本以供外部开发者参考。写在最后希望大家都能在自己的领域,享受技术前进的快乐。17101年度精选技术栈内容终端技术篇/技术经典总结技术人的百宝黑皮书2022版大淘宝技术出品参考文献1 HTTP3:https:/datatracker.ietf.org/doc/rfc

326、9114/2 QPACK:https:/datatracker.ietf.org/doc/rfc9204/4 互通性验证:https:/interop.seemann.io/5 XQUIC开源仓库:https:/ XDP:https:/dl.acm.org/doi/pdf/10.1145/3281411.32814437 XUDP:https:/ Multipath Extension for QUIC:https:/datatracker.ietf.org/doc/draft-ietf-quic-multipath/团队介绍XQUIC团队隶属于大淘宝平台技术-终端体验平台团队,希望能通过网络

327、技术演进给用户带来更丝滑的体验。如果对XQUIC、网络技术、高性能网络传输等领域比较感兴趣,欢迎点击“阅读原文”关注我们的 GitHub 仓库:https:/ 业务发展目标作为业务团队,以业务先赢为目标,以技术突破为手段,赋能购物车业务高效发展应当是我们的核心目标,那么购物车这个场景的业务发展目标又是什么?其实业务如何发展,首先要思考的是,这个域场景以及作为该场景的平台方面对的角色都有哪些?这些角色目前对应的痛点与诉求是什么?对于购物车业务发展,总的来说当下面对三种角色:消费者、商家与平台、业务方。因此,面对购物车域的这些产品痛点与诉求,我们将购物车的业务发展目标总结为三个方向:方向一:体验购

328、物车产品的使用体验体现在哪些方面?作为一个下单链路的基础产品,购物车管理的“物”为商品、首先面对的“角色”是消费者,那么我们思考人与商品的关系,在整个产品使用中,人(即消费者)对物(即购物车商品)存在以下行动动线:存储、浏览、管理、决策、结算。那么在以上几个环节中消费者操作是否高效则定义为购物车产品良好的使用体验。【消费者角色】:即需要使用淘宝购物车来完成购买过程的用户;对于消费者来说,购物车产品基础功能使用体验差、购买决策效率低是最大的痛点;【商家与平台角色】:购物车作为用户私域,给商家营销、运营提供较小的空间,对于如何促转化、提高用户购买意愿,从而获得增量是该类角色面临的最大痛点;【业务方

329、】:业务玩法愈的发复杂,导致业务逻辑也变的复杂,严重阻碍研发效率及业务发展迭代;1.2.3.17701年度精选技术栈内容终端技术篇/相关业务实践技术人的百宝黑皮书2022版大淘宝技术出品方向二:转化购物车作为一个基础产品,是否具备转化的空间?是否能为商家自运营营销提供可能,并最终给平台带来增量?这是我们在购物车业务发展中思考和数据挖掘的方向。数据分析与挖掘带给我们的结论:淘宝购物车中存在大量用户加购但没有被转化的存量商品,这些存量商品转化率随着加购时间越久,转化率越低,加购前两个小时成交占比60%左右。因此购物车实际上有巨大的空间去获得新的增量;如何增强货品的吸引力以及重新唤醒用户需求是购物车

330、转化提升的两个方向,除此之外实际上从21年我们逐步开始寻找购物车外场景的增量,结合算法手段精准推荐让用户买的更多、更划算;方向三:效率无论是体验还是转化,业务的发展离不开快速的试错与迭代,最终离不开高效的研发效率。而研发效率又面对恶劣的业务现状和开发环境:业务上多端多平台,需求繁多复杂;开发上,需求响应慢、沟通协调多,重度依赖客户端发版。以上几点都严重阻碍业务迭代速度。需要依靠技术改造来改变研发模式,提高研发效率;业务发展策略基于购物车业务发展的三个方向,我们拆解为两个主要的实施策略:消费者侧产品升级&研发提效。【策略一】消费者侧产品升级:购物车产品升级主要体现在两个方面:(1)基于购物车的工

331、具属性进行体验优化;(2)基于购物车的场景特征促转化得增量;【策略二】研发提效:购物车研发效率的提升体现在两个方面:(1)技术的改造提升研发效率;(2)业务的闭环提升业务迭代的效率;最后,我以我的理解将近两年购物车的发展(业务+开发提效)总结为一张大图(其中部分内容后面章节会详细介绍):17801年度精选技术栈内容终端技术篇/相关业务实践技术人的百宝黑皮书2022版大淘宝技术出品当我们在说购物车体验时我们在说什么作为一个基础工具产品,无论KPI导向是GMV还是体验,我始终认为提升用户在日常以及大促的使用体验才是产品升级的核心,那么,当我们在说购物车体验时我们在说什么?我们又做了什么呢?淘宝购物

332、车产品使用现状既然要提升用户的体验,那第一步需要了解用户的诉求与痛点,以21年初一份手淘购物车体验调研报告为例,从购物车使用人群分布、使用场景、使用痛点三个方面来看:17901年度精选技术栈内容终端技术篇/相关业务实践技术人的百宝黑皮书2022版大淘宝技术出品当我们在说购物车体验时我们在说什么购物车是一个提供商品管理、凑单合并结算能力的基础工具,围绕两个核心:人和商品,人与商品的关系总结为两个,即人对商品的管理以及人对商品的购买结算。那么购物车产品使用体验也围绕这两个点展开。整体如下图所示:【人群分布】:高购买力人群是购物车的主要使用群体;【使用场景】:(21年初统计的数据):除收藏商品、购物

333、车结算等基础功能外,用户使用购物车的主要场景依次为为凑单、对比商品价格,对比商品属性。可以看出用户对购物车使用诉求主要总结为:商品管理与发现、算价与下单、凑单;【使用痛点】:(21年初统计的数据):总结下来,用户对购物车的使用痛点来自于几个方面:(1)大促期间跨店凑单效率低;(2)价格体验:包括预热期无法透出大促价、动态计算结果与下单不能完全一致等;(3)购物车商品的快速发现:查找、分类筛选等;1.2.3.18001年度精选技术栈内容终端技术篇/相关业务实践技术人的百宝黑皮书2022版大淘宝技术出品商品管理即用户按照当下购买意愿强烈程度对商品进行查找、增删改查等。影响用户进行商品管理体验的因素包括:(1)购物车容量问题导致的加购卡点;(2)商品查找与发现的效率;(3)商品管理即各种增删改查的操作路线是否简单高效;商品购买即用户在购物车不断选择商品、算价、凑单、再算价最终完成下单结算的购买

友情提示

1、下载报告失败解决办法
2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
4、本站报告下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。

本文(大淘宝技术:2022技术人的百宝黑皮书-阿里大淘宝技术2022技术年货(1276页).pdf)为本站 (Azure) 主动上传,三个皮匠报告文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知三个皮匠报告文库(点击联系客服),我们立即给予删除!

温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。
会员购买
客服

专属顾问

商务合作

机构入驻、侵权投诉、商务合作

服务号

三个皮匠报告官方公众号

回到顶部