\n\n\n \n\n\n```\n\n#### CanvasKit Variants\n\n```javascript\n// web/index.html\nwindow.flutterConfiguration = {\n // Use full variant (larger but more compatible)\n canvasKitVariant: \"full\", // ~2.7 MB\n\n // Use Chromium variant (smaller, Chrome-only optimizations)\n canvasKitVariant: \"chromium\", // ~2.3 MB\n\n // Auto-detect best variant\n canvasKitVariant: \"auto\", // Recommended\n};\n```\n\n### Optimizing CanvasKit Performance\n\n#### 1. Lazy Loading\n\n```dart\n// Load heavy graphics only when needed\nclass LazyGraphicsPage extends StatefulWidget {\n @override\n _LazyGraphicsPageState createState() => _LazyGraphicsPageState();\n}\n\nclass _LazyGraphicsPageState extends State {\n bool _loadGraphics = false;\n\n @override\n Widget build(BuildContext context) {\n return Column(\n children: [\n ElevatedButton(\n onPressed: () => setState(() => _loadGraphics = true),\n child: Text('Load Graphics'),\n ),\n if (_loadGraphics)\n GraphicsIntensiveWidget(),\n ],\n );\n }\n}\n```\n\n#### 2. Caching\n\n```dart\nclass CachedCustomPainter extends CustomPainter {\n @override\n void paint(Canvas canvas, Size size) {\n // Cache complex paths/images\n final path = Path()\n ..moveTo(0, 0)\n ..lineTo(size.width, size.height);\n\n canvas.drawPath(path, Paint());\n }\n\n @override\n bool shouldRepaint(covariant CustomPainter oldDelegate) {\n // Only repaint when necessary\n return false;\n }\n}\n```\n\n#### 3. Use RepaintBoundary\n\n```dart\nclass OptimizedWidget extends StatelessWidget {\n @override\n Widget build(BuildContext context) {\n return Column(\n children: [\n Text('Static content'),\n\n // Isolate repainting to this widget only\n RepaintBoundary(\n child: AnimatedGraphicsWidget(),\n ),\n\n Text('More static content'),\n ],\n );\n }\n}\n```\n\n### Debugging CanvasKit\n\n#### Check Active Renderer\n\n```dart\nimport 'package:flutter/foundation.dart';\n\nvoid main() {\n print('Platform: ${defaultTargetPlatform}');\n print('Is Web: ${kIsWeb}');\n\n runApp(MyApp());\n}\n```\n\n#### DevTools Performance\n\n```bash\n# Run with performance overlay\nflutter run -d chrome --profile --web-renderer canvaskit\n\n# Open DevTools\nflutter pub global activate devtools\nflutter pub global run devtools\n```\n\n### Bundle Size Optimization\n\n```bash\n# Minify and compress\nflutter build web --release --web-renderer canvaskit --dart-define=FLUTTER_WEB_USE_SKIA=true\n\n# Check bundle size\nls -lh build/web/\n```\n\n### Browser Compatibility\n\n| Browser | CanvasKit Support |\n|---------|-------------------|\n| Chrome 88+ | ✅ Full support |\n| Firefox 89+ | ✅ Full support |\n| Safari 14+ | ✅ Full support |\n| Edge 88+ | ✅ Full support |\n| Mobile browsers | ⚠️ May have performance issues |\n\n### Fallback Strategy\n\n```html\n\n\n```\n\n### Best Practices\n\n1. **Choose Renderer Based on Use Case**: Graphics apps → CanvasKit, Content apps → HTML\n2. **Test on Target Devices**: Performance varies across devices\n3. **Monitor Bundle Size**: CanvasKit adds significant size\n4. **Use Auto Renderer**: Let Flutter choose optimal renderer\n5. **Optimize Assets**: Compress images and reduce asset sizes\n6. **Profile Performance**: Use Chrome DevTools to identify bottlenecks\n\n### Common Issues and Solutions\n\n#### Issue 1: Slow Initial Load\n\n**Solution**: Use HTML renderer or implement loading screen:\n\n```dart\nclass LoadingApp extends StatefulWidget {\n @override\n _LoadingAppState createState() => _LoadingAppState();\n}\n\nclass _LoadingAppState extends State {\n bool _isLoaded = false;\n\n @override\n void initState() {\n super.initState();\n // Simulate CanvasKit loading\n Future.delayed(Duration(seconds: 2), () {\n setState(() => _isLoaded = true);\n });\n }\n\n @override\n Widget build(BuildContext context) {\n if (!_isLoaded) {\n return Center(child: CircularProgressIndicator());\n }\n return MyApp();\n }\n}\n```\n\n#### Issue 2: Text Rendering Quality\n\n**Solution**: Use native text widgets when possible:\n\n```dart\n// Prefer Material/Cupertino text widgets\nText('High quality text') // Uses platform text rendering\n```\n\n> **Important**: CanvasKit provides desktop-quality graphics on the web but comes with larger bundle sizes and longer load times. Choose the renderer that best fits your app's needs.\n\n**Documentation**: [Flutter Web Renderers](https://docs.flutter.dev/development/platform-integration/web/renderers)"}}]}
Question #87EasyFlutter Basics

