WWDC 2018:Safari与WebKit的新特性

Session 234: What’s New in Safari and WebKitjavascript

这个Session介绍了Safari与WebKit的新特性,主要面向三类人群html

  • Web 网页开发者(是本篇主要面相对象)
  • Use WKWebView 原生开发者
  • Safari Extension 浏览器插件开发者

这个Session主要围绕着与浏览器技术相关的新特性与新功能,而且和大会的其余煊赫一时的议题好比ARKitWatchOS,都有相关和联动,极大地加强了Web技术的功能与性能。整个 Session 介绍的各类新功能相对来讲比较琐碎,主要包括三大部分:java

  • 安全性与隐私保护
  • 表现力与性能
  • 丰富的交互体验

安全 Security

这一大块主要凸显苹果对安全以及用户隐私方面的重视,小到规范获取受权的提示,跨端的密码自动填充,大到网页上干扰广告商经过 cookie 定位跟踪用户,一种值得尊敬得企业态度。ios

UIWebView废弃,迁移WKWebView

在安全方面,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扩展开发 Safari Extensions

safari扩展开发的历史promise

  • 2010: 开放 macOS (Safari网页插件扩展) - Safari Extensions
  • 2014: 开放 macOS 与 iOS 的 App Extensions 扩展开发 - App Extensibility for macOS and iOS
  • 2015: 开放了 macOS 与 iOS 的 Safari 内容拦截能力(广告插件)- Content Blockers for macOS and iOS
  • 2016: 开放了 macOS 的 Safari App Extensions 扩展开发 - Safari App Extensions for macOS

在macOS上,有一个Safari扩展的商店 Safari Extensions Gallery,如今这个扩展商店也要退出历史舞台了,苹果但愿开发者逐渐转移到 App Extensions 开发,最终提交到 AppStore 而不是开发Safari浏览器插件,提交到 Safari Extensions Gallery,这个期限会持续到2018年末,以后 Gallery 就再也不接受提交了。浏览器

子资源完整性校验 Subresource Integrity

早在好久以前,已经全面要求开发者适配HTTPS了,但若是开发者在我的网站上引用了存放在第三方平台的子资源,诸如 HTML/CSS/JS ,若是该资源在第三方平台出现了篡改等问题的发生,将致使咱们的网站会遭受攻击缓存

subresuroucesha

为了应对这种安全问题,Safari在新的版本里对HTML标签加入了一个新的属性 integrity 用来填写当前要引用的子资源的Hash值,若是该子资源下载完毕的时候发现Hash值和 integrity 属性不一致,则会直接放弃加载该资源,这个属性适用于一切子资源,JS/CSS等

<script src="https://thirdparty.example/framework.js" integrity="sha384oqVuAfXRKa+R9GqQ8K/ux"></script>
复制代码

智能防追踪 Intelligent Tracking Prevention

在WWDC第一天的开场大会上,介绍到了在本届 WWDC,Apple 全面增强了用户隐私相关的保护,不管是用户设备指纹追踪,仍是网络浏览行为追踪,表现出了,苹果很是在乎保护用户的我的隐私。而在本场 Session 进一步介绍了如何智能的防止隐私追踪,Cookie 是这项技术的关键之一。

不少广告/搜索进行的用户行为追踪,致使用户刚搜过什么东西,在别处广告就能看到对应的商品推荐,主要靠的是建立一种惟一识别用户的 token,并将这 token 存入除了当前网站以外的第三方网站cookie,从而作到访问任意网站的时候可以追踪到用户在其余网站作过什么。

  • 在去年的WWDC,苹果就宣布,Cookies 在24小时内以内能够被第三方上下文使用(用户能够被追踪),而过了24小时以后,Cookies 会被隔离存储,而且不提供给第三方上下文,30天候,Cookies 会被删除
  • 今年这项举措进一步收紧,移除了24小时的宽限期,直接禁止第三方上下文使用 Cookies

那么问题来了?当用户确实须要跨网站之间同步登录状态等用户信息怎么办?

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.
});
}
复制代码

自动生成强密码 Automatic Strong Passwords

