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 的版本中發佈了的,只不過拿到了本次大會來一塊兒進行說明。