【CSS in Depth 2 精译_095】16.3:深入理解 CSS 动画(animation)的性能

当前内容所在位置(可进入专栏查看其他译好的章节内容)

  • 第五部分 添加动效 ✔️
  • 【第 16 章 变换】 ✔️
    • 16.1 旋转、平移、缩放与倾斜
      • 16.1.1 变换原点的更改
      • 16.1.2 多重变换的设置
      • 16.1.3 单个变换属性的设置
    • 16.2 变换在动效中的应用
      • 16.2.1 放大图标(上)
      • 16.2.2 带“飞入”特效的文本标签的创建(下)
      • 16.2.3 过渡特效的交错渲染(下)
    • 16.3 动画的性能 ✔️
    • 16.4 三维变换

文章目录

  • 16.3 动画的性能 Animation performance
    • 16.3.1 渲染流程 Looking at the rendering pipeline
      • 16.3.1.1 布局 Layout
      • 16.3.1.2 绘制 Paint
      • 16.3.1.3 合成 Composite

《CSS in Depth》新版封面

《CSS in Depth》新版封面

译者按
这又是一篇 “看上去不起眼、实际上却非常有用” 的 CSS 硬核知识 —— CSS 渲染的性能问题。也只有在今后的实际开发中遇到了类似的性能瓶颈,本节介绍的知识才会凸显出它真正的价值来。不过话又说回来,如果页面渲染性能真的遭遇了瓶颈,CSS 处理不当也仅仅是问题排查的一个方面,更多情况下是综合因素的结果,这估计也是为什么作者没有通过典型案例来演示说明的原因吧。无论如何,了解浏览器渲染的底层逻辑还是非常有必要的。

16.3 动画的性能 Animation performance

有些变换看上去好像没有存在的必要。例如平移变换的效果,通常也可以使用相对定位来实现;对图片或 SVG 进行缩放变换,其实也可以通过设置宽高完成。

其实,变换在浏览器中的性能要好很多。如果我们对元素位置设置动画效果(例如对属性 left 添加过渡特效),就能明显感受到性能上的不足。特别是在给大型复杂元素设置动画、或者是在页面上一次性给大量元素添加动画时,问题尤为突出。这种性能问题在 CSS 过渡(详见第 15 章)和动画(下一章会讨论)效果上都有体现。

如果我们要实现过渡或动画,无论什么类型,包括元素定位或大小设置,都应该尽可能地考虑用变换实现。想要彻底搞懂原因,需要进一步深入考察页面在浏览器中的渲染方式。

16.3.1 渲染流程 Looking at the rendering pipeline