iOS12 会在用户须要建立一个用户名和密码的时候,自动生成一个强密码,包含了大小写,数字,特殊字符等等。而且这个强密码会被保存到用户的 KeyChain 之中,将来在访问当前网站的时候自动填充登录,用户也能够在设置中查询已经生成的各个网站的密码,

对开发者来讲,这个功能能够彻底不作任何开发适配自动生效 Apple 默认的强密码规则,开发者也能够在本身的网站自定义强密码的规则

短信验证码自动填充 Security Code AutoFill

自动填充短信验证码,这个功能依然不须要开发者作任何适配自动填充,短信验证码会被填充到输入法里,快速录入到目标输入框

性能与展示 Performance

本届 WWDC 上来在介绍 iOS12 的时候就强调了软件性能,苹果作了巨大得努力,得到了巨大程度的提高。而在 Web 在浏览器上,一直被人诟病说表现力不如 Native ,性能流畅度不如 Native。而这一个大块内容就重点介绍了 Apple 是如何全面优化 web 的表现力与流畅度的。

字体集 Font Collections

Safari新增了一种能够将一些固定字符集的多种字体打包在一块儿,造成一个固定字符集的字体合集用来加载,此举能够大幅度减小多字体状况下的字体包下载大小,Session中提到的例子,使用了Font Collection,须要下载的全部字体体积降低了了84%

原理是多种字体在相同字符集下,能够共享同一个字符表,每个字符的编码下对应存储多个字体的字形glyph,从而减小空间上的冗余。

CCS属性 font-display Descriptor

当一个网页使用了自定义字体,那么Safari会先用空白区域占位,而后去下载该字体,等下载完毕后在刷新出新的字体,若是这个过程 web 开发者想进一步的本身控制,就须要 font-display 这个 CSS 属性

font-display 是一个新的 CSS 属性,已经在 Chrome & Chrome for Android 率先获得了支持,此次 Safari 跟进了对这个属性的支持。

Session 中并无讲太细致这个 CSS 到底该如何使用,目前有5种效果能够进行选择,样例中用的是 font-display: fallback; 此外还有 auto/swap/optional

  • auto:默认值。使用自定义字体的文本会先被隐藏,直到字体加载结束后才会显示。
  • swap:先用默认字体当即显示文字,直到自定义字体加载完成后再使用自定义字体渲染文本。
  • fallback:这个能够说是auto和swap的一种折中方式。须要使用自定义字体渲染的文本会在较短的时间不可见,若是自定义字体尚未加载结束,那么就先加载无样式默认字体的文本。一旦自定义字体加载结束,那么文本就会被从新渲染。
  • optional:效果和fallback几乎同样,都是先在极短的时间内文本不可见,而后再加载无样式的文本。不过optional选项可让浏览器自由决定是否使用自定义字体,而这个决定很大程度上取决于浏览器的链接速度。若是速度很慢,那你的自定义字体可能就不会被使用。

Image标签中播放视频 Videos in image elements

网页中常常要播放动图,动画,咱们通常都会使用 Gif 图,但 Gif 图加载时间太长了,所以开放了直接在 Image 标签中加载视频。而且 Safari 会使用内置的视频解码技术对视频进行最佳的渲染。

代码也很是简洁,不管是写一个HTML标签,仍是写在CSS里,都支持

//html 写法
<img src="explosion.mp4" alt="Color Explosion">
//CSS 写法
body {
 background-image: url("explosion.mp4");
} 
复制代码

被动事件监听 Passive Event Listeners

这个 feture 大幅度优化了 Web 的滚动性能

在本来的 Safari 事件监听实现里,若是在滚动中触发了 addEventListener() 的事件监听,滚动会等待 JS 事件监听处理完毕,再继续滚动。

本次的被动事件监听优化,就是专门针对这种状况致使的可能的卡顿。被动监听做为一个标记位在 addEventListener() 的时候传入,当这个标记开启的时候,滚动不会等待 JS 事件监听执行完毕在继续,从而保证了流畅度。

异步图片解码 Async image decoding

新的 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

