摘要:值得一提的是,微信瀏覽器的內核,也即是瀏覽器內核已經內置了很多游戲引擎比如白鷺游戲引擎與,供開發者開發游戲,所以長時間來看,微信瀏覽器的畫布性能將會越來越強大。
1、什么是流暢的用戶體驗?
游戲的開發界有一個理論,就是當動畫或者交互響應達到60FPS(60幀每秒)的時候,就可以定義為流暢,按此理論,那么每幀里所有操作必須在16ms完成。要想提高頁面的用戶體驗,必須在性能上下功夫。最早做動畫都是用 setTimeout來實現的,而 setTimeout的處理回調的時間精度都在 16ms 左右。所以,可以想象正常用頁面這兩個函數就已經 16 ms了,再加上reflow/repaint/compositing 卡頓或跳幀就是家常便飯了。不過還好的是w3c 標準和各瀏覽器廠商較早就支持了動畫接口 RAF(RequestAnimationFrame 函數)來處理動畫幀回調。解決了上述 setTimeout不足的問題。但是,另一個問題仍然沒解決,當瀏覽器打開網頁時,需要解析文檔,在內存中生成DOM結構,如果遇到復雜的文檔,這個過程是很慢的。如果遇上低端的手機瀏覽器,可以想象一下,如果網頁上有上萬個形狀(不管是圖片或CSS),生成DOM需要多久?更不要提與其中某一個形狀互動了。
2、React是什么?用戶與瀏覽器互動,從技術上看就是用戶在操作DOM,所有的DOM操作都是同步的,會堵塞瀏覽器。JavaScript操作DOM時,必須等前一個操作結束,才能執行后一個操作。只要一個操作有卡頓,整個網頁就會短暫失去響應。瀏覽器重繪網頁的頻率是60FPS,JavaScript做不到在16毫秒內完成DOM操作,因此產生了跳幀。用戶體驗上的不流暢、不連貫就源于此。JavaScript語言運行效率本身很快,但是DOM太慢了,DOM拖慢JavaScript。為了解決這個問題,React出現了,React是 Facebook 推出的一個用來構建用戶界面的 JavaScript 開源框架,React的最引人注目的特征就是引入了虛擬DOM(Virtual DOM)這個概念,在瀏覽器端用JavaScript實現了一套DOM API。基于React進行開發時所有的DOM構造都是通過虛擬DOM進行,每當用戶界面需要變化時,React都會重新構建整個DOM樹,然后React將當前整個DOM樹和上一次的DOM樹進行對比,得到DOM結構的區別,然后僅僅將需要變化的部分進行實際的瀏覽器DOM更新。React實現了代碼最小化參與DOM操作的方法,大大提升了瀏覽器的性能。
3、Canvas是什么?Canvas 是 HTML5 的畫布元素,也一個原生的DOM 元素。它相當于一個“白板”,我們可以通過javascript在這塊白板上增加文字與圖像,“繪制”一些可視內容。目前大多數H5游戲和動畫特效都是用canvas實現的。很多在微信里傳播的小游戲和小應用,也是用canvas實現的。用canvas的話整個頁面只用一個DOM 元素,并且瀏覽器只需要繪制一次形成一幅圖。這大大降低了DOM 數量與渲染的復雜度。更好的是,canvas默認支持GPU硬件加速的,可以將原來 CPU 密集型操作變成 GPU 操作。提高了動畫的流暢度。值得一提的是,微信瀏覽器的內核,也即是QQ瀏覽器 X5 內核已經內置了很多游戲引擎(比如白鷺游戲引擎與cocos2dx),供開發者開發canvas游戲,所以長時間來看,微信瀏覽器的畫布性能將會越來越強大。
4、新的方法大多數現代移動設備都擁有硬件加速的 canvas,我們為什么不利用起來呢?HTML5 游戲已經做到了。我們為什么不采用游戲的思路設計界面,在 canvas 上開發應用界面么,用canvas來渲染頁面呢?相信你已經想到了,但是有人已經做到了,那就是Flipboard公司的React-canvas。React-canvas是什么呢?光看名字就知道這是跟react和canvas相關的。React-canvas,可以使我們用react技術渲染canvas。
5、React-canvas入門React Canvas 是依賴于React的一個組件,它擁有了渲染到canvas的能力,它可以讓我們脫離繁瑣的canvas命令式繪圖,使用簡單的css布局(Layout)。接下來給大家演示一個簡單的圖文實現。
5.1.安裝node新時代的前端開發離不開node環境,所以,react-canvas也不例外,node安裝的具體步驟不再贅述。記住,Node版本不低于4.0。
5.2創建項目空間
在D: odejs eactdemo創建文件夾,此為開發的根目錄 打開到此目錄,切換到命令行,執行 npm init,默認回車,初始化package.json
5.3安裝框架和插件需要在node環境上安裝一系列框架 切換到命令行, 執行
npm install react
安裝基礎框架react(注:安裝v0.13.0,新版本我沒試驗,不知是否可行), 執行
npm install jsx-loader
安裝編譯react用的jsx-loader插件, 執行
npm install react-canvas
安裝核心框架react-canvas, 執行
npm install webpack
安裝打包代碼用的工具webpack。 然后創建文本文件index.html, 創建配置文件webpack.config.js, 創建js文件夾存放代碼文件。 至此,你的工作環境下應該有
其中node_modules文件夾下,應該至少有自動生成的react、react-canvas、webpack三個文件夾。
5.4讓代碼跑起來打開index.html文件,代碼如下:
"Content-type" content="text/html; charset=utf-8">
"viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
react canvas第一步
"main">
主頁面只有一個id=main的div標簽,并外鏈一個js文件。 打開js文件夾,創建index.js,代碼如下
var React = require("react");
var ReactCanvas = require("react-canvas");
var Surface = ReactCanvas.Surface;
var Image = ReactCanvas.Image;
var Text = ReactCanvas.Text;
var MyComponent = React.createClass({
// 界面渲染
render: function () {
var surfaceWidth = window.innerWidth;
var surfaceHeight = window.innerHeight;
var imageStyle = this.getImageStyle();
var textStyle = this.getTextStyle();
return (
"http://img1.gtimg.com/joke/pics/hv1/193/44/1996/129801313.png" />
哈哈,你來打我呀
);
},
// 計算居中
getImageHeight: function () {
return Math.round(window.innerHeight / 2);
},
getImageWidth: function () {
return Math.round(window.innerWidth / 2);
},
// 圖片樣式
getImageStyle: function () {
return {
top: this.getImageHeight() -32,
left: this.getImageWidth() -32,
width: 64,
height: 64
};
},
// 文字樣式
getTextStyle: function () {
return {
top: this.getImageHeight() + 64,
left: 0,
width: window.innerWidth,
height: 20,
lineHeight: 20,
fontSize: 12,
textAlign : "center"
};
}
});
React.render( , document.getElementById("main"));
配置webpack.config.js
module.exports = {
//入口文件
entry: "./js/main.jsx",
//輸出文件
output: {
path: __dirname,
filename: "bundle.js"
},
module: {
loaders: [
// 凡是遇到jsx、js結尾的,都用jsx-loader這個插件來加載,
// 且啟用harmony模式
{ test: /.jsx$/, loader: "jsx-loader");},
{ test: /.js$/, loader: "jsx-loader");},
]
},
// 表示這個依賴項是外部lib,遇到require它不需要編譯,
// 且在瀏覽器端對應window.React
//externals: {
//"react": "window.React"
//},
// 現在可以寫 require("file") 代替 require("file.jsx")
resolve: {
root: __dirname,
extensions: ["", ".js", ".jsx"]
}
};
配置完畢后,切換到命令行執行 webpack -p 命令,打包,編譯 打包后在根目錄下生成一個bundle.js,直接用瀏覽器打開,就可以看到效果了。
線上demo地址:點我
6、語法及元素(標簽、組件)react-canvas的語法和react一樣,如果你熟悉react,react-canvas很容易上手。react-canvas自定義了幾個標簽。這些標簽也都是標準的React components。
Surface是一個頂級標簽,是一個容器,你可以把任何元素放在上面,可以把它看成canvas元素,整個項目要被套在一個surface里面。在上述示例中已經使用。
Layer 層級僅次于surface,可以放其他元素。 基本樣式和屬性例如top, width, left, height, backgroundColor and zIndex可以在這一層設置。
Group是一個容器,因為react渲染組件時必須要有一個總的標簽包含所有的散列標簽,在react-canvas中,Group扮演了div的角色,可以用來做零散標簽的父標簽。把一系列相關聯標簽用Group封裝起來,一方面可以提高代碼的內聚,更加模塊化,另一方面可以提高頁面滾動時的性能。
Text 是用來存放文本的,是一個彈性的標簽,canvas不支持自動截斷換行,而Text標簽支持。
Image 跟你想象的一樣,用來放圖片的。 但是它支持加載完畢后才顯示,并且可以隨意的隱藏。
ListView是一個列表,可以認為它相當于HTML頁面里的ul或者native app中的UITableView ,它可以提高頁面的滾動性能。 同時react-canvas給各個標簽以事件支持,有touchstart,move,end,click等事件。
7、圖文滾動列表接下來介紹如何在 React Canvas 中創建一個達到60 fps ,分頁的滾動列表。事實證明這實現起來非常容易, 修改main.js代碼為
/** @jsx React.DOM */
"use strict";
var React = require("react");
var ReactCanvas = require("react-canvas");
// page文件負責渲染單個頁面
var Page = require("./components/Page");
// data文件存放json格式的圖文
var articles = require("./common/data");
var Surface = ReactCanvas.Surface;
var ListView = ReactCanvas.ListView;
var App = React.createClass({
// 渲染整個列表
render: function () {
var size = this.getSize();
return (
true}
scrollingDeceleration={0.92}
scrollingPenetrationAcceleration={0.13}
numberOfItemsGetter={this.getNumberOfPages}
itemHeightGetter={this.getPageHeight}
itemGetter={this.renderPage} />
);
},
// 渲染單頁
renderPage: function (pageIndex, scrollTop) {
var size = this.getSize();
var article = articles[pageIndex % articles.length];
var pageScrollTop = pageIndex * this.getPageHeight() - scrollTop;
return (
);
},
// 瀏覽器大小
getSize: function () {
return document.getElementById("main").getBoundingClientRect();
},
// 整個列表的外觀
getListViewStyle: function () {
var size = this.getSize();
return {
top: 0,
left: 0,
width: size.width,
height: size.height,
};
},
// 設置頁面的可滾動的次數,若超過頁面的數量,循環滾動
getNumberOfPages: function () {
return 9;
},
// 計算單頁的高度
getPageHeight: function () {
return this.getSize().height;
}
});
React.render( , document.getElementById("main"));
整個頁面代碼由一個surface,一個listview,9個page組成,可以上下屏滾動。react-canvas將網頁變成了一個canvas,用戶就等于在跟圖片互動,這樣就繞開了DOM,降低了操作時滯。而且,canvas可以被硬件加速,這樣就提高了性能,體驗非常流暢。
你可以查看這個線上的Demo點我,pc用戶記得用chrome模擬手機瀏覽器。文章末尾附件里有完整實現的源代碼。
8、React-canvas的優缺點 8.1優點React-canvas使用一個 canvas 元素來繪制界面,完成滾動。在每一個觸摸事件時,根據當前的滾動程度去更新渲染樹。之后,整個渲染樹使用新的坐標來重新渲染。在 canvas 上有個重要的技術叫離屏canvas(off-screen),可以現在內存中完成繪制,之后可以一次性復制到用戶界面,并且使用離屏層重新繪制也是非常快的。React在界面更新之前會做虛擬 DOM 的 diff 。在render() 函數中只更新有變動的界面,React進一步提升了React-canvas的性能。流暢是React-canvas的主要優點。 代碼基于react,因為react現在比較火,很多前端已經熟悉react的書寫,react也有很多相關的組件,所以react-canvas比較應景,讓一部分人很快的可以上手。另外兼容性也比較好,繼承react和canvas的兼容性和跨平臺優點。
8.2缺點當前不成熟和不穩定,react一直在變動,所以React-canvas也會隨之一并升級。react-canvas還不完善,很多DOM中的標簽特性在目前react-canvas里面未能實現,比如無法對文本進行復制,這讓使用React-canvas的時候會有一些限制。這個項目已經在Github上開源,作者也在對項目進行重構,期望下次更新的時候是一個功能強大的版本。另外,react-canvas的學習成本也比較高,使用react-canvas需要對react和canvas有一定的了解。
9、總結React Canvas并不能完全取代DOM。個人覺得只適用在移動web(或者webview)上,手機的硬件資源相對有限,用戶互動又相對頻繁,我們可以在我們的頁面中性能要求最關鍵的地方去使用它,尤其是在微信瀏覽器中很常見滾動視圖這部分。當渲染性能不是問題的時候, DOM 可能是一個更好的方法。事實上,對于某些元素比如輸入字段,和音頻/視頻標簽等,DOM是唯一的方法。從某種意義上說,react-canvas也算是一個混合( hybird )的應用程序。相比傳統的原生應用,react-canvas內容全部是 web 。我們在開發中可以把界面基于 dom 實現,并在適當的地方使用 canvas 渲染。DOM和canvas各取所長,優勢互補。React-canvas能將頁面的交互和性能水平提升到可以與本地應用相競爭,這就是它引人注意的地方。
我們在web開發過程中,都見過或者使用過一些奇技淫巧,這種技術我們統稱為黑魔法,這些黑魔法散落在各個角落,為了方便大家查閱和學習,我們做了收集、整理和歸類,并在github上做了一個項目——awesome-blackmargic,希望各位愛鉆研的開發者能夠喜歡,也希望大家可以把自己的獨門絕技分享出來,如果有興趣可以給我們發pr。
如果你對React感興趣,想進一步了解React,加入我們的QQ群(784383520)吧!
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/7288.html
摘要:基因組學方面,騰訊云批量計算的彈性資源作業調度等優勢能滿足基礎科研數據處理及臨床應用等不同場景下對數據處理存儲和傳輸的要求。世界杯賽事激戰正酣,八強戰即將開打,你是否沉迷比分競猜難以自拔,寵物預測、緣分預測、玄學預測等機關算盡,卻總是猜不對,各種爆冷錘到你懷疑人生…。那邊天臺上新人換舊人,熙熙攘攘,人滿為患,好不熱鬧。不少球迷感慨這屆世界杯勝負要反買,別墅靠著海。小編只想大喊:嘿,天臺上這位...
摘要:所以在使用屬性選擇器的時候,注意大小寫問題。目前就只覺得這些黑科技需要提醒自己一下,有可以補充。 原文來自:https://jellybool.com/post/css-that-you-may-not-know 補充篇在這里 http://segmentfault.com/a/1190000003029085 昨天由于某些原因沒有寫博客,之前說好的每天一篇的,這篇...
摘要:除此之外,無碼科技還推出抽獎助手和等流量和工具產品。目前無碼科技旗下用戶數過億,由醫療用戶和非醫療用戶構成。無碼科技產品負責人邱岳介紹。此外,在高性能的支持下,無碼科技在人工智能領域的技術得以不斷推進。無癥狀新冠疫情要如何判斷?家附近哪里有疫苗接種點接種疫苗有什么注意事項……新冠疫情爆發后,醫療小程序就診問問上,關于新冠疫情的搜索量出現明顯增長。就診問問是無碼科技旗下專注醫療健康搜索的小程序...
摘要:在整個實施過程中,華為云提供了從架構設計集成及壓力測試等各個環節的大力支持。攜手華為云,一下科技更平穩高效的開啟多云化進程,實現業務加速發展。 華為云攜手秒拍,云+AI助力短視頻加速發展 作為行業領先的移動視頻矩陣平臺,炫一下(北京)科技有限公司(以下簡稱一下科技)一直走在行業發展前沿,旗下秒拍、小咖秀、波波等多款火爆產品,長期以來都是微博短視頻內容的熱門平臺。這些平臺不僅能供大量C端...
閱讀 1369·2021-10-13 09:39
閱讀 1333·2021-09-23 11:22
閱讀 2243·2019-08-30 14:05
閱讀 1059·2019-08-29 17:03
閱讀 770·2019-08-29 16:24
閱讀 2227·2019-08-29 13:51
閱讀 656·2019-08-29 13:00
閱讀 1290·2019-08-29 11:24