


A brief discussion on using cache to optimize the performance of HTML5 Canvas program_html5 tutorial skills
After you play with canvas too much, you will automatically start to consider performance issues. How to optimize canvas animation?
【Use cache】
Using cache means using off-screen canvas for pre-rendering. The principle is very simple, that is, first draw into an off-screen canvas, and then draw the off-screen canvas into the main canvas through drawImage. Many people may misunderstand this. Isn't this a double-buffering mechanism used a lot in games?
In fact, the double buffering mechanism is used in game programming to prevent screen flickering. Therefore, there will be a canvas displayed in front of the user and a background canvas. When drawing, the screen content will first be drawn to the background canvas, and then the background canvas will be drawn. The data in the canvas is drawn to the front canvas. This is double buffering, but there is no double buffering in canvas, because modern browsers basically have a built-in double buffering mechanism. Therefore, using off-screen canvas is not double buffering, but treating off-screen canvas as a cache area. Cache screen data that needs to be drawn repeatedly to reduce the consumption of calling the canvas API.
As we all know, calling the canvas API consumes performance. Therefore, when we want to draw some repeated screen data, proper use of off-screen canvas can greatly improve performance. You can take a look at the following DEMO
2. Cache is used but the width and height of the off-screen canvas are not set
3. Cache is used but the width and height of the off-screen canvas are not set
4. Use caching and set the width and height of the off-screen canvas
You can see that the performance of the above DEMO is different. Let’s analyze the reasons below: In order to achieve the style of each circle, I used loop drawing when drawing circles. If caching is not enabled, when the number of circles on the page When it reaches a certain point, a large number of canvas API calls are required for each frame of the animation, and a large amount of calculations are required, so that no matter how good the browser is, it will be brought down.
XML/HTML CodeCopy content to clipboard
- ctx.save();
- var j=0;
- ctx.lineWidth = borderWidth;
- for(var i=1;ithis.r;i =borderWidth){
- ctx.beginPath();
- ctx.strokeStyle = this.color[j];
- ctx.arc(this.x , this.y , i , 0 , 2*Math.PI);
- ctx.stroke();
- j ;
- }
- ctx.restore();
所以,我的方法很简单,每个圈圈对象里面给他一个离屏canvas作缓存区。
除了创建离屏canvas作为缓存之外,下面的代码中有一点很关键,就是要设置离屏canvas的宽度和高度,canvas生成后的默认大小是300X150;对于我的代码中每个缓存起来圈圈对象半径最大也就不超过80,所以300X150的大小明显会造成很多空白区域,会造成资源浪费,所以就要设置一下离屏canvas的宽度和高度,让它跟缓存起来的元素大小一致,这样也有利于提高动画性能。上面的四个demo很明显的显示出了性能差距,如果没有设置宽高,当页面超过400个圈圈对象时就会卡的不行了,而设置了宽高1000个圈圈对象也不觉得卡。
- var ball = function(x , y , vx , vy , useCache){
- this.x = x;
- this.y = y;
- this.vx = vx;
- this.vy = vy;
- this.r = getZ(getRandom(20,40));
- this.color = [];
- this.cacheCanvas = document.createElement("canvas");
- thisthis.cacheCtx = this.cacheCanvas.getContext("2d");
- this.cacheCanvas.width = 2*this.r;
- this.cacheCanvas.height = 2*this.r;
- var num = getZ(this.r/borderWidth);
- for(var j=0;jnum;j ){
- this.color.push("rgba(" getZ(getRandom(0,255)) "," getZ(getRandom(0,255)) "," getZ(getRandom(0,255)) ",1)");
- }
- this.useCache = useCache;
- if(useCache){
- this.cache();
- }
- }
When I instantiate the circle object, I directly call the cache method and draw the complex circle directly into the off-screen canvas of the circle object and save it.
- cache:function(){
- this.cacheCtx.save();
- var j=0;
- this.cacheCtx.lineWidth = borderWidth;
- for(var i=1;ithis.r;i =borderWidth){
- this.cacheCtx.beginPath();
- thisthis.cacheCtx.strokeStyle = this.color[j];
- this.cacheCtx.arc(this.r, this.r, i, 0, 2*Math.PI);
- this.cacheCtx.stroke();
- j ;
- this.cacheCtx.restore();
- Then in the next animation, I only need to draw the off-screen canvas of the circle object into the main canvas. In this way, the canvasAPI called in each frame only has this sentence:
XML/HTML Code
- Compared with the previous for loop drawing, it is really much faster. So when we need to repeatedly draw vector graphics or draw multiple pictures, we can reasonably use the off-screen canvas to cache the picture data in advance, which can reduce a lot of unnecessary performance consumption in each subsequent frame. operation.
XML/HTML Code
- html>
- html lang="en">
- head>
- meta charset="UTF-8">
- style>
- body{
- padding:0;
- margin:0;
- overflow: hidden;
- }
- #cas{
- display: block;
- background-color:rgba(0,0,0,0);
- margin:auto;
- border:1px solid;
- }
- style>
- title>Testtitle>
- head>
- body>
- div >
- canvas id='cas' width="800" height="600">The browser does not support canvascanvas> ;
- div style="text- align:center">1000 circle objects are not stuckdiv>
- div>
- script>
- var testBox = function(){
- var canvas = document.getElementById("cas"),
- ctx = canvas.getContext('2d'),
- borderWidth = 2,
- Balls = [];
- var ball = function(x, y, vx, vy, useCache){
- this.x = x;
- this.y = y;
- this.vx = vx;
- this.vy = vy;
- this.r = getZ(getRandom(20,40));
- this.color = [];
- this.cacheCanvas = document.createElement("canvas");
- thisthis.cacheCtx = this.cacheCanvas.getContext("2d");
- this.cacheCanvas.width = 2*this.r;
- this.cacheCanvas.height = 2*this.r;
- var num = getZ(this.r/borderWidth);
- for(var j=0;jnum;j ){
- this.color.push("rgba(" getZ(getRandom(0,255)) "," getZ(getRandom(0,255)) "," getZ(getRandom(0,255)) ",1)");
- }
- this.useCache = useCache;
- if(useCache){
- this.cache();
- }
- }
- function getZ(num){
- var rounded;
- rounded = (0.5 num) | 0;
- // A double bitwise not.
- rounded = ~~ (0.5 num);
- // Finally, a left bitwise shift.
- rounded = (0.5 num) 0;
- return rounded;
- }
- ball.prototype = {
- paint:function(ctx){
- if(!this.useCache){
- ctx.save();
- var j=0;
- ctx.lineWidth = borderWidth;
- for(var i=1;ithis.r;i =borderWidth){
- ctx.beginPath();
- ctx.strokeStyle = this.color[j];
- ctx.arc(this.x , this.y , i , 0 , 2*Math.PI);
- ctx.stroke();
- j ;
- }
- ctx.restore();
- } else{
- ctx.drawImage(this.cacheCanvas , this.x-this.r , this.y-this.r);
- }
- },
- cache:function(){
- this.cacheCtx.save();
- var j=0;
- this.cacheCtx.lineWidth = borderWidth;
- for(var i=1;ithis.r;i =borderWidth){
- this.cacheCtx.beginPath();
- thisthis.cacheCtx.strokeStyle = this.color[j];
- this.cacheCtx.arc(this.r , this.r , i , 0 , 2*Math.PI);
- this.cacheCtx.stroke();
- j ;
- }
- this.cacheCtx.restore();
- },
- move:function(){
- this.x = this.vx;
- this.y = this.vy;
- if(this.x>(canvas.width-this.r)||this.xthis.r){
- thisthis.x=this.xthis.r?this.r:(canvas.width-this.r);
- this.vx = -this.vx;
- }
- if(this.y>(canvas.height-this.r)||this.ythis.r){
- thisthis.y=this.ythis.r?this.r:(canvas.height-this.r);
- this.vy = -this.vy;
- }
- this.paint(ctx);
- }
- }
- var Game = {
- init:function(){
- for(var i=0;i1000;i ){
- var b = new ball(getRandom(0,canvas.width) , getRandom(0,canvas.height) , getRandom(-10 , 10) , getRandom(-10 , 10) , true)
- Balls.push(b);
- }
- },
- update:function(){
- ctx.clearRect(0,0,canvas.width,canvas.height);
- for(var i=0;iBalls.length;i ){
- Balls[i].move();
- }
- },
- loop:function(){
- var _this = this;
- this.update();
- RAF(function(){
- _this.loop();
- })
- },
- start:function(){
- this.init();
- this.loop();
- }
- }
- window.RAF = (function(){
- return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) {window.setTimeout(callback, 1000 / 60); };
- })();
- return Game;
- }();
- function getRandom(a , b){
- return Math.random()*(b-a) a;
- }
- window.onload = function(){
- testBox.start();
- }
- script>
- body>
- html>
There is another note about off-screen canvas. If the effect you do is to continuously create and destroy objects, please use off-screen canvas with caution. At least do not bind the attributes of each object as I wrote above. Set off-screen canvas.
Because if bound like this, when the object is destroyed, the off-screen canvas will also be destroyed, and a large number of off-screen canvases are constantly being created and destroyed, which will cause the canvas buffer to consume a lot of GPU resources and easily cause the browser to Crash or serious frame freeze. The solution is to create an off-screen canvas array, preload a sufficient number of off-screen canvases, cache only the objects that are still alive, and uncache them when the objects are destroyed. This will not cause the off-screen canvas to be destroyed.
【Use requestAnimationFrame】
I won’t explain this in detail. I guess many people know that this is the best loop for animation, not setTimeout or setInterval. Directly post the compatibility writing method:
- window.RAF = (function(){
- Return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) {window.setTimeout(callback, 1000 / 60 ); };
- })();
【Avoid floating point operations】
Although JavaScript provides some very convenient rounding methods, such as Math.floor, Math.ceil, and parseInt, foreign friends have done tests and the parseInt method does some extra work (such as detecting whether the data is valid value, parseInt even converts the parameter into a string first!), so using parseInt directly is relatively more performance-intensive. So how to round up, you can directly use a very clever method written by foreigners:
1.rounded = (0.5 somenum) | 0;
2.rounded = ~~ (0.5 somenum); 3.rounded = (0.5 somenum)
【Reduce canvasAPI calls as much as possible】
When making particle effects, try to use circles as little as possible and preferably use squares. Because the particles are too small, squares look similar to circles. As for the reason, it is easy to understand. We need three steps to draw a circle: first beginPath, then use arc to draw an arc, and then use fill to fill it to produce a circle. But to draw a square, you only need one fillRect. Although there is only a difference of two calls, when the number of particle objects reaches a certain level, the performance gap will show up.
There are some other things to note, I won’t list them all because there are quite a few on Google. This can be regarded as a record for myself, mainly to record the usage of cache. If you want to improve the performance of canvas, the most important thing is to pay attention to the structure of the code, reduce unnecessary API calls, reduce complex operations in each frame, or change complex operations from once for each frame to once for several frames. At the same time, for the cache usage mentioned above, for convenience, I used an off-screen canvas for each object. In fact, off-screen canvas cannot be used too extensively. If you use too many off-screen canvases, there will be performance problems. Please try your best. Make reasonable use of off-screen canvas.
Source code address: https://github.com/whxaxes/canvas-test/tree/gh-pages/src/Other-demo/cache

