Skip to content

Optimize product loading time#135

Merged
alexshikov merged 6 commits intotrunkfrom
optimize-load-time
Jan 24, 2025
Merged

Optimize product loading time#135
alexshikov merged 6 commits intotrunkfrom
optimize-load-time

Conversation

@alexshikov
Copy link
Contributor

@alexshikov alexshikov commented Jan 23, 2025

⬅️ As Is

  • Product loading takes a while (3-4 seconds), due to sequential API requests

➡️ To Be

  • Parallel possible API requests to reduce loading time
  • Product loading time is within 2 seconds now
  • Introduced first usage of async coroutines

☑️ Checklist

  • Useless comments and/or Log.d etc are removed
  • Unit test are covered
  • Code has been deployed and tested on STG
  • ClickUp ticket status has been updated to production
  • Update CHANGELOG.md with the new changes

@alexshikov alexshikov requested a review from akueisara January 23, 2025 18:38
@alexshikov alexshikov self-assigned this Jan 23, 2025
Comment on lines 191 to 209

// Those API requests are independent and can be run in parallel
val storeJob =
CoroutineScope(coroutineContext).async {
virtusizeAPIService.getStoreProduct(productId)
}
val productTypesJob =
CoroutineScope(coroutineContext).async {
virtusizeAPIService.getProductTypes()
}
val langJob =
CoroutineScope(coroutineContext).async {
virtusizeAPIService.getI18n(language)
}

val storeProductResponse = storeJob.await()
val productTypesResponse = productTypesJob.await()
val i18nResponse = langJob.await()

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://stackoverflow.com/questions/59368838/difference-between-coroutinescope-and-coroutinescope-in-kotlin
For calling async, you can create a coroutine scope as follows:

internal suspend fun fetchInitialData(
        language: VirtusizeLanguage?,
        product: VirtusizeProduct,
    ) = coroutineScope {
    // optional: It doesn't return a Job instead of Deferred although it inherits from Job. 
    // It might be better to remove the job naming
    val storeProduct = async {
        virtusizeAPIService.getStoreProduct(productId)
    }

    storeProduct.await()
    ...
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Often we need to use the result of await() which is technically a desirable object:

val storeProductJob = async {
    virtusizeAPIService.getStoreProduct(productId)
}

val storeProduct = storeProductJob.await()

Would using another prefix, like storeProductDeferred or storeProductAsync be a better option?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coroutine scope created. Still keep the naming though. Let me know if you have a better naming or approach to use result of .await().

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would think storeProductDeferred or storeProductAsync sounds better, but it's up to you.

@alexshikov
Copy link
Contributor Author

@akueisara fyi, because linter breaks the formatting of the whole productCheck function, I've decided to refactor it a bit by reducing nesting. Sorry for including this in the same PR, but the linter mess the code anyway.

@alexshikov alexshikov merged commit 1c00080 into trunk Jan 24, 2025
3 checks passed
@alexshikov alexshikov deleted the optimize-load-time branch January 24, 2025 14:16
@alexshikov alexshikov mentioned this pull request Feb 14, 2025
13 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants