codingjoe / django-pictures

Responsive cross-browser image library using modern codes like AVIF & WebP

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

`contrib.rest_framework.PictureField` serialization is slow

amureki opened this issue · comments

Greetings Johannes!

While doing bulk operations with images that involved this library, I noticed a noticeable difference in the serialization time compared to the standard DRF library.
Here is a quick snippet that I am trying:

import time
from django.db import models

from pictures.contrib.rest_framework import PictureField as PictureFieldRest
from rest_framework.fields import ImageField as DRFImageField

class MyPicture(models.Model):
    image = PictureField(
        aspect_ratios=["3/2", "1/1", "15/2"],
        file_types=["WEBP", "JPEG"],
        width_field="image_width",
        height_field="image_height",
    )
    image_width = models.PositiveSmallIntegerField(editable=False)
    image_height = models.PositiveSmallIntegerField(editable=False)


def test_serialization_speed():
    items_count = 5000

    start = time.time()
    serialized = []
    for item in MyPicture.objects.all()[:items_count]:
        serialized.append(
            DRFImageField().to_representation(item.image)
        )
    print("DRF ImageField serialization TIME: ", time.time() - start)

    start = time.time()
    serialized = []
    for item in MyPicture.objects.all()[:items_count]:
        serialized.append(
            PictureFieldRest().to_representation(item.image)
        )
    print("PictureField serialization TIME: ", time.time() - start)

The results on my dev machine (MacBook M1, 16 Gb) are the following:

DRF ImageField serialization TIME:  0.11259627342224121
PictureField serialization TIME:  11.82898998260498

I believe that the issue comes from the serialization of this part:
https://github.com/codingjoe/django-pictures/blob/main/pictures/contrib/rest_framework.py#L25-L38

We have plenty of combinations of aspect ratios and containers, each of them has to be serialized from SimplePicture object to its url, which leads to a heavy CPU-bound operation.
However, I cannot yet come up with the solution to that problem.
Would you have any ideas on this?

Best,
Rust

@amureki, as a see it, we currently render the ratios part of the payload twice if you declare a specific ratio. We first serialize everything and overwrite it later. Avoiding this could resolve in a considerable performance boost. Would you care to provide a patch?