fabricjs / fabric.js

Javascript Canvas Library, SVG-to-Canvas (& canvas-to-SVG) Parser

Home Page:http://fabricjs.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Feature]: Selective rendering – Update only the changed object on the canvas.

shashi-drishya opened this issue · comments

CheckList

  • I agree to follow this project's Code of Conduct
  • I have read and followed the Contributing Guide
  • I have searched and referenced existing issues, feature requests and discussions
  • I am filing a FEATURE request.

Description

The selective rendering feature should enhance canvas performance by only updating the modified object. When an object is altered or manipulated, the canvas should efficiently re-render just that specific object rather than the entire canvas. This selective rendering should be smart enough to update only the necessary portions of the canvas that are impacted by the change.

The feature should accommodate scenarios like moving, scaling, rotating, or modifying object properties. The solution should intelligently track changes, optimize redrawing, and minimize unnecessary updates to improve performance, particularly with complex or crowded canvases.

Additionally, this feature should be intuitive and straightforward to integrate, allowing developers to enhance their applications' performance without extensive refactoring. By focusing on updating only the changed object, the canvas should operate more efficiently, providing smoother user interactions and enhanced application responsiveness.

Current State

In Fabric.js, the default behavior when an object is modified is to re-render the entire canvas. This approach ensures that the canvas's visual state remains consistent, especially when multiple overlapping objects are involved.

However, this can be inefficient in cases where only a single object is updated, as redrawing the whole canvas may involve unnecessary computation, particularly for large or complex canvases. The lack of selective rendering is a key reason why developers sometimes request more optimized rendering features for scenarios where frequent or incremental updates are necessary.

@asturur, can we have this

I am currently working on this feature for a private project and it is major when the canvas has 5000+ objects.
Not only does rendering improves significantly (50ms dropped to 9ms for each render).
The same amount of time is saved if the app tracks the result of isOnScreen (instead of running it from Object#render) and reused by findTarget that won't need to interate through all the objects but only the objects that are visible on screen.

Also I turned the renderer to be an infinite loop, bailing out the current tick if nothing has changed
That seems to be a good design decision inspired by pixi.js

This is part of the roadmap since long and was never started.
It will be done after v6 is out and the first fires of documentation and issues are settled.

I think this was in planning since 2018 at least.

The issue with approaching this as a rendering library and not as an app is that tracking is up to you.
So when you change the color of an object you know you don't need to call canvas.renderAll but maybe something like canvas.renderObject(object).

When dragging an object that is one of the basic feature of fabric, is already harder because you have to track previous and next position for update, and if there are animations running on the canvas maybe you have to settle with renderAll at the end.

Is a balance between spending time deciding what to re-render and what intersect with it or just rendering everything.

You can expect this to go out as a method for the canvas and then slowly integrate supported actions.