H5referstoHTML5,apivotaltechnologyinwebdevelopment.1)HTML5introducesnewelementsandAPIsforrich,dynamicwebapplications.2)Itsupportsmultimediawithoutplugins,enhancinguserexperienceacrossdevices.3)SemanticelementsimprovecontentstructureandSEO.4)H5'srespo

The tools and frameworks that need to be mastered in H5 development include Vue.js, React and Webpack. 1.Vue.js is suitable for building user interfaces and supports component development. 2.React optimizes page rendering through virtual DOM, suitable for complex applications. 3.Webpack is used for module packaging and optimize resource loading.

HTML5hassignificantlytransformedwebdevelopmentbyintroducingsemanticelements,enhancingmultimediasupport,andimprovingperformance.1)ItmadewebsitesmoreaccessibleandSEO-friendlywithsemanticelementslike,,and.2)HTML5introducednativeandtags,eliminatingthenee

H5 improves web page accessibility and SEO effects through semantic elements and ARIA attributes. 1. Use, etc. to organize the content structure and improve SEO. 2. ARIA attributes such as aria-label enhance accessibility, and assistive technology users can use web pages smoothly.

"h5" and "HTML5" are the same in most cases, but they may have different meanings in certain specific scenarios. 1. "HTML5" is a W3C-defined standard that contains new tags and APIs. 2. "h5" is usually the abbreviation of HTML5, but in mobile development, it may refer to a framework based on HTML5. Understanding these differences helps to use these terms accurately in your project.