What is flutter canvas kit renders ?

#flutter

Answer

Flutter CanvasKit Renderer

CanvasKit is one of Flutter's rendering engines for web applications. It's a WebAssembly (Wasm) based implementation of Skia, the 2D graphics library that Flutter uses for rendering on mobile platforms. CanvasKit brings desktop-quality rendering performance to web applications.

Flutter Web Renderers

Flutter for web supports two rendering backends:

RendererTechnologyBest For
CanvasKitWebAssembly + WebGLGraphics-intensive apps, animations, custom painting
HTMLHTML + CSS + CanvasText-heavy apps, better accessibility, smaller bundle size

What is CanvasKit?

CanvasKit is a compiled version of Skia (written in C++) converted to WebAssembly that runs in the browser. It provides:

  • Consistent rendering across platforms (web matches mobile/desktop)
  • High performance graphics and animations
  • Full Flutter feature support including custom painters and shaders
  • Pixel-perfect rendering identical to mobile platforms

How CanvasKit Works

text
Flutter App Code (Dart)
Flutter Framework
Skia Graphics Engine (compiled to WebAssembly)
WebGL (GPU acceleration)
Browser Canvas
Screen

Specifying the Renderer

At Build Time

bash
# Build with CanvasKit (default for Flutter 3.x)
flutter build web --web-renderer canvaskit

# Build with HTML renderer
flutter build web --web-renderer html

# Build with auto-detection (chooses best for device)
flutter build web --web-renderer auto

At Runtime

bash
# Run with CanvasKit
flutter run -d chrome --web-renderer canvaskit

# Run with HTML renderer
flutter run -d chrome --web-renderer html

In Code (Advanced)

dart
// main.dart - not commonly used
void main() {
  // This is handled by Flutter framework automatically
  runApp(MyApp());
}

CanvasKit vs HTML Renderer Comparison

Feature Comparison

FeatureCanvasKitHTML Renderer
Rendering QualityPixel-perfectGood but may differ
PerformanceExcellent for graphicsBetter for DOM content
Bundle Size~2-3 MB (Wasm + Skia)~500 KB - 1 MB
Load TimeSlower initial loadFaster initial load
Custom PaintFull supportLimited support
Text RenderingCustom implementationNative browser text
AccessibilityRequires extra workBetter native support
SEORequires extra workBetter support
Browser SupportModern browsers onlyWider compatibility

Performance Comparison

dart
// This widget benefits from CanvasKit
class GraphicsIntensiveWidget extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return CustomPaint(
      size: Size(300, 300),
      painter: ComplexGraphicsPainter(),
    );
  }
}

class ComplexGraphicsPainter extends CustomPainter {
  
  void paint(Canvas canvas, Size size) {
    // Complex drawing operations
    for (int i = 0; i < 1000; i++) {
      final paint = Paint()
        ..color = Colors.blue.withOpacity(0.5)
        ..strokeWidth = 2;

      canvas.drawCircle(
        Offset(size.width / 2, size.height / 2),
        i.toDouble(),
        paint,
      );
    }
  }

  
  bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}

When to Use CanvasKit

✅ Use CanvasKit For:

  1. Graphics-Intensive Apps
dart
// Games, animations, data visualizations
class AnimatedGame extends StatefulWidget {
  
  _AnimatedGameState createState() => _AnimatedGameState();
}

class _AnimatedGameState extends State<AnimatedGame>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;

  
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: Duration(seconds: 2),
      vsync: this,
    )..repeat();
  }

  
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: _controller,
      builder: (context, child) {
        return CustomPaint(
          painter: GamePainter(_controller.value),
        );
      },
    );
  }
}
  1. Custom Painting and Drawing
dart
class DrawingCanvas extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return CustomPaint(
      painter: MyCustomPainter(),
      child: Container(),
    );
  }
}
  1. Apps with Complex UI Effects
dart
class BlurredBackdrop extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return BackdropFilter(
      filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10),
      child: Container(
        color: Colors.black.withOpacity(0.5),
      ),
    );
  }
}
  1. Cross-Platform Consistency Required
    • When web app must look identical to mobile/desktop versions

❌ Avoid CanvasKit For:

  1. Simple Text-Heavy Apps
dart
// Blog, documentation, content-heavy sites
class TextHeavyApp extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: ListView(
          children: [
            Text('Lots of text content...'),
            Text('More text...'),
            // HTML renderer is better here
          ],
        ),
      ),
    );
  }
}
  1. SEO-Critical Websites
  2. Apps with Slow Network/Low-End Devices
  3. Maximum Accessibility Required

CanvasKit Configuration

Customize CanvasKit Loading

Create

text
web/index.html
with custom configuration:

html
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>My Flutter App</title>

  <script>
    // Configure CanvasKit loading
    window.flutterConfiguration = {
      canvasKitBaseUrl: "https://unpkg.com/canvaskit-wasm@0.38.0/bin/",
      canvasKitVariant: "auto", // Options: "auto", "full", "chromium"
    };
  </script>
</head>
<body>
  <script src="flutter.js" defer></script>
</body>
</html>

CanvasKit Variants

javascript
// web/index.html
window.flutterConfiguration = {
  // Use full variant (larger but more compatible)
  canvasKitVariant: "full", // ~2.7 MB

  // Use Chromium variant (smaller, Chrome-only optimizations)
  canvasKitVariant: "chromium", // ~2.3 MB

  // Auto-detect best variant
  canvasKitVariant: "auto", // Recommended
};

Optimizing CanvasKit Performance

1. Lazy Loading

dart
// Load heavy graphics only when needed
class LazyGraphicsPage extends StatefulWidget {
  
  _LazyGraphicsPageState createState() => _LazyGraphicsPageState();
}

class _LazyGraphicsPageState extends State<LazyGraphicsPage> {
  bool _loadGraphics = false;

  
  Widget build(BuildContext context) {
    return Column(
      children: [
        ElevatedButton(
          onPressed: () => setState(() => _loadGraphics = true),
          child: Text('Load Graphics'),
        ),
        if (_loadGraphics)
          GraphicsIntensiveWidget(),
      ],
    );
  }
}

2. Caching

dart
class CachedCustomPainter extends CustomPainter {
  
  void paint(Canvas canvas, Size size) {
    // Cache complex paths/images
    final path = Path()
      ..moveTo(0, 0)
      ..lineTo(size.width, size.height);

    canvas.drawPath(path, Paint());
  }

  
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    // Only repaint when necessary
    return false;
  }
}

3. Use RepaintBoundary

dart
class OptimizedWidget extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return Column(
      children: [
        Text('Static content'),

        // Isolate repainting to this widget only
        RepaintBoundary(
          child: AnimatedGraphicsWidget(),
        ),

        Text('More static content'),
      ],
    );
  }
}

Debugging CanvasKit

Check Active Renderer

dart
import 'package:flutter/foundation.dart';

void main() {
  print('Platform: ${defaultTargetPlatform}');
  print('Is Web: ${kIsWeb}');

  runApp(MyApp());
}

DevTools Performance

bash
# Run with performance overlay
flutter run -d chrome --profile --web-renderer canvaskit

# Open DevTools
flutter pub global activate devtools
flutter pub global run devtools

Bundle Size Optimization

bash
# Minify and compress
flutter build web --release --web-renderer canvaskit --dart-define=FLUTTER_WEB_USE_SKIA=true

# Check bundle size
ls -lh build/web/

Browser Compatibility

BrowserCanvasKit Support
Chrome 88+✅ Full support
Firefox 89+✅ Full support
Safari 14+✅ Full support
Edge 88+✅ Full support
Mobile browsers⚠️ May have performance issues

Fallback Strategy

html
<!-- web/index.html -->
<script>
  // Detect WebAssembly support
  if (typeof WebAssembly !== 'object') {
    // Fallback to HTML renderer
    window.flutterConfiguration = {
      renderer: "html"
    };
  } else {
    // Use CanvasKit
    window.flutterConfiguration = {
      renderer: "canvaskit"
    };
  }
</script>

Best Practices

  1. Choose Renderer Based on Use Case: Graphics apps → CanvasKit, Content apps → HTML
  2. Test on Target Devices: Performance varies across devices
  3. Monitor Bundle Size: CanvasKit adds significant size
  4. Use Auto Renderer: Let Flutter choose optimal renderer
  5. Optimize Assets: Compress images and reduce asset sizes
  6. Profile Performance: Use Chrome DevTools to identify bottlenecks

Common Issues and Solutions

Issue 1: Slow Initial Load

Solution: Use HTML renderer or implement loading screen:

dart
class LoadingApp extends StatefulWidget {
  
  _LoadingAppState createState() => _LoadingAppState();
}

class _LoadingAppState extends State<LoadingApp> {
  bool _isLoaded = false;

  
  void initState() {
    super.initState();
    // Simulate CanvasKit loading
    Future.delayed(Duration(seconds: 2), () {
      setState(() => _isLoaded = true);
    });
  }

  
  Widget build(BuildContext context) {
    if (!_isLoaded) {
      return Center(child: CircularProgressIndicator());
    }
    return MyApp();
  }
}

Issue 2: Text Rendering Quality

Solution: Use native text widgets when possible:

dart
// Prefer Material/Cupertino text widgets
Text('High quality text') // Uses platform text rendering

Important: CanvasKit provides desktop-quality graphics on the web but comes with larger bundle sizes and longer load times. Choose the renderer that best fits your app's needs.

Documentation: Flutter Web Renderers