当浏览器计算好页面上哪些样式会在哪些元素上生效之后,需要把这些样式转换为屏幕上的像素,这个过程就叫作 渲染(rendering。渲染可分为三个阶段:布局(layout)阶段、绘制(paint)阶段与合成(composite)阶段(如图 16.2 所示)。

图 16.12 渲染流程中的三个阶段

【图 16.12 渲染流程中的三个阶段】

16.3.1.1 布局 Layout

在第一个阶段 布局(layout 中,浏览器需要计算每个元素将在屏幕上占据多大空间。由于文档流的工作方式,一个元素的大小和位置可以影响页面上无数其他元素的大小和位置。这个阶段会将所有这些问题整理清楚。

任何时候改变一个元素的宽高,或者调整其位置属性(如 topleft)时,都必须重新计算该元素的布局。如果使用 JavaScript 在 DOM 中插入或移除某个元素,也会导致布局的重新计算。一旦布局发生改变,浏览器就必须 重排(reflow(译注:即重新排版)页面,重新计算因布局变更而被移动、或被调整大小的所有其他元素的布局。

16.3.1.2 绘制 Paint

布局之后便是 绘制(painting。这个过程就是填充像素:例如绘制文本、给图片、边框、阴影上色等。这一阶段并不会真正显示到屏幕上,而是在内存中绘制。页面各部分内容就这样被绘制到不同的 图层(layers 中。

举个例子,假如需要改变某个元素的背景颜色,就必须重新绘制该元素。但由于更改背景色不会影响页面上任何元素的位置与大小,这样的变更也无需重新计算布局。因此,改变背景颜色的计算开销要低于改变元素尺寸的开销。

在适当的条件下,页面元素会被提取到自己的图层。此时,该元素会从页面的其他图层中独立出来单独绘制。浏览器把这个图层发送到计算机的图形处理器(graphics processing unit,即 GPU)进行绘制,而不是像主图层那样使用主 CPU 绘制。这样安排是有好处的,因为 GPU 经过了充分的优化,比较适合做这类计算。

这就是我们经常提到的 硬件加速(hardware acceleration,因为需要依赖于计算机上的某些硬件来提高渲染速度。多个图层就意味着需要消耗更多的内存,但好处则是可以加快渲染的处理时间。

16.3.1.3 合成 Composite

合成(composite 阶段,浏览器收集所有绘制完成的图层,并把它们整合为最终呈现给用户浏览的图像。合成过程需要按照特定顺序进行,以确保图层在出现重叠时,让正确的图层出现在其他图层的前面。

某些属性在属性值发生变更时,需要的渲染时间会更短,尤其是 opacitytransform 这两个属性。在我们修改元素的这两个属性之一时,浏览器就会把元素提升到它们各自的绘制图层并使用 GPU 加速。因为元素位于自己的图层中,所以主图层在整个图像变化过程中不会发生变化,也无须反复重绘(repeated repainting)。

如果只是对页面做一次性修改,这样的优化往往不会带来多么显著的差异;但要是修改的是动画的一部分时,屏幕需要在一秒内发生多达几十次的更新,这种情况下渲染速度的提升就很关键了。大部分的屏幕每秒钟会刷新 60 次。理想情况下,动画中的每一次变化需要的重新计算也至少要达到这个速度,才能在屏幕上生成最流畅的运动轨迹。浏览器在每次重新计算时需要完成的工作越多,达到这个速度也就相应越困难。

使用 will-change 控制绘制图层(Controlling paint layers with will-change)

浏览器在优化渲染流程方面已经取得了长足的进步,会尽可能将一些元素划归到不同的图层。如果对某个元素的 opacity 或者 transform 属性设置动画,现代浏览器为了使动画过程更加流畅,通常会基于包括系统资源在内的一系列因素来作出最佳处理;但有时也可能会遭遇卡顿(choppy)或者动画闪烁(flickering animations)。

如果遇到这种情况,可以使用一个叫做 will-change 的属性来对渲染图层实施控制。该属性可以提前告知浏览器,元素的特定属性将发生改变。这通常意味着元素将被提升到自己的绘制图层中。例如,设置了 will-change: transform 就表示我们期望改变元素的 transform 属性。

除非遇到性能问题,否则不要在页面上盲目添加该属性,因为这样会占用很多系统资源。最好应用前后都测试一下,在性能表现良好时再将 will-change 留在样式表中。想要更加深入地了解该属性的用法,以及是否应该启用该属性,可以查看 Sara Soueidan 的这篇优质文章《Everything You Need To Know About The CSS will-change Property》。

我发现这篇文章发表后,有件事发生了变化:文章表示只有 3D 变换会将元素提升到自己的图层,现在已经不是这样了。最新的浏览器也支持对 2D 变换使用 GPU 加速。

在处理过渡或动画(下一章会重点介绍)特效的时候,尽量只改变 transformopacity 属性。如有必要,可以修改那些只会导致重绘(paint)而不会重新布局(re-layout)的属性。只有在没有其他替代方案的情况下,再去修改那些影响布局的属性,并且密切关注动画中是否存在性能问题。如果想要查看哪些属性会导致布局、绘制和/或合成,也可以访问这个网站:CSS Triggers。

译注

实测发现,介绍 will-change 属性时提到的那篇文章链接已经失效了,要查看原文可以访问这个链接:https://richstyle.org/?documentation/css-will-change-property-en。



关于《CSS in Depth》(中译本书名《深入解析 CSS》)

第 1 版第 2 版
读者评分原版:4.7(亚马逊);中文版:9.3(豆瓣)原版:5.0(亚马逊);中文版:暂无,待出版
出版时间原版:2018 年 3 月;中文版:2020 年 4 月原版:2024 年 7 月;中文版:暂无,待出版
原价原版:$44.99;中文版:¥139.00原版:$59.99;中文版:暂无,待出版
现价原版:$36.49;中文版:¥52.54 起步原版:$52.09;中文版:暂无,待出版
原版国内预订起步价 ¥461.00起步价 ¥750.00

本专栏为该书第 2 版高分译文专栏,全网首发,精译精校,持续更新,计划今年内完成全书翻译,敬请期待!!!

目前已完结的章节(可进入本专栏查看详情,连载期间完全免费):

  • 第一章 层叠、优先级与继承(已完结)
    • 1.1 层叠
    • 1.2 继承
    • 1.3 特殊值
    • 1.4 简写属性
    • 1.5 CSS 渐进式增强技术
    • 1.6 本章小结
  • 第二章 相对单位(已完结)
    • 2.1 相对单位的威力
    • 2.2 em 与 rem
    • 2.3 告别像素思维
    • 2.4 视口的相对单位
    • 2.5 无单位的数值与行高
    • 2.6 自定义属性
    • 2.7 本章小结
  • 第三章 文档流与盒模型(已完结)
    • 3.1 常规文档流
    • 3.2 盒模型
    • 3.3 元素的高度
    • 3.4 负的外边距
    • 3.5 外边距折叠
    • 3.6 容器内的元素间距问题
    • 3.7 本章小结
  • 第四章 Flexbox 布局(已完结)
    • 4.1 Flexbox 布局原理
    • 4.2 弹性子元素的大小
    • 4.3 弹性布局的方向
    • 4.4 对齐、间距等细节处
    • 4.5 本章小结
  • 第五章 网格布局(已完结)
    • 5.1 构建基础网格
    • 5.2 网格结构剖析 (上)
      • 5.2.1 网格线的编号(下)
      • 5.2.2 网格与 Flexbox 配合(下)
    • 5.3 两种替代语法
      • 5.3.1 命名网格线
      • 5.3.2 命名网格区域
    • 5.4 显式网格与隐式网格(上)
      • 5.4.1 添加变化 (中)
      • 5.4.2 让网格元素填满网格轨道(下)
    • 5.5 子网格(全新增补内容)
    • 5.6 对齐相关的属性
    • 5.7 本章小结
  • 第六章 定位与堆叠上下文(已完结)
    • 6.1 固定定位
      • 6.1.1 创建一个固定定位的模态对话框
      • 6.1.2 在模态对话框打开时防止屏幕滚动
      • 6.1.3 控制定位元素的大小
    • 6.2 绝对定位
      • 6.2.1 关闭按钮的绝对定位
      • 6.2.2 伪元素的定位问题
    • 6.3 相对定位
      • 6.3.1 创建下拉菜单(上)
      • 6.3.2 创建 CSS 三角形(下)
    • 6.4 堆叠上下文与 z-index
      • 6.4.1 理解渲染过程与堆叠顺序(上)
      • 6.4.2 用 z-index 控制堆叠顺序(上)
      • 6.4.3 深入理解堆叠上下文(下)
    • 6.5 粘性定位
    • 6.6 本章小结
  • 第七章 响应式设计(已完结)
    • 7.1 移动端优先设计原则(上篇)
      • 7.1.1 创建移动端菜单(下篇)
      • 7.1.2 给视口添加 meta 标签(下篇)
    • 7.2 媒体查询(上篇)
      • 7.2.1 深入理解媒体查询的类型(上篇)
      • 7.2.2 页面断点的添加(中篇)
      • 7.2.3 响应式列的添加(下篇)
    • 7.3 流式布局
    • 7.4 响应式图片
    • 7.5 本章小结
  • 第八章 层叠图层及其嵌套
    • 8.1 用 layer 图层来操控层叠规则(上篇)
      • 8.1.1 图层的定义(上篇)
      • 8.1.2 图层的顺序与优先级(下篇)
      • 8.1.3 revert-layer 关键字(下篇)
    • 8.2 层叠图层的推荐组织方案
    • 8.3 伪类 :is() 和 :where() 的用法
    • 8.4 CSS 嵌套的使用
      • 8.4.1 嵌套选择器的使用
      • 8.4.2 深入理解嵌套选择器
      • 8.4.3 媒体查询及其他 @规则 的嵌套
    • 8.5 本章小结
  • 第九章 CSS 的模块化与作用域
    • 9.1 模块的定义
      • 9.1.1 模块和全局样式
      • 9.1.2 一个简单的 CSS 模块
      • 9.1.3 模块的变体
      • 9.1.4 多元素模块
    • 9.2 将模块组合为更大的结构
      • 9.2.1 模块中多个职责的拆分
      • 9.2.2 模块的命名
    • 9.3 CSS 的作用域
      • 9.3.1 CSS 作用域的就近原则
      • 9.3.2 划定作用域的边界
      • 9.3.3 CSS 中的隐式作用域
      • 9.3.4 关于 CSS 作用域与层叠图层
    • 9.4 CSS 模式库
    • 9.5 本章小结
  • 第十章 CSS 容器查询
    • 10.1 容器查询的一个简单示例
      • 10.1.1 容器尺寸查询的用法
    • 10.2 深入理解容器
      • 10.2.1 容器的类型
      • 10.2.2 容器的名称
      • 10.2.3 容器与模块化 CSS
    • 10.3 与容器相关的单位
    • 10.4 容器样式查询的用法
      • 10.4.1 将模块与所在容器解耦
      • 10.4.2 减少重复代码
    • 10.5 本章小结
  • 第 11 章 颜色与对比
    • 11.1 通过对比进行交流
      • 11.1.1 模式的建立
      • 11.1.2 还原设计稿
    • 11.2 颜色的定义
      • 11.2.1 色域与色彩空间
      • 11.2.2 CSS 颜色表示法(RGB、Hex、HSL、HWB、LAB/OKLAB、LCH/OKLCH)
    • 11.3 利用 OKLCH 处理颜色(上篇)
      • 11.3.4 从页面其他颜色衍生出新颜色(下篇)
    • 11.4 思考字体颜色的对比效果
    • 11.5 本章小结
  • 第 12 章 CSS 排版与间距
    • 12.1 间距设置
      • 12.1.1 使用 em 还是 px
      • 12.1.2 对行高的深入思考
      • 12.1.3 行内元素的间距设置
    • 12.2 Web 字体
    • 12.3 谷歌字体
    • 12.4 @font-face 的工作原理
      • 12.4.1 字体格式与回退处理
      • 12.4.2 同一字型的多种变体形式
    • 12.5 性能因素考量
      • 12.5.1 font-display 属性解析
      • 12.5.2 可变字体的用法
    • 12.6 调整字间距,提升可读性
      • 12.6.1 正文的字间距
      • 12.6.2 标题、小元素和间距
    • 12.7 本章小结
  • 第 13 章 渐变、阴影与混合模式
    • 13.1 渐变
      • 13.1.1 使用多个颜色节点(上)
      • 13.1.2 颜色插值方法(中)
      • 13.1.3 径向渐变(下)
      • 13.1.4 锥形渐变(下)
    • 13.2 阴影
      • 13.2.1 利用渐变和阴影打造立体感
      • 13.2.2 使用扁平化设计创建元素
      • 13.2.3 创建混合风格的按钮外观
    • 13.3 混合模式
      • 13.3.1 为图片上色
      • 13.3.2 混合模式的类型
      • 13.3.3 图片纹理的添加
      • 13.3.4 融合混合模式的用法
    • 13.4 本章小结
  • 第 14 章 蒙版、形状与剪切
    • 14.1 滤镜
      • 14.1.1 滤镜的类型
      • 14.1.2 背景滤镜
    • 14.2 蒙版
      • 14.2.1 带渐变效果的蒙版特效
      • 14.2.2 基于亮度来定义蒙版
      • 14.2.3 其他蒙版属性
    • 14.3 剪切路径
      • 14.3.1 多边形的裁剪路径
      • 14.3.2 Firefox 内置的剪切路径工具
      • 14.3.3 其他剪切路径类型
    • 14.4 浮动与形状
      • 14.4.1 浮动
      • 14.4.2 形状的定义
    • 14.5 本章小结
  • 第 15 章 过渡
    • 15.1 状态间的由此及彼
    • 15.2 定时函数
      • 15.2.1 定制贝塞尔曲线
      • 15.2.2 阶跃
    • 15.3 非动画属性
      • 15.3.1 不可添加动画效果的属性
      • 15.3.2 淡入与淡出
    • 15.4 过渡到自然高度
    • 15.5 自定义属性的过渡设置
    • 15.6 本章小结
  • 附录
    • 附录A:CSS 选择器参考
    • 附录B:CSS 预处理器简介

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/65205.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据之林的守护者:二叉搜索树的诗意旅程

文章目录 前言一. 二叉搜索树的概念1.1 二叉搜索树的定义1.1.1 为什么使用二叉搜索树? 二. 二叉搜索树的性能分析2.1 最佳与最差情况2.1.1 最佳情况2.1.2 最差情况 2.2 平衡树的优势 三.二叉搜索树的基本操作实现3.1.1 详细示例3.1.2 循环实现插入操作3.1.2.1 逻辑解…

利索能及 ▏外观专利相似度多少算侵权?

判断是否侵权前提: 双方产品属于同类产品,不属于同类产品的不能比较。 判定同类产品不仅仅要依据《国际外观设计分类表》,还要依据一般商品商品的分类标准来却确定。 简单概括来说,判定侵权前提就是被控侵权产品和外观设计专利…

【编译原理】往年题汇总(山东大学软件学院用)

🌈 个人主页:十二月的猫-CSDN博客 🔥 系列专栏: 🏀编译原理_十二月的猫的博客-CSDN博客 💪🏻 十二月的寒冬阻挡不了春天的脚步,十二点的黑夜遮蔽不住黎明的曙光 目录 1. 前言 2. …

适用于Synology NAS的在线办公套件:ONLYOFFICE安装指南

使用 Synology NAS 上的 ONLYOFFICE 文档,您能在私有云中直接编辑文本文档、电子表格、演示文稿和 PDF,确保工作流程既安全又高效。本指南将分步介绍如何在 Synology 上安装 ONLYOFFICE 文档。 关于 Synology Synology NAS(网络附加存储&…

SpringbBoot如何实现Tomcat集群的会话管理

在使用 Tomcat 集群时,由于每个 Tomcat 实例的 Session 存储是独立的,导致无法实现 Session 的共享,这可能影响到用户跨节点的访问。为了实现跨 Tomcat 实例共享 Session,可以使用 Spring Session 配合 Redis 进行集中式会话管理。…

机器人C++开源库The Robotics Library (RL)使用手册(三)

进入VS工程,我们先看看这些功能函数及其依赖库的分布关系: rl命名空间下,主要有八大模块。 搞定VS后将逐个拆解。 1、编译运行 根据报错提示,配置相应错误的库(根据每个人安装位置不同而不同,我的路径如下:) 编译所有,Release版本耗时大约10分钟。 以rlPlan运动…

零基础微信小程序开发——页面导航之声明式导航(保姆级教程+超详细)

🎥 作者简介: CSDN\阿里云\腾讯云\华为云开发社区优质创作者,专注分享大数据、Python、数据库、人工智能等领域的优质内容 🌸个人主页: 长风清留杨的博客 🍃形式准则: 无论成就大小,…

Ch9 形态学图像处理

Ch9 形态学图像处理 blog点此处&#xff01;<--------- 四大算子相应性质。 腐蚀、膨胀、开闭之间的含义、关系 文章目录 Ch9 形态学图像处理预备知识(Preliminaries)膨胀和腐蚀(Dilation and Erosion)腐蚀膨胀膨胀与腐蚀的对偶关系 开闭操作(Opening and Closing)开运算闭…

【UE5 C++课程系列笔记】14——GameInstanceSubsystem与动态多播的简单结合使用

效果 通过在关卡蓝图中触发GameInstanceSubsystem包含的委托&#xff0c;来触发所有绑定到这个委托的事件&#xff0c;从而实现跨蓝图通信。 步骤 1. 新建一个C类 这里命名为“SubsystemAndDelegate” 引入GameInstanceSubsystem.h&#xff0c;让“SubsystemAndDelegate”继承…

实战举例——vue.js组件开发

有很多人在问有关Vue的组件开发&#xff0c;虽然之前我的文章里讲过关于前端组件开发的例子&#xff0c;不过作为一个前端技术小白&#xff0c;还是有很多内容需要学习和巩固。我这里用我之前开发过的组件举例&#xff0c;再次为大家简单分享一下基于Vue2和elementUI开发的组件…

devops和ICCID简介

Devops DevOps&#xff08;Development 和 Operations 的组合&#xff09;是一种软件开发和 IT 运维的哲学&#xff0c;旨在促进开发、技术运营和质量保障&#xff08;QA&#xff09;部门之间的沟通、协作与整合。它强调自动化流程&#xff0c;持续集成&#xff08;CI&#xf…

设计宝藏解压密码

设计宝藏官网的解压密码是多少&#xff1f; 设计宝藏解压密码是&#xff1a;memm 设计宝藏一个致力于提供免费资源的宝藏网站。 无论你是Blender、After Effects (AE)、Cinema 4D (C4D)、Premiere Pro (PR)、Photoshop (PS)、Illustrator (AI)的爱好者&#xff0c;还是对CG影…

Android OpenGLES2.0开发(十):FBO离屏渲染

人生是一场单程的旅行&#xff0c;即使有些遗憾我们也没有从头再来的机会&#xff0c;与其纠结无法改变的过去不如微笑着珍惜未来。 Android OpenGLES开发&#xff1a;EGL环境搭建Android OpenGLES2.0开发&#xff08;一&#xff09;&#xff1a;艰难的开始Android OpenGLES2.0…

Magnet: 基于推送的大规模数据处理Shuffle服务

本文翻译自&#xff1a;《Magnet: Push-based Shuffle Service for Large-scale Data Processing》 摘要 在过去的十年中&#xff0c;Apache Spark 已成为大规模数据处理的流行计算引擎。与其他基于 MapReduce 计算范式的计算引擎一样&#xff0c;随机Shuffle操作&#xff08;即…

Pytorch | 利用VA-I-FGSM针对CIFAR10上的ResNet分类器进行对抗攻击

Pytorch | 利用VA-I-FGSM针对CIFAR10上的ResNet分类器进行对抗攻击 CIFAR数据集VA-I-FGSM介绍相关定义算法流程 VAI-FGSM代码实现VAI-FGSM算法实现攻击效果 代码汇总vaifgsm.pytrain.pyadvtest.py 之前已经针对CIFAR10训练了多种分类器&#xff1a; Pytorch | 从零构建AlexNet对…

WebPack3项目升级webpack5的配置调试记录

文章目录 前言一、webpack3环境1.1、知识点记录1.1.1、配置解释1.1.2、webpack与sass版本对应关系1.1.3、CommonJS与ESModule1.1.4、node版本管理nvm1.1.5、sass-loader、sass与node-sass 1.2、其他1.2.1、.d.ts是什么文件1.2.2、react与types/react版本对应关系1.2.3、webpack…

MySQL 数据”丢失”事件之 binlog 解析应用

事件背景 客户反馈在晚间数据跑批后,查询相关表的数据时,发现该表的部分数据在数据库中不存在 从应用跑批的日志来看,跑批未报错,且可查到日志中明确显示当时那批数据已插入到数据库中 需要帮忙分析这批数据丢失的原因。 备注:考虑信息敏感性,以下分析场景测试环境模拟,相关数据…

微信小程序的轮播图学习报告

微信小程序轮播图学习报告 好久都没分享新内容了&#xff0c;实在惭愧惭愧。今天给大家做一个小程序轮播图的学习报告。 先给大家看一下我的项目状态&#xff1a; 很空昂&#xff01;像一个正在修行的老道&#xff0c;空的什么也没有。 但是我写了 4 个 view 容器&#xff0c;…

【RAII | 设计模式】C++智能指针,内存管理与设计模式

前言 nav2系列教材&#xff0c;yolov11部署,系统迁移教程我会放到年后一起更新&#xff0c;最近年末手头事情多&#xff0c;还请大家多多谅解。 上一节我们讲述了C移动语义相关的知识&#xff0c;本期我们来看看C中常用的几种智能指针&#xff0c;并看看他们在设计模式中的运…

微软 CEO 萨提亚・纳德拉:回顾过去十年,展望 AI 时代的战略布局

近日&#xff0c;微软 CEO 萨提亚・纳德拉与著名投资人比尔・格里和布拉德・格斯特纳进行了一场深度对话&#xff0c;回顾了过去十年微软的转型历程&#xff0c;并展望了 AI 时代的战略布局。在这次访谈中&#xff0c;纳德拉分享了他在微软的早期经历&#xff0c;包括他加入微软…