Session 234: What’s New in Safari and WebKitjavascript
这个Session介绍了Safari与WebKit的新特性,主要面向三类人群html
这个Session主要围绕着与浏览器技术相关的新特性与新功能,而且和大会的其余煊赫一时的议题好比ARKit
,WatchOS
,都有相关和联动,极大地加强了Web技术的功能与性能。整个 Session 介绍的各类新功能相对来讲比较琐碎,主要包括三大部分:java
这一大块主要凸显苹果对安全以及用户隐私方面的重视,小到规范获取受权的提示,跨端的密码自动填充,大到网页上干扰广告商经过 cookie 定位跟踪用户,一种值得尊敬得企业态度。ios
在安全方面,Session上来就宣布了一件重量级的大事,UIWebView正式被官方宣布废弃,建议开发者迁移适配到WKWebView。在XCode9中UIWebView仍是 NS_CLASS_AVAILABLE_IOS(2_0)
,而咱们从最新的Xcode10再看UIWebView就已是这个样子了web
UIKIT_EXTERN API_DEPRECATED("No longer supported; please adopt WKWebView.", ios(2.0, 12.0)) API_PROHIBITED(tvos, macos)
@interface UIWebView : UIView <NSCoding, UIScrollViewDelegate>
复制代码
WKWebView从诞生之初相比UIWebView有太多的优点,不管是内存泄露仍是网页性能,而且WKWebView能够同时支持macOS与iOS。因为WKWebView的独特设计,网页运行在独立的进程,若是网页遇到Crash,不会影响App的正常运行。objective-c
可是WKWebView不支持JSContext,不支持NSURLProtocol,Cookie管理蛋疼等问题确实给让很多开发者不想丢弃UIWebView,但最后通牒来了仍是准备着手替换吧。macos
safari扩展开发的历史promise
在macOS上,有一个Safari扩展的商店 Safari Extensions Gallery
,如今这个扩展商店也要退出历史舞台了,苹果但愿开发者逐渐转移到 App Extensions 开发,最终提交到 AppStore
而不是开发Safari浏览器插件,提交到 Safari Extensions Gallery
,这个期限会持续到2018年末,以后 Gallery 就再也不接受提交了。浏览器
早在好久以前,已经全面要求开发者适配HTTPS了,但若是开发者在我的网站上引用了存放在第三方平台的子资源,诸如 HTML/CSS/JS ,若是该资源在第三方平台出现了篡改等问题的发生,将致使咱们的网站会遭受攻击缓存
为了应对这种安全问题,Safari在新的版本里对HTML标签加入了一个新的属性 integrity
用来填写当前要引用的子资源的Hash值,若是该子资源下载完毕的时候发现Hash值和 integrity
属性不一致,则会直接放弃加载该资源,这个属性适用于一切子资源,JS/CSS等
<script src="https://thirdparty.example/framework.js" integrity="sha384oqVuAfXRKa+R9GqQ8K/ux"></script>
复制代码
在WWDC第一天的开场大会上,介绍到了在本届 WWDC,Apple 全面增强了用户隐私相关的保护,不管是用户设备指纹追踪,仍是网络浏览行为追踪,表现出了,苹果很是在乎保护用户的我的隐私。而在本场 Session 进一步介绍了如何智能的防止隐私追踪,Cookie 是这项技术的关键之一。
不少广告/搜索进行的用户行为追踪,致使用户刚搜过什么东西,在别处广告就能看到对应的商品推荐,主要靠的是建立一种惟一识别用户的 token,并将这 token 存入除了当前网站以外的第三方网站cookie,从而作到访问任意网站的时候可以追踪到用户在其余网站作过什么。
那么问题来了?当用户确实须要跨网站之间同步登录状态等用户信息怎么办?
Storage Access API
Apple 开放了专门用于存储读取这类用户敏感信息的 API,在使用这个 API 的时候会,苹果会向用户发起询问弹框,询问用户是否容许此类信息追踪,Storage Access API 的代码也很简单
function makeRequestWithUserGesture() {
let promise = document.requestStorageAccess();
promise.then(function () {
// Storage access was granted.
// Check whether the user is logged in.
// If not, do a popup to log the user
// in.
}, function () {
// Storage access was denied.
});
}
复制代码
iOS12 会在用户须要建立一个用户名和密码的时候,自动生成一个强密码,包含了大小写,数字,特殊字符等等。而且这个强密码会被保存到用户的 KeyChain 之中,将来在访问当前网站的时候自动填充登录,用户也能够在设置中查询已经生成的各个网站的密码,
对开发者来讲,这个功能能够彻底不作任何开发适配自动生效 Apple 默认的强密码规则,开发者也能够在本身的网站自定义强密码的规则
自动填充短信验证码,这个功能依然不须要开发者作任何适配自动填充,短信验证码会被填充到输入法里,快速录入到目标输入框
本届 WWDC 上来在介绍 iOS12 的时候就强调了软件性能,苹果作了巨大得努力,得到了巨大程度的提高。而在 Web 在浏览器上,一直被人诟病说表现力不如 Native ,性能流畅度不如 Native。而这一个大块内容就重点介绍了 Apple 是如何全面优化 web 的表现力与流畅度的。
Safari新增了一种能够将一些固定字符集的多种字体打包在一块儿,造成一个固定字符集的字体合集用来加载,此举能够大幅度减小多字体状况下的字体包下载大小,Session中提到的例子,使用了Font Collection,须要下载的全部字体体积降低了了84%
原理是多种字体在相同字符集下,能够共享同一个字符表,每个字符的编码下对应存储多个字体的字形glyph,从而减小空间上的冗余。
当一个网页使用了自定义字体,那么Safari会先用空白区域占位,而后去下载该字体,等下载完毕后在刷新出新的字体,若是这个过程 web 开发者想进一步的本身控制,就须要 font-display
这个 CSS 属性
font-display
是一个新的 CSS 属性,已经在 Chrome & Chrome for Android 率先获得了支持,此次 Safari 跟进了对这个属性的支持。
Session 中并无讲太细致这个 CSS 到底该如何使用,目前有5种效果能够进行选择,样例中用的是 font-display: fallback;
此外还有 auto/swap/optional
网页中常常要播放动图,动画,咱们通常都会使用 Gif 图,但 Gif 图加载时间太长了,所以开放了直接在 Image 标签中加载视频。而且 Safari 会使用内置的视频解码技术对视频进行最佳的渲染。
代码也很是简洁,不管是写一个HTML标签,仍是写在CSS里,都支持
//html 写法
<img src="explosion.mp4" alt="Color Explosion">
//CSS 写法
body {
background-image: url("explosion.mp4");
}
复制代码
这个 feture 大幅度优化了 Web 的滚动性能
在本来的 Safari 事件监听实现里,若是在滚动中触发了 addEventListener() 的事件监听,滚动会等待 JS 事件监听处理完毕,再继续滚动。
本次的被动事件监听优化,就是专门针对这种状况致使的可能的卡顿。被动监听做为一个标记位在 addEventListener() 的时候传入,当这个标记开启的时候,滚动不会等待 JS 事件监听执行完毕在继续,从而保证了流畅度。
新的 Web API 可让JS自由的进一步控制DOM的异步图片解码,这里代码举个例子:页面中的一个图片,在点击的时候,加载下一张图片,而后淡淡地动画过分到新图片
//读取要加载的新图片dom 和 新图片 src
const img = this..currentItem.getElementsByTagName('img')[0];
const unloadedSource = img.getAttribute('data-src');
//新图片加载(会异步加载,不会卡主线程)
if(unloadedSource){
img.src = img.getAttribute('data-src');
}
//播放一个淡出动画,在老图片淡出,透出下面的新图片
const transition = () =>{
this.bringElementToFront(this.currentItem);
this.currentItem.classList.add('fade-in');
this.currentItem.onanimationend = () =>{
this.currentItem.classList.remove('fade-in');
};
}
transition()
复制代码
这段代码中最大的问题在于,当对 img.src 赋值的时候,web就开始异步加载图片了,但JS代码会马上开始执行下面的动画效果,图片还没加载完,动画效果执行过程当中出现了闪烁。
如今图片元素有了新API decode(),这个 decode() 会返回一个 promise ,当图片在异步下载解码完成后会触发。
//读取要加载的新图片dom 和 新图片 src
const img = this..currentItem.getElementsByTagName('img')[0];
const unloadedSource = img.getAttribute('data-src');
//新图片加载(会异步加载,不会卡主线程)
if(unloadedSource){
img.src = img.getAttribute('data-src');
}
//播放一个淡出动画,在老图片淡出,透出下面的新图片
const transition = () =>{
this.bringElementToFront(this.currentItem);
this.currentItem.classList.add('fade-in');
this.currentItem.onanimationend = () =>{
this.currentItem.classList.remove('fade-in');
};
}
//使用新 decode() Api 实现当解码完成的时候再执行动画效果
img.decode().then(transition)
复制代码
这个 Beacon API 可不是苹果他们家那个 iBeacon 设备与手机通讯的东西哟!。
Beacon API 是 W3C 的一项新标准新 API,这个 API 主要用于发送不须要服务器回应的HTTP请求,Chrome && Firefox 彷佛已经实现了,如今 Safari 跟进了这个功能。
这个API有什么用?
unload
状态下,也会异步发送出去统计,不影响过渡/跳转到下个页面举个例子:当按钮点击,调往下一个页面的时候,咱们但愿发送一条数据请求给服务器,通常状况下浏览器发起请求都是发起异步的请求,但如今这个例子里,一旦发生跳转,当前页面即将销毁,这个网络请求会被浏览器忽略,为了保证数据发送成功,就得使用同步网络请求,就会致使页面先卡一会,请求完成后再跳转新页面。
document.body.addEventListener('click',function(event){
if(event.target.tagName == 'A'){
const data = `from=${window.location.href}&to$(event.target.href)`;
const xhr = new XMLHttpRequest();
xhr.open('POST','/Event',false);//注意这里 false 表示这里强制同步网络请求,会卡
xhr.send(data);
}
},true)
复制代码
有了不须要回应的 Beacon API,在这个例子里咱们就能够不用让页面卡一下在跳转了,而且 sendBeacon() 这个 API 也比 XMLHttpRequest 简洁好多。
document.body.addEventListener('click',function(event){
if(event.target.tagName == 'A'){
const data = `from=${window.location.href}&to$(event.target.href)`;
//判断浏览器是否支持 Beacon API
if (navigator.sendBeacon){
navigator.sendBeacon('/event',data);
}else{
const xhr = new XMLHttpRequest();
xhr.open('POST','/Event',false);
xhr.send(data);
}
}
},true)
复制代码
若是说安全与性能都是优化层面,那么这一大块内容就是不折不扣的新功能了,更复杂的 Web 交互,Web 的移动支付,Web AR展示,甚至是 watch OS 上的 Web,让咱们好好感觉一下 Safari 的新能力
新的 Safari 提供了拖拽 API,这个 API 也是 H5 的标准API,此次 Safari 跟进了支持。
下面看个简单的例子
dragzone.forEach(function(element){
element.addEventListener('dragstart',function(event){
event.dataTransfer.setData('text/plain',element.textContent());
});
});
dropzone.addEventListener('drop',function(event){
event.preventDefault();
const li = document.createElement('li');
li.textContent = event.dataTransfer.getData('text/plain')
goodList.appendChild(li);
dropzone.classList.add('has-items');
});
复制代码
恩,没错,苹果支付如今开放给 Web Safari 了,而且是遵循的 W3C 的标准 Payment Request API 从而对接到苹果支付上。
简单的例子:
payButton.addEventListener('click',function(event){
if (window.PaymentRequest){
const method = {
supportedMethods:"https://apple.com/apple-pay",
data:{
version:3,
merchantIdentifier:"example,outdoorsy",
merchantCapabilities: ['supports3DS','supportsCredit','supportsDebit'],
countryCode:'US'
}
};
const shoppingListItems = Array.from(shoppingList.children);
const pricePerItem = 5.00;
const details = {
total:{
label:"Outdoorsy",
amount:{
value:String(shoppingListItem.length * pricePerItem),
currency:'USD'
}
},
displayItems:shoppingListItems.map(function(item){
return {
label:item.textContent,
pending:false,
amount:{
value:String(pricePerItem),
currency:'USD'
}
}
}),
shippingOptions:[{
id:'ground',
label:'Ground Shipping',
selected:true,
amount:{
value:'0.00',
currency:'USD'
}
}]
};
const options = {
requestPayerName:true,
requestShipping:true
}
const paymentRequest = new PaymentRequest([method],details,options);
paymentRequest.show().then((response) => {
//do some thing
//处理支付 response
});
}
});
复制代码
Service Worker 是当下煊赫一时的渐进式网页技术 PWA ( Progressive Web App) 中的很重要的一环,赋予渐进式网页离线运行与更新的能力,原本由 Google 提出,苹果已经在 iOS 11.3 的版本进行了跟进和支持,关于 PWA 的内容能够搜到太多,这里就不详细讲了。
Service Worker 这种技术能带给网页离线访问的体验 Great offline experience,主要是经过向浏览器注册安装事件,从而引导内核在后台把网页所须要的 HTML/JS/CSS/IMG 等静态资源安装到本地,而且在网页生命周期以外,浏览器内核维持本地资源的更新频次,而且提供了请求拦截,凡是命中本地资源或数据的请求,都将优先返回本地缓存,不发起网络,从而作到离线使用
这里介绍一篇更详细介绍 Service Worker 的文章,(译)理解 Service Workers
以前 HTML 的全屏模式 API 在 iPad 是不支持的,如今能够正确的在 iPad 上生效了,而且提供了2个额外的 CSS 属性,来控制全屏模式下,关闭按钮的隐藏。
本届 WWDC 重点介绍了 ARKit2.0 ,如今经过 Safari 也可以体验 AR了!
USDZ 是一种苹果ARKit的新模型格式,在 ARKit 的相关 Session 中有详细的介绍,如今 Safari 也能在浏览器中以 AR 的形式,展现这种模型了。如今已经升级 iOS12 的朋友能够直接用 Safari 打开下面的连接,你就能够马上体验到浏览器中的 AR
代码很是简单,只须要写个 A 标签,加上一个属性 rel = 'ar' ,href指向 usdz 文件便可,感受AR模型放置类的 APP 能够完全被淘汰了,这么简短的3行 html 就能代替掉全部 AR 放置类 App。
<a rel="ar" href="myfile.usdz">
<img src="myimagefallback.jpg">
</a>
复制代码
如今 WebKit 已经被移植到 watchOS 上了,能够在手表上打开网页了
总的来讲这场 Session 主要仍是为 web 开发者准备的,全面加强了 Safari 在各方面的能力。不过须要补充一点的是。好多新的功能都是 W3C 标准,JS API or CSS 属性之类的,我在文中都有提到,苹果在 Safari 中对这些标准进行了跟进与实现。其实,好多功能都是已经在 iOS 11.3 的版本中发布了的,只不过拿到了本次大会来一块儿进行说明。