H5, or HTML5, is the fifth version of HTML. It provides developers with a stronger tool set, making it easier to create complex web applications. The core functions of H5 include: 1) elements that allow drawing graphics and animations on web pages; 2) semantic tags such as, etc. to make the web page structure clear and conducive to SEO optimization; 3) new APIs such as GeolocationAPI support location-based services; 4) Cross-browser compatibility needs to be ensured through compatibility testing and Polyfill library.

How to create an H5 link? Determine the link target: Get the URL of the H5 page or application. Create HTML anchors: Use the <a> tag to create an anchor and specify the link target URL. Set link properties (optional): Set target, title, and onclick properties as needed. Add to webpage: Add HTML anchor code to the webpage where you want the link to appear.

Solutions to H5 compatibility issues include: using responsive design that allows web pages to adjust layouts according to screen size. Use cross-browser testing tools to test compatibility before release. Use Polyfill to provide support for new APIs for older browsers. Follow web standards and use effective code and best practices. Use CSS preprocessors to simplify CSS code and improve readability. Optimize images, reduce web page size and speed up loading. Enable HTTPS to ensure the security of the website.


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

WebStorm Mac version
Useful JavaScript development tools

Dreamweaver Mac version
Visual web development tools

PhpStorm Mac version
The latest (2018.2.1) professional PHP integrated development tool

MantisBT
Mantis is an easy-to-deploy web-based defect tracking tool designed to aid in product defect tracking. It requires PHP, MySQL and a web server. Check out our demo and hosting services.

Zend Studio 13.0.1
Powerful PHP integrated development environment