这个 Beacon API 可不是苹果他们家那个 iBeacon 设备与手机通讯的东西哟!。

Beacon API 是 W3C 的一项新标准新 API,这个 API 主要用于发送不须要服务器回应的HTTP请求,Chrome && Firefox 彷佛已经实现了,如今 Safari 跟进了这个功能。

这个API有什么用?

  • 在空闲的时候发出异步请求,通常用于发送统计,而且由于不须要回应,彻底不会影响页面诸如 JS/CSS Animation 的执行
  • 即便在页面即将关闭 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)
复制代码

丰富的交互体验 Rich Experience

若是说安全与性能都是优化层面,那么这一大块内容就是不折不扣的新功能了,更复杂的 Web 交互,Web 的移动支付,Web AR展示,甚至是 watch OS 上的 Web,让咱们好好感觉一下 Safari 的新能力

拖放交互 Drag and drop

新的 Safari 提供了拖拽 API,这个 API 也是 H5 的标准API,此次 Safari 跟进了支持。

  • 经过 Dom 对象的 draggable 属性来开启拖拽效果
  • 经过 dragstart/drop/dragover 事件监听来处理拖拽逻辑
  • 经过 dataTransfer 来向事件对象 event 传递数据

下面看个简单的例子

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');
});

复制代码

苹果支付 Payment Request API + Apple Pay

恩,没错,苹果支付如今开放给 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
        });
    }
});

复制代码

webpay

离线网页 Service Worker

Service Worker 是当下煊赫一时的渐进式网页技术 PWA ( Progressive Web App) 中的很重要的一环,赋予渐进式网页离线运行与更新的能力,原本由 Google 提出,苹果已经在 iOS 11.3 的版本进行了跟进和支持,关于 PWA 的内容能够搜到太多,这里就不详细讲了。

Service Worker 这种技术能带给网页离线访问的体验 Great offline experience,主要是经过向浏览器注册安装事件,从而引导内核在后台把网页所须要的 HTML/JS/CSS/IMG 等静态资源安装到本地,而且在网页生命周期以外,浏览器内核维持本地资源的更新频次,而且提供了请求拦截,凡是命中本地资源或数据的请求,都将优先返回本地缓存,不发起网络,从而作到离线使用

这里介绍一篇更详细介绍 Service Worker 的文章,(译)理解 Service Workers

iPad的全屏模式 Fullscreen API on iPad

以前 HTML 的全屏模式 API 在 iPad 是不支持的,如今能够正确的在 iPad 上生效了,而且提供了2个额外的 CSS 属性,来控制全屏模式下,关闭按钮的隐藏。

Safari下的AR AR Quick Look + Safari

本届 WWDC 重点介绍了 ARKit2.0 ,如今经过 Safari 也可以体验 AR了!

USDZ 是一种苹果ARKit的新模型格式,在 ARKit 的相关 Session 中有详细的介绍,如今 Safari 也能在浏览器中以 AR 的形式,展现这种模型了。如今已经升级 iOS12 的朋友能够直接用 Safari 打开下面的连接,你就能够马上体验到浏览器中的 AR

AR Quick Look Gallery

代码很是简单,只须要写个 A 标签,加上一个属性 rel = 'ar' ,href指向 usdz 文件便可,感受AR模型放置类的 APP 能够完全被淘汰了,这么简短的3行 html 就能代替掉全部 AR 放置类 App。

<a rel="ar" href="myfile.usdz">
    <img src="myimagefallback.jpg">
</a>
复制代码

手表上的WebKit

如今 WebKit 已经被移植到 watchOS 上了,能够在手表上打开网页了

watchos

小结

总的来讲这场 Session 主要仍是为 web 开发者准备的,全面加强了 Safari 在各方面的能力。不过须要补充一点的是。好多新的功能都是 W3C 标准,JS API or CSS 属性之类的,我在文中都有提到,苹果在 Safari 中对这些标准进行了跟进与实现。其实,好多功能都是已经在 iOS 11.3 的版本中发布了的,只不过拿到了本次大会来一块儿进行说明。

相关文章
相关标签/搜索