大多数浏览器和
Developer App 均支持流媒体播放。
-
开发高级网页内容
是用 JavaScript、WebGL 还是 WebAssembly 进行开发?敬请了解 Safari 浏览器和 WebKit 的最新更新,例如对类语法的语言做出的更改,如何帮助您简化开发过程、增强性能和提高安全性。我们将探索几个有助于提供更佳互操作性并为网页内容带来新功能的网页 API。
资源
- Introducing Storage Access API
- Safari Release Notes
- Safari Technology Preview
- WebKit Open Source Project
相关视频
WWDC21
-
下载
♪播放重低音音乐♪ ♪ 刘思慧:哈啰 欢迎收看 《开发进阶的网页内容》 我是思慧 我是Safari浏览器 和WebKit团队的工程师 很开心在这里跟大家分享过去一年中 我们为网页开发者 在WebKit和Safari浏览器 所做的重要更新 接下来我要分享的内容 大致上分成三个类别 首先 我要向大家介绍JavaScript中 的新性能和强化 接着我会概括WebAssembly的更新 最后 我会介绍一些新的 网页API 这些能够在你的网页内容中 添加附加功能 要说的内容很多 就让我们从JavaScript的新内容开始 每一年 我们在JavaScript引擎上 都会做上百项的更动 我会介绍一些大家使用JavaScript 需要知道的重要内容 包括:新的类字段语法 优化内存管理的弱引用 等待关键词的新用法 支持Web workers的模块 以及增加到国际化API 家族上的界面 为了让大家更了解这些新性能 我用一个简单的计时器当范例 这个计时器只有一个按钮 单击它就开始计时 再单击 它就会停下来 并且告诉你经过多久的时间 先记住这个 我们待会会在JavaScript中执行它 现在 让我们来看看 新的类字段语法 我们有新的私用类字段和方法 让你来定义通过语言保护存取 的真正私用成员 如果你破坏存取规则 就会出现错误 我们也增加支持静态字段 让大家可以不用在类别中建立实体 就宣吿能存取的 类别成员 现在各位有基本的概念了 让我们来看看它要如何用在 计时器的范例中 当你进行计时器类别的实作时 你的实作界面看起来会像这样 StopwatchWithOneButton 只有一个叫做“click()”的方法 它会检查startTime变量 如果没有设定起始时间 那么按下代表“开始“ 那么它就会设定起始的时间 如果起始已经已经设定了 那么按下代表“停止” 它会计算经过的时间长度 并且重新设置起始时间 大家可以看到startTime 有一个前缀底线 这是经常用来表示 变量只能用在这个类别中的命名规则 不过那样没办法预防 起始时间被公开存取 新的私用语法可以帮忙修正这个问题 只要把底线换成#字号 你就可以宣告真正的私用实体字段 封装是通过语言来执行的 同时也有支持私用方法 例如 要让click()方法更结构化 我们可以建立两个私用方法: start()和stop() 来取代要强调的内容 像这样 在方法前面加上井字号 我们能确保成员功能 只能从类别里面被存取 新的私用语法同样能用在静态字段上 例如startedStopwatchCount 这里 startedStopwatchCount 只能够用定时器对象的 起始或结束时间来调整 当然 如果你希望 startedStopwatchCount 在任何地方都能被存取 你可以把它宣告为公共静态字段 不要加前缀#字号 现在WebKit也有公共静态字段了 私用实体字段、方法 私用静态字段和公共静态字段 这些是我们新支持的类别字段 让我们继续介绍下一个性能 弱引用 弱引用让你用一种 能避免垃圾回收的方式 拥有JavaScript对象的参考 不像弱映射和弱集合 你可以在还没有参考的时候 就取得潜在的对象 这个支持同时包含 垃圾回收的通知 因此如果有必要 你可以执行一些清理的工作 让我们来看看它怎么使用 我们刚才实作了计时器类别 现在 想象你替不同的任务 建立许多个计时器对象 为了要测试 你必须同时按下它们 你会怎么做呢? 最直觉的方式是 把所有计时器实例设成一个集合 建立计时器的时候 把它放到集合里 接着在clickAllStopwatches功能中 重复这个集合 和按下每一个计时器 不过用这个方法会遇到一个问题 我们知道JavaScript对象 有预设的强参考 所以在这个例子中 所有的计时器对象都无法被清除回收 因为集合还保有它们的参考 当然 我们不会希望留下 所有测试用的计时器对象 这样对内存的使用不太好 你可能会建议直接用弱集合取代集合 可是弱集合没办法重复 那么你要怎么办? 我们可以用新的界面WeakRef来解决 它具有对象的弱引用 我们还是有集合 不过这次我们把计时器对象的 WeakRef加到集合上 在clickAllStopwatches功能中 我们能在按下前 通过反参考 检查对象是否还存在 这样似乎能解决我们的问题 不过还有另一个问题 我们并没有及时从集合中 移除垃圾回收的计时器 在我们下个测试开始前 集合可能会变得很大 现在我们该怎么办? 另外一个新界面 FinalizationRegistry 应该可以帮上忙 有了这个 你可以在某些对象 被回收清空时 叫出特定的回调 这里我们建立一个 具有removeStopwatch功能的 finalizationRegistry对象 每次有对象的回收时 这个功能就会被叫出来 接着我们把计时器对象 登录到登录档上 每个计时器都连结到一个标识符 所以removeStopwatch知道 要移除哪一个计时器 很好 现在被垃圾回收的计时器 能够从allStopwatches移除了 弱引用的使用听起来不难 对吧? 不过大家要知道 在JavaScript中的垃圾回收 是非常复杂的 其中有很多不确定性 举例来说 你认为应该要被回收的对象 可能要很久以后才会被回收 还有你可能不会马上从 FinalizationRegistry取得回调 因为它在执行事件循环 因此 在使用前一定要彻底认识 语法和它的预期行为 让我们结束弱引用 进入下一个性能 顶层等待 这是模块的新性能 它让你能在异步功能外 使用等待关键词 在这个例子中 模块本身就像一个 很大的异步功能 所以异步模块可以阻止 输入它们的模块执行 让我们看一下计时器类别的例子 这是我们刚刚建立的类别 要说明顶层等待的使用 我们先把它变成一个模块 并且输出它的类别 这是一个包含内联模块的HTML档案 它会以动态输入来输入计时器模块 输入功能会回传一个实现 所以输入完成后 我们可以用 “then”或抓取方法来执行动作 有了顶层等待 你可以移除链式方法 并且以同步的方式来写编码 这样能使你的编码更容易理解 另外 输入的模块 在加载时会受到评估 因此异步模块可以根据这个 来阻止模块的执行 那表示当计时器模块执行异步操作 并且在等待结果时 这里的计时器变量就会在 计时器模块结束执行后被初始化 有了顶层等待 要做依赖管理就更简单了 不过再强调一次 这个性能只有在模块中才有 如果命令不是模块 像这样…
你会在网页检阅器上看到语法错误 说到模块 还有另一个相关的性能: 工作者模块 工作者有一些众所皆知的优势 它可以在背景线程中执行命令 因此可以更有效地利用资源 有了这个新的支持 现在工作者能享有模块的优势 包含动态输入、优化加载和执行 以及依赖管理 让你可以更简单地将繁重的工作 从主线程搬移到背景线程 目前可以在不同类型的工作者中 使用模块 包含Web worker、Worklet 和服务工作线程中 要在Web workers和服务工作线程中 建立工作者模块 你必须在选项中 将型态指定为模块 至于worklet 像是Audio Worklet 你可以用addModule功能 要建立能让你的应用程序速度变快 的工作者模块很简单 在JavaScript的最后一部分 是国际化API的更新 这个API提供 基于语言的格式 如果你的网页内容 是针对不同的语言环境设计的 这会是很有用的更新 为了向大家示范如何使用 我建立了这个计时器纪录页面 因为计时器需要记录下时间 和我们新释出的性能 这个页面显示了 单一用途计时器的细节 包含经过的时间长度、起始时间 事件、参与者 和页面可使用的语言 现在 让我们深入每个部分 并且仔细看看每个界面 第一个是NumberFormat NumberFormat提供 对语言敏感的数字格式 它是用来格式化经过的时间长度 NumberFormat的建构子 有两个选择性参数: 语言和选项 这里我把语言设成英文 然后我建立两个选项对象 用来指定每个数字分别为几位数 在以语言和选项建立 两个NumberFormat对象后 我们可以用它们来设定 经过时间长短的数字格式 这里 如果数字不是毫秒 我会用Format1 保留两位数 不然的话 我会使用Format2 保留三位数 大家可以看到 格式方法 会自动帮我们把“零”加上去 你有很多不同的选项可以用来 建立你需要的格式 例如样式 你可以将值指定为货币格式 或单位格式 接下来是DateTimeFormat 它允许写入对语言敏感的 日期和时间格式 它的使用和NumberFormat类似 首先 设定语言 接着 设定选项 在选项中 我把日期和时间 设定成不同的样式 DateTimeFormat对象 能提供细粒度组态 甚至能让你指定秒或毫秒的样式 在那之后 我们可以用参数建立 DateTimeFormat对象 并且用它来格式化我们的起始时间 结果会以英文呈现 各位可以看到日期比较详细 因为它套用的是长样式 下一个是分词器 它能让你做 对语言敏感的字符串分割 我用它来找事件句子的关键词 这是中文版的计时器纪录页面 首先 我宣告一小串 我想要强调的关键词 事件字符串甚至包含 用在摄氏符号的统一码 这里我们把语言指定为中文 在选项中 将粒度设定为词 其他可能的值 是字位和句子 接着我们建立一个分词器 通过分割方法 用分词器来分割字符串 我们可以重复结果对象 来取得所有的片段 检查看看每一个片段 是不是都含在关键词列表 以用来标注它 分词器对于口译很有用 像是中文里面 词的界线不是很明显 下一个是ListFormat 它能格式化对语言敏感的列表 和前面一样 我们可以指定语言和选项 ListFormat不像其他界面 有那么多选项 我觉得最有用的是型态和样式 有了语言和选项 我们可以建立ListFormat 并且格式化我们的参加者名单 就像大家看到的 因为型态是链接 样式是长样式 格式方法在结果中加上逗号 以及一个“和”字 最后一个是DisplayNames 它替语言、区块和命令 提供显示名称的连贯翻译 这里我将语言指定为日文 DisplayNames可以拿语言的编码 做为输入 在选项中 我们把型态设为语言 接着我们可以建立DisplayNames对象 这里 用of方法 我们可以得到翻译后的结果 虽然这个页面是用英文建立的 日文用户可以知道有支持哪些语言 这就是我如何使用新的国际化界面 建立计时器纪录页面 来帮大家恢复一下记忆 列出来的是我们刚刚 在JavaScript这部分看过的内容 接着 下一站是WebAssembly的更新 我们推出WebAssembly引擎 已经好一阵子了 不过怕有人对它不太熟悉 让我先从一些WebAssembly的背景 开始介绍 WebAssembly是一个使用 二进制指令格式的堆栈式虚拟机 它是能在现代网页浏览器执行时 有接近原生码表现的编码 WebAssembly被设计为 在携带型设备上的编译方式 它是类似C、C++或Rust 这类程序语言 因此WebAssembly可以帮我们 把以那些语言写下的应用程序 配置到网页上 在WebAssembly多数的使用案例中 它和JavaScript一起运行 它们能通过WebAssemblyAPI 彼此沟通 WebAssembly能提供接近原生的表现 并且在网页上做出更强大的框架 JavaScript则可以操作 文件对象模型 并且提供强大的网页API 它们彼此能相辅相成 时髦卡丁车是使用WebAssembly 很棒的例子 它是用Emscripten编译器把C++ 转换成WebAssembly的游戏 就像大家看到的 它在Safari浏览器中跑得很顺畅 今年 我们在WebAssembly引擎 升级了下列性能:新的内存指令 让你在海量内存作业时 有更好的表现 像是复制或初始化内存区块 新的指令告诉用户处理程序 不要卡在例外上 像是 在整数和浮点数之间转换时 出现的正溢位 新的符号延伸运算符 让你能延伸有号整数的 执行在WebAssembly类型i64 和JavaScript BigInt之间 转换的最新方案 这比之前的解决方案更简单 而且可以让你的编码运作得更快 WebAssembly模块具有对JavaScript 和文件对象模型对象 引用的新引用类型 将它们以自变量传出去和储存 最后 串流下载和能缩短整体 执行时间的WebAssembly编码 这些是我们在WebAssembly 新性能的重点 希望这些能帮助大家的开发 现在 让我们从强大的低阶编码 移动到一些高阶的API 在这个段落中 我们会探索新的网页API 我的目标不只是让大家 认识这些新的性能 而是让大家觉得准备好能使用它们 所以大家会看到一些很好的范例 不过这并不是完整的教学 记得在使用前去查看官方说明书 先让大家看一下我会讲到的性能 有些是全新的性能: 例如语音识别 有些则是之前就有的 不过我们有些想跟大家分享的更新 像是储存访问 现在 让我们一个个深入来看 大家都知道 要让网页内容吸引人 很重要的是提供让人惊艳的视觉体验 在WebKit和Safari浏览器 可以使用WebGL2 让你能更容易的建立 漂亮、互动式的网页内容 这是有一个以WebGL2 能做出来的例子 “洪水之后”是由PlayCanvas开发的 互动式样品 你可以看到微风让树晃动 它在Safari浏览器中看起来栩栩如生 那么WebGL2是什么? WebGL是一个广泛用来做 2D和3D绘图的 低阶API WebGL2是WebGL的升级版 它排除了回退机制 并且导入一些很厉害的新性能 它能加入3D材质来渲染体积效果 像是云 它有样本对象 让你能够灵活地 在着色器中使用材质 它提供变化反馈 帮助你在GPU上 实作性能粒子系统 在WebGL2中有很多很棒的性能 更重要的是 WebGL2现在在所有Apple装置的 Safari浏览器上都能使用 这代表说你可以架构一个 不论在哪里看起来都很棒的网站 让我们用一个例子来更熟悉WebGL2: 做出一个橘色的正方形 这是你需要帮它写的JavaScript编码 如果你过去没有使用过WebGL 这可能不像你想象中那么简单 我刚刚说过 因为WebGL是低阶API 它可能会很冗长的 不过不用担心 有很多很棒的函数库和框架 能帮助你简化你的开发 有了这些 要做出一个漂亮的正方形 或比那个更复杂的东西就没那么难了 如果你已经在你的网页内容中 使用WebGL 我们也有个好消息 我们将后端从OpenGL移转到Metal 来改善我们的支持 代表说现在iOS模拟器可以 将GPU用在网页内容上 让你的使用者能看到 更精准的画面 同时 你也可以使用Metal工具 例如:Xcode Frame Debugger 来分析你的WebGL编码 除了以WebGL建立内容 另一个提供优良视觉体验的常用方法 是通过影片 不是所有的浏览器都支持相同种类的 媒体格式 因此有时候要决定使用哪一种格式 是蛮困难的 为了事情容易一些 今年我们新增支持WebM 这种常用在网页上的媒体格式 一开始 只支持串流播放 在macOS 11.3中 我们增加支持 播放包含VP8或VP9影片的WebM档案 以及Vorbis音频 在macOS 12中 我们增加支持包含Opus音频的档案 去年 我们开始支持WebM在macOS上 进行媒体源扩展 现在我们把这项支持带入iPadOS 15 要检查WebM是否支持你的编码 你可以使用 MediaCapabilitiesAPI 它能让你准确地侦测 你想使用的媒体组态 最新的Safari浏览器 会支持屏幕上的组态 也就是说现在也支持VP9了 支持了这个影片编码格式 我们预期在Safari浏览器 和WebKit应用程序上 会有更多的网页内容 你在串流和WebRTC中都可以使用VP9 它能在macOS和iPadOS上运作 关于不同装置上的支持 现在在所有配载Apple Silicon芯片的 Mac都能使用 其他装置可以用MediaCapabilities API来检查 就像我们刚刚看到在WebM上那样 如果你的网站有WebM或VP9内容 我鼓励大家看一下它如何在最新的 Safari浏览器和WebKit上运作 不过如果你还在决定 要用哪一个媒体格式 我们会建议H.264或HEVC H.264很成熟 在不同浏览器之间 有很好的支持 HEVC对于高画质影片有很好的支持 它们都有硬件加速 能提供更流畅的回放 以及更长的播放电池寿命 说到放上影片内容 常见的例子是我们并不拥有那个内容 而是我们从第三方取得的 例如 我在video.domain上 看到这个很棒的影片 我想让它在我的网页 main.domain上出现 我可以从video.domain 载入这个影片来源 或者我可以直接建立 video.domain的内联框架 基于安全考虑 第三方内联框架或资源 无法以预设值存取第一方的储存区 意思是说 如果要求video.domain的资源 是由main.domain发起的 它就不会包含video.domain的 信息记录程序 当video.domain的网页服务器只想 将内容提供给经过授权的合法使用者 就会产生问题 没有信息记录程序代表没有授权 储存访问API 解决了这个问题 它让第三方内联框架能要求 存取第一方信息记录程序的权限 如果使用者授予权限 那么第三方video.domain 就能存取它的第一方信息记录程序 储存访问API在WebKit 和Safari浏览器上面已经超过三年了 为了改善互操作性 今年我们加入两个新的性能 第一个 存取授予的范围是每个页面 意思是说 一旦将权限授予第三方 就会延伸到它同一个页面上 所有的子资源 你不需要针对内联框架提出要求 第二个 我们允许巢状内联框架 来提出要求 意思是在内联框架内的内联框架 也可以要求存取第一方信息记录程序 这在过去是做不到的 想更了解新的使用方式 请看我们在webkit.org的贴文: 《储存访问API的更新》 现在我们知道如何在有需要时 以用户权限从第三方载入 或输入影片内容 那么如果是自己建立一些内容呢? 有了新的Media RecorderAPI 这变得很简单 Media RecorderAPI 能让你从媒体元素中撷取数据 包括HTML媒体元素 像是影片标签 或MediaStream对象 你可以用它从使用者的输入设备 进行录制 你可以指定想要的选项 例如容器的MIME类型 或者想要的音频频率位元 这个API很简单 它是由单一的主要界面 MediaRecorder所组成的 MediaRecorder会处理所有 从来源收集数据和传送给你的工作 我让大家看一个例子 我用MediaRecorderAPI 来建立这个网页应用程序 叫做“声音备忘录” 这是我的第一个声音备忘录 按下按钮 它就开始从麦克风录音 再按一次 它就会停止录音并且提供回放 这是我的第一个声音备忘录 这很有趣 现在让我们来看看它的实作 我们有两个主要的功能: startRecording和stopRecording 在startRecording中 我们从麦克风取得输入媒体串流 接着我们用它建立一个 MediaRecorder对象 我们监听媒体录制的两个事件 接下来我们用开始方法来启动录音器 要停止录制 我们只要叫出 在mediaRecorder上的停止方法 这里有两个事件处理器 当已经有一些撷取到的数据 我们把它放到数组中 当录制停止时 我们用数组中收集的数据 来制作二进制大型对象 然后把它传到既有的音频元素来播放 像那样 你就可以建立 实用的语音录制器 在你收集音频资料后 你可能会想要编辑它 在这个例子中 你可以让 新的Audio WorkletAPI 发挥很棒的用途 Audio Worklet界面是 Web AudioAPI的一部分 如果以曾经在网页上处理音频 那么你可能已经对它很熟悉 它让我们可以执行命令: 例如JavaScript或WebAssembly编码 来处理在音频渲染线程上 支持使用者AudioNodes的音频 和ScriptProcessorNode 这个过去用来执行使用者命令 的解决方法比起来 它减少了在渲染线程和主线程 之间的跳跃 并且确保了低延迟 有了Audio Worklet 我在我的声音备忘录加上一个新功能 这是我变声后的声音 如果录制时勾选了变声器 音频就会加上变声的效果 这是我变声后的声音 这听起来很酷 让我们来看看它的实作是怎么进行的 我修改了startRecording功能 来增加音频处理 我们还是需要先用MediaStream 来做音频输入 要使用Audio WorkletAPI 有四个基本的步骤 第一步:建立一个来源 第二步:建立AudioWorkletNode 并且把它和执行音频处理的 Audio Worklet处理器连结在一起 处理器是在模块中执行 我们等一下会说明 第三步:建立一个目标 第四步:将来源到目标的路径 连接在一起 这次MediaRecorder会拿 从AudioWorklet来的输出当作来源 而且它会录下变声后的音频 这是音频处理模块 我们在这里实作 DistortionProcessor类别 它一定要延伸 AudioWorkletProcessor类别 以及以一定要提供 处理功能的实作 输入是进到Audio Worklet 的音频样本 输出则是处理后得到的样本 你可以用不同的算法来建立输出 这里 我用叫做“distort()”的 用户功能 根据输入来计算值 处理功能回传“是” 代表处理器节点是激活的 这是处理功能的基本结构 建立处理器类别后 我们需要将它全面性登录在 特定的名字下 那么它就能用来建构 AudioWorkletNode 像这样 你就可以把声音效果 加入你的音频数据中 到目前为止我们讨论了 创造和处理音频数据 那如果你想要储存你的录音 或是分享到其他地方呢? 我猜你不会想要在关掉浏览器之后 就失去这个录音 今年在网页分享API的更新 让你可以很轻易就做到 网页分享不是WebKit 和Safari浏览器的新功能 如果你选择要在Safari浏览器中 分享一个网页连结 就会出现分享页面 上面有分享对象 像是Messages、邮件或隔空投送 和系统类型能相对应的分享页面 是由网页分享API所建立的 今年 我们添加支持档案分享 也就是说用这个API 你能分享图片、影片、音频 或或其他类型的档案 让我们在声音备忘录加上分享的功能 如果勾选了储存框 声音备忘录会用撷取的数据 建立一个音频档案 并且出现一个分享按钮 让我们来分享档案 这里 我想通过电子邮件 分享这个备忘录档案 只要单击 就能建立一封 夹带备忘录档案的草稿 让我们来看看编码 这是我们在MediaRecorder范例中 看到的停止事件处理器 首先 我们把停止事件处理器中 的二进制大型对象变量设为全局 这样就能用在分享功能中 分享功能是分享按钮 的点击事件处理器 它会把二进制大型对象转换成档案 并且给它一个文件名 档案会放在数组里 因为那是预期的输入类型 接着我们检查是否能用API 以及档案是否能用canShare方法分享 如果通过检查 我们就叫出有档案数组的 navigator.share 有一些你可以指定的选项 像是标题和描述文字 要让你的网页应用程序 像原生应用程序那样分享档案 就是这么简单 嗯 如果你并不打算和音频数据 有所互动 而只是想要它的文字 像是在语音指令的案例中 我们也有个新的API 那就是语音识别 就像它的名称一样 语音识别API 能撷取实时音频并且将它转译成文字 同时它还会给你文字译本的机率 和替代选项 它是使用和Siri相同的语音引擎 而且它取得所有的优势: 支持多国语言和优异的准确度 那也表示说你的使用者需要在 系统偏好或设定中打开Siri或听写 才能使用这个API 辨识可以是基于服务器的 因此在应用程序 第一次使用辨识服务时 我们设置了隐私权提示 用户可以在系统偏好或设定中 更改权限 现在 让我们用这个新功能 来更新声音备忘录 如果勾选了辨识框 代表说从录音产生文字译本 这是我的声音备忘录文字译本 句号 让我们来看看编码 它的用法和媒体录制有点像 这里我们有两个主要的功能: startRecognition 以及stopRecognition 你需要先建立一个 webkitSpeechRecognition对象 没错 考虑到兼容性 我们暂时还是要保留前缀WebKit 不要忘了把它加上去 然后你可以设定一些辨识的属性 像是连续 这会要求辨识一直进行到 被停下来的时候 我们监听结果和最终事件 通过辨识对象 我们可以叫出开始方法来启动 并且叫出停止方法来停止 在结果事件 我们把 finalTranscript收集成字符串 这里 我只挑选结果的第一个项目 因为转译替代选项 是根据机率分类的 当辨识停止时 我用用户日志功能 将文字译本打印到屏幕上 这样一来 你可以只用几行语法 就将辨识功能添加到你的网页内容中 我们已经讲了很多 不过我认为最后还有一个 值得一提的网页API 你可以已经注意到 在macOS和iOS上 “现在播放”挂件能显示 你在Safari浏览器的媒体状态 这很方便 可是上面通常没有太多信息 例如 这个只有显示网页的标题 没有其他关于正在播放音频的信息 有一个新的API 能帮你改善这个状况 媒体会话集API 媒体会话集API能让网页 和其他平台组件之间的媒体状态相通 如果你希望能让使用者在网页外部 看到或控制媒体状态 像在“现在播放”挂件里面那样 这是你需要知道的API 关于媒体会话集API的更多信息 请看我们WWDC中 《在网页上以GroupAcitivities 整合媒体播放》 这些是我们刚才探索的新功能 我希望各位觉得你们学到一些东西 大家今天的功课 是用这些新的API 实作你自已的声音备忘录 开玩笑的 不过确实希望大家可以帮忙几件事 协助我们在WebKit和Safari浏览器中 带给各位最棒的开发体验 请大家在最新的WebKit 和Safari浏览器中试试看新的性能 并且将程序错误回报到 bugs.webkit.org 大家可以从Safari浏览器 技术预览版 抢先看新的性能 或是在激活开发下的性能 如果你对于在WebKit或Safari浏览器 使用的网页技术有兴趣 或有兴趣加入WebKit社群 webkit.org是很棒的资源 如果你想取得WebKit的最新消息 或者你对我们有任何问题 记得在推特上追踪或标注我们 谢谢大家收看这段介绍 希望大家在WWDC有很棒的时光! ♪
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。