Short Excerpts

Short Insights on Previously Covered Random Topics

Use-Site Variance

Use-Site Variance in Kotlin Explained: When & How It Works

Kotlin is a powerful and flexible programming language that introduces many advanced features to make development easier. One such feature is Use-Site Variance in Kotlin, which helps handle type variance effectively in generic programming. If you’ve ever struggled with understanding variance in Kotlin, this guide will break it down in a simple, easy-to-understand way.

What is Use-Site Variance in Kotlin?

In Kotlin, variance defines how different types relate to each other in a type hierarchy when dealing with generics. Generics allow you to create flexible and reusable code, but without proper variance handling, type safety issues may arise.

Kotlin provides two types of variance:

  1. Declaration-Site Variance — Defined at the class level using out (covariance) and in (contravariance).
  2. Use-Site Variance — Applied at the point where a generic class is used, rather than where it is declared.

Use-Site Variance is particularly useful when you don’t have control over the generic class declaration but still need to enforce type variance.

When to Use Use-Site Variance in Kotlin?

Use-Site Variance in Kotlin is useful in scenarios where:

  • You are working with a generic class that doesn’t specify variance at the declaration level.
  • You need to ensure type safety when passing a generic object to a function.
  • You want to restrict read and write operations based on the expected type.

Understanding when to use it is important because incorrect usage may lead to type mismatches and compilation errors.

BTW, How does use-site variance work in Kotlin?

Kotlin supports use-site variance, you can specify variance at the use site, which means you can indicate the variance for a specific occurrence of a type parameter, even if it can’t be declared as covariant or contravariant in the class declaration. Let’s break down the concepts and see how use-site works.

In Kotlin, many interfaces, like MutableList, are not covariant or contravariant by default because they can both produce and consume values of the types specified by their type parameters. However, in certain situations, a variable of that type may be used only as a producer or only as a consumer.

Consider the function copyData that copies elements from one collection to another:

Kotlin
fun <T> copyData(source: MutableList<T>, destination: MutableList<T>) {
    for (item in source) {
        destination.add(item)
    }
}

In this function, both the source and destination collections have an invariant type. However, the source collection is only used for reading, and the destination collection is only used for writing. In this case, the element types of the collections don’t need to match exactly.

To make this function work with lists of different types, you can introduce a second generic parameter:

Kotlin
fun <T : R, R> copyData(source: MutableList<T>, destination: MutableList<R>) {
    for (item in source) {
        destination.add(item)
    }
}

In this modified version, you declare two generic parameters representing the element types in the source and destination lists. The source element type (T) should be a subtype of the elements in the destination list (R).

However, Kotlin provides a more elegant way to express this using use-site variance. If the implementation of a function only calls methods that have the type parameter in the “out” position (as a producer) or only in the “in” position (as a consumer), you can add variance modifiers to the particular usages of the type parameter in the function definition.

For example, you can modify the copyData function as follows:

Kotlin
fun <T> copyData(source: MutableList<out T>, destination: MutableList<T>) {
    for (item in source) {
        destination.add(item)
    }
}

In this version, you specify the out modifier for the source parameter, which means it’s a projected (restricted) MutableList. You can only call methods that return the generic type parameter (T) or use it in the “out” position. The compiler prohibits calling methods where the type parameter is used as an argument (“in” position).

Here’s an example usage:

Kotlin
val ints = mutableListOf(1, 2, 3)
val anyItems = mutableListOf<Any>()
copyData(ints, anyItems)
println(anyItems) // [1, 2, 3]

When using use-site variance in Kotlin, there are limitations on the methods that can be called on a projected type. If you are using a projected type, you may not be able to call certain methods that require the type parameter to be used as an argument (“in” position) :

Kotlin
val list: MutableList<out Number> = ...
list.add(42) // Error: Out-projected type 'MutableList<out Number>' prohibits the use of 'fun add(element: E): Boolean'

Here, list is declared as a MutableList<out Number>, which is an out-projected type. The out projection restricts the type parameter Number to only be used in the “out” position, meaning it can only be used as a return type or read from. You cannot call the add method because it requires the type parameter to be used as an argument (“in” position).

If you need to call methods that are prohibited by the projection, you should use a regular type instead of a projection. In this case, you can use MutableList<Number> instead of MutableList<out Number>. By using the regular type, you can access all the methods available for that type.

Regarding the concept of using the in modifier, it indicates that in a particular location, the corresponding value acts as a consumer, and the type parameter can be substituted with any of its supertypes. This is similar to the contravariant position in Java’s bounded wildcards.

For example, the copyData function can be rewritten using an in-projection:

Kotlin
fun <T> copyData(source: MutableList<T>, destination: MutableList<in T>) {
    for (item in source) {
        destination.add(item)
    }
}

In this version, the destination parameter is projected with the in modifier, indicating that it can consume elements of type T or any of its supertypes. This allows you to copy elements from the source list to a destination list with a broader type.

It’s important to note that use-site variance declarations in Kotlin correspond directly to Java’s bounded wildcards. MutableList<out T> in Kotlin is equivalent to MutableList<? extends T> in Java, while the in-projected MutableList<in T> corresponds to Java’s MutableList<? super T>.

Use-site projections in Kotlin can help widen the range of acceptable types and provide more flexibility when working with generic types, without the need for separate covariant or contravariant interfaces.

Conclusion

Use-Site Variance in Kotlin is a powerful feature that ensures type safety while working with generics. By using out when you only need to retrieve values and in when you only need to pass values, you can effectively manage type variance without modifying class declarations.

Understanding how and when to use Use-Site Variance in Kotlin can help you write cleaner, more flexible, and safer generic code. Start experimenting with it in your Kotlin projects and see how it simplifies handling type variance..!

Jetpack Compose UI Components

The Ultimate Guide to Jetpack Compose UI Components

Jetpack Compose has revolutionized Android UI development by providing a declarative approach to building modern and dynamic user interfaces. If you’re new to Jetpack Compose or looking for a comprehensive guide on UI components, this blog will walk you through the essential elements used to create stunning Android apps. From basic text displays to complex interactive components, we’ve got it all covered.

Why Jetpack Compose?

Jetpack Compose simplifies UI development by allowing developers to create interfaces with less boilerplate code while improving performance and maintainability. Key benefits include:

  • Declarative UI: Define UI components with a reactive programming model.
  • Interoperability: Easily integrates with existing Views.
  • State Management: Works seamlessly with LiveData, Flow, and ViewModel.
  • Customization: Highly flexible and adaptable for various design needs.

Now, let’s explore the core UI components available in Jetpack Compose!

Basic UI Components

These foundational elements are the building blocks of any Compose-based UI.

1. Text

The Text composable is used to display text on the screen.

Kotlin
Text(text = "Hello, Jetpack Compose!")

2. Button

A simple button for user interactions.

Kotlin
Button(onClick = { /* Handle click */ }) {
    Text("Click Me")
}

3. OutlinedButton

A button with an outlined border.

Kotlin
OutlinedButton(onClick = { /* Handle click */ }) {
    Text("Outlined Button")
}

4. IconButton

A button designed to hold an icon.

Kotlin
IconButton(onClick = { /* Handle click */ }) {
    Icon(Icons.Default.Favorite, contentDescription = "Favorite")
}

5. FloatingActionButton (FAB)

A circular button often used for primary actions.

Kotlin
FloatingActionButton(onClick = { /* Handle click */ }) {
    Icon(Icons.Default.Add, contentDescription = "Add")
}

Input Components

Capture user input effectively with these components.

1. TextField

Enables users to enter text.

Kotlin
var text by remember { mutableStateOf("") }
TextField(value = text, onValueChange = { text = it }, label = { Text("Enter text") })

2. Checkbox

Used for boolean input.

Kotlin
var checked by remember { mutableStateOf(false) }
Checkbox(checked = checked, onCheckedChange = { checked = it })

3. Switch

A toggle switch for binary states.

Kotlin
var switched by remember { mutableStateOf(false) }
Switch(checked = switched, onCheckedChange = { switched = it })

4. RadioButton

For mutually exclusive options.

Kotlin
RadioButton(selected = true, onClick = { /* Handle selection */ })

Selection Components

1. DropdownMenu

A dropdown for multiple options.

Kotlin
DropdownMenu(expanded = true, onDismissRequest = { /* Handle dismiss */ }) {
    DropdownMenuItem(text = { Text("Option 1") }, onClick = { /* Handle click */ })
}

2. Slider

For selecting values within a range.

Kotlin
var sliderValue by remember { mutableStateOf(0f) }
Slider(value = sliderValue, onValueChange = { sliderValue = it }, valueRange = 0f..100f)

Layout Components

Create structured layouts using these flexible components.

1. Column

Arranges elements vertically.

Kotlin
Column {
    Text("Item 1")
    Text("Item 2")
}

2. Row

Arranges elements horizontally.

Kotlin
Row {
    Text("Left")
    Spacer(modifier = Modifier.width(8.dp))
    Text("Right")
}

3. Box

For overlaying components.

Kotlin
Box {
    Text("Hello in a Box!")
}

4. Card

A container with elevation and rounded corners.

Kotlin
Card(elevation = 4.dp) {
    Text("This is a card!")
}

List & Lazy Components

Efficiently display lists using these components.

1. LazyColumn

A vertically scrolling list optimized for performance.

Kotlin
LazyColumn {
    items(10) { index ->
        Text("Item #$index")
    }
}

2. LazyRow

A horizontally scrolling list.

Kotlin
LazyRow {
    items(10) { index ->
        Text("Item #$index")
    }
}

Dialogs & Notifications

1. AlertDialog

A pop-up dialog box.

Kotlin
AlertDialog(
    onDismissRequest = { /* Handle dismiss */ },
    confirmButton = {
        Button(onClick = { /* Confirm action */ }) { Text("OK") }
    },
    title = { Text("Dialog Title") },
    text = { Text("This is a dialog message.") }
)

2. Snackbar

Temporary notification messages.

Kotlin
val snackbarHostState = remember { SnackbarHostState() }
SnackbarHost(hostState = snackbarHostState)

Other UI Components

1. ProgressIndicator

Indicates loading states.

Kotlin
CircularProgressIndicator()

LinearProgressIndicator(progress = 0.5f)

2. Surface

For defining background and themes.

Kotlin
Surface(color = Color.Gray) {
    Text("Styled Surface")
}

Conclusion

Jetpack Compose simplifies UI development, providing a modern and scalable approach to building Android apps. By mastering these core UI components, you can create highly interactive and visually appealing applications with minimal effort.

Kotlin StateFlow and SharedFlow

Kotlin StateFlow and SharedFlow Explained: A Beginner-Friendly Guide

Kotlin’s Flow API has transformed the way we think about asynchronous data streams. But when your app needs to hold state or broadcast events, two specialized types of Flows shine the brightest: StateFlow and SharedFlow.

In this guide, we’ll break down StateFlow and SharedFlow in a simple way. Whether you’re working with Jetpack Compose, MVVM, or traditional Android UI, you’ll understand when and how to use each one — with examples.

StateFlow — Holds a State

StateFlow is similar to LiveData and is used to store a single state that updates over time.

Kotlin
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*

fun main() = runBlocking {
    val stateFlow = MutableStateFlow(0)

    val job = launch {
        stateFlow.collect { value ->
            println("Collector received: $value")
        }
    }

    delay(500)
    stateFlow.value = 1
    delay(500)
    stateFlow.value = 2
    delay(500)
    job.cancel()
}


//Output

Collector received: 0
Collector received: 1
Collector received: 2

StateFlow always emits the latest value to collectors. It behaves like LiveData, and collectors receive the current state immediately upon subscription.

SharedFlow — Broadcasts Data to Multiple Collectors

Kotlin
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*

fun main() = runBlocking {
    // Create a MutableSharedFlow with a buffer capacity of 2
    val sharedFlow = MutableSharedFlow<Int>(
        replay = 0,
        extraBufferCapacity = 2
    )

    val job1 = launch {
        sharedFlow.collect { value ->
            println("Collector 1 received: $value")
        }
    }

    val job2 = launch {
        sharedFlow.collect { value ->
            println("Collector 2 received: $value")
        }
    }

    // Delay to ensure collectors are active before emitting
    delay(100)

    sharedFlow.emit(10)
    sharedFlow.emit(20)

    delay(500)

    job1.cancel()
    job2.cancel()
}

// Output

Collector 1 received: 10
Collector 2 received: 10
Collector 1 received: 20
Collector 2 received: 20

By default, MutableSharedFlow has no buffer and replay = 0, meaning it won’t emit any value unless a collector is ready at the moment of emission.

  • We set extraBufferCapacity = 2, allowing SharedFlow to buffer a couple of values while the collectors start.
  • We add delay(100) before emitting, ensuring both collectors are already collecting.

This way, both collectors reliably receive all values.

SharedFlow broadcasts emitted values to all active collectors. It’s great for one-time events (like navigation, snackbars, etc.), and multiple collectors will receive the same emissions.

Conclusion

Kotlin’s StateFlow and SharedFlow are powerful tools to build reactive UIs that are predictable, scalable, and cleanly architected. Understanding the difference between state and event helps you choose the right flow for the right situation.

Mastering Jetpack Compose

Mastering Jetpack Compose: The Ultimate Guide to Navigation, State Management, Animations, and More

Jetpack Compose is revolutionizing Android UI development, offering a declarative, efficient, and intuitive approach to building beautiful applications. Whether you’re just starting or looking to refine your expertise, this guide will help you understand key aspects such as navigation, state management, animations, custom composables, performance optimization, and theming in Jetpack Compose.

Navigation in Jetpack Compose

Setting Up Navigation

Jetpack Compose replaces traditional Fragment-based navigation with NavHost and NavController. First, add the dependency:

Kotlin
implementation("androidx.navigation:navigation-compose:2.7.5")

Basic Navigation Example

Kotlin
@Composable
fun MyApp() {
    val navController = rememberNavController()
    NavHost(navController, startDestination = "home") {
        composable("home") { HomeScreen(navController) }
        composable("details") { DetailsScreen() }
    }
}

@Composable
fun HomeScreen(navController: NavController) {
    Column {
        Text("Home Screen")
        Button(onClick = { navController.navigate("details") }) {
            Text("Go to Details")
        }
    }
}

@Composable
fun DetailsScreen() {
    Text("Details Screen")
}

Passing Data Between Screens

To pass arguments:

Kotlin
composable("details/{userId}") { backStackEntry ->
    val userId = backStackEntry.arguments?.getString("userId")
    DetailsScreen(userId)
}

Navigate with:

Kotlin
navController.navigate("details/123")

State Management in Jetpack Compose

Jetpack Compose follows unidirectional data flow (UDF). Here are the key approaches to managing state:

Using remember and mutableStateOf (Local State)

Kotlin
@Composable
fun Counter() {
    var count by remember { mutableStateOf(0) }
    
    Column {
        Text("Count: $count")
        Button(onClick = { count++ }) {
            Text("Increment")
        }
    }
}

Using ViewModel (Recommended for Shared State)

Add ViewModel dependency:

Kotlin
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.7.0")
Kotlin
class CounterViewModel : ViewModel() {
    var count by mutableStateOf(0)
        private set

    fun increment() {
        count++
    }
}

@Composable
fun CounterScreen(viewModel: CounterViewModel = viewModel()) {
    Column {
        Text("Count: ${viewModel.count}")
        Button(onClick = { viewModel.increment() }) {
            Text("Increment")
        }
    }
}

Animations in Jetpack Compose

Simple Animation Example

Kotlin
@Composable
fun AnimatedBox() {
    var expanded by remember { mutableStateOf(false) }
    val size by animateDpAsState(if (expanded) 200.dp else 100.dp, label = "")

    Box(
         modifier = Modifier
            .size(size)
            .background(Color.Blue)
            .clickable { expanded = !expanded }
    )
}

Advanced Animation with AnimatedVisibility

Kotlin
@Composable
fun AnimatedText(visible: Boolean) {
    AnimatedVisibility(visible) {
        Text("Hello, Jetpack Compose!", fontSize = 24.sp)
    }
}

Custom Composables

Reusable Button Composable

Kotlin
@Composable
fun CustomButton(text: String, onClick: () -> Unit) {
    Button(onClick = onClick) {
        Text(text)
    }
}

@Composable
fun ExampleUsage() {
    CustomButton(text = "Click Me") {
        println("Button Clicked!")
    }
}

Performance Optimization in Compose

Avoid Unnecessary Recompositions

Use remember to store expensive calculations:

Kotlin
@Composable
fun ExpensiveOperation() {
    val result = remember { computeSomethingExpensive() }
    Text("Result: $result")
}

Use LaunchedEffect for Side Effects

Kotlin
@Composable
fun TimerEffect() {
    LaunchedEffect(Unit) {
        delay(1000L)
        println("Executed after 1 second")
    }
}

Theming and Styling with Material3

Setting Up Material3

Add the dependency:

Kotlin
implementation("androidx.compose.material3:material3:1.2.0")

Defining a Custom Theme

Define colors in Color.kt:

Kotlin
val PrimaryColor = Color(0xFF6200EE)
val SecondaryColor = Color(0xFF03DAC5)

And apply them in Theme.kt:

Kotlin
val myColorScheme = lightColorScheme(
    primary = PrimaryColor,
    secondary = SecondaryColor
)

@Composable
fun MyTheme(content: @Composable () -> Unit) {
    MaterialTheme(
        colorScheme = myColorScheme,
        typography = Typography(),
        content = content
    )
}

Conclusion

Jetpack Compose is an exciting evolution in Android UI development, simplifying layouts, interactions, and performance optimizations. Mastering navigation, state management, animations, and theming allows you to build more efficient, maintainable, and beautiful Android applications.

JavaScript vs. TypeScript

JavaScript vs. TypeScript: Which One Should You Learn First?

If you’re stepping into the world of web development, you’re bound to face the question: JavaScript vs. TypeScript — which should you learn first?

Both languages are essential tools in modern development. But depending on your goals, one might be a better starting point. In this post, we’ll break down what each language does, how they differ, and help you decide which one to tackle first.

What Is JavaScript?

JavaScript is a scripting language used to create interactive websites. It’s the backbone of front-end development and runs in every modern browser. Think dynamic buttons, real-time updates, and interactive forms — that’s JavaScript at work.

TypeScript
function greet(name) {
  console.log("Hello, " + name + "!");
}

greet("Amol");

Here,

  • function greet(name) defines a function.
  • console.log outputs text to the browser console.
  • Calling greet("Amol") logs: Hello, Amol!

Simple, right?

What Is TypeScript?

TypeScript is a superset of JavaScript. That means all JavaScript is valid TypeScript, but TypeScript adds extra features, especially static typing.

With TypeScript, you can catch errors before running your code. It helps teams build large applications with fewer bugs and better structure.

TypeScript
function greet(name: string): void {
  console.log("Hello, " + name + "!");
}

greet("Amol");

What’s Different?

  • name: string explicitly declares that name must be a string.
  • : void indicates the function doesn’t return anything.

If you try greet(42), TypeScript will throw an error before running the code. 

TypeScript
Error : Argument of type 'number' is not assignable to parameter of type 'string'.

That’s a big win for reliability.

JavaScript vs. TypeScript: Key Differences

FeatureJavaScriptTypeScript
TypingDynamicStatic (optional)
CompilationNot requiredCompiles to JavaScript
Learning CurveEasier for beginnersSteeper, but scalable
ToolingGoodExcellent with editors like VS Code
Error CheckingAt runtimeAt compile time

Should You Learn JavaScript or TypeScript First?

Short answer:

  • If you’re just starting out: Learn JavaScript first. It’s simpler, widely used, and gives you instant feedback in the browser.
  • If you already know JavaScript basics: Add TypeScript to your toolkit. It makes your code more predictable and maintainable.

Let’s look deeper.

Why Learn JavaScript First?

  • It’s the foundation of web development.
  • Works out of the box in any browser.
  • Huge community support and learning resources.
  • Helps you understand core programming concepts like variables, functions, loops, and objects.

Why Learn TypeScript Later?

  • It’s built on top of JavaScript, so knowing JS first helps.
  • Better for large projects or team-based development.
  • Adds type safety, reducing bugs and improving code readability.

Real-World Example

Let’s say you’re building a to-do app.

JavaScript Version:

JavaScript
function addTask(task) {
  tasks.push(task);
}

You might accidentally do:

JavaScript
addTask(123);

It still runs — but it might break your UI.

TypeScript Version:

TypeScript
function addTask(task: string): void {
  tasks.push(task);
}

Try addTask(123) here, and TypeScript stops you immediately. Safer and cleaner.

Final Thoughts: JavaScript vs. TypeScript

The JavaScript vs. TypeScript debate isn’t about which one is better overall — it’s about what’s better for you right now.

Start with JavaScript if you’re new to programming. Once you’re comfortable, leveling up with TypeScript will give you a big advantage in writing scalable, error-resistant code.

In short:

  • Beginner? Learn JavaScript.
  • Already know JS? Learn TypeScript.

Both skills are in high demand, and together they make you a stronger, more confident developer.

FAQs

Is TypeScript harder than JavaScript?

Yes, a bit. It adds new concepts like types and interfaces. But once you know JavaScript, the transition is smooth.

Can I skip JavaScript and go straight to TypeScript?

Technically, yes. But it’s like learning to sprint before you can walk. TypeScript assumes you understand JavaScript.

Are JavaScript and TypeScript used together?

Absolutely. TypeScript compiles down to JavaScript, so they work hand-in-hand in modern projects.

Conclusion

JavaScript vs. TypeScript isn’t a battle — it’s a journey. Start with JavaScript to build a strong foundation. Then, move to TypeScript to take your skills to the next level.

By mastering both, you open the door to more job opportunities, better projects, and cleaner code.

Happy Scripting..!

manually optimize your WordPress site

How to Optimize Your Astra + Elementor WordPress Site Without Breaking the Design (No Plugins Needed)

Optimizing your WordPress website can feel like a balancing act — especially when you’re using powerful tools like Elementor and Astra. On one hand, you want a fast, lightweight site. On the other, you don’t want to lose the design flexibility and beautiful layouts you’ve worked hard to build.

The good news is, you don’t have to sacrifice either.

In this guide, you’ll learn how to manually optimize your WordPress site built with Astra and Elementor — without adding extra plugins or breaking your layout. Every tweak is custom, safe, and focused on performance and maintainability.

Why Avoid Plugin-Based Optimization?

Plugins like WP Rocket, Asset CleanUp, and Autoptimize can be helpful — but they also come with overhead, compatibility concerns, and sometimes even break Elementor layouts if not configured correctly.

Instead, custom code and manual configuration give you:

  • Full control over what loads and when
  • Zero plugin bloat
  • Better long-term stability
  • Higher performance scores with less risk

Technical Disclaimer: Always back up your website before making any direct changes.

Reduce Elementor Bloat: Only Load What You Need

Elementor is powerful, but it loads more than most sites use. Let’s cut the fat.

a. Enable Optimized DOM Output

Go to: Elementor → Settings → Experiments → Optimized DOM OutputEnable

This reduces unnecessary wrapper divs and keeps the page structure clean — improving both speed and SEO.

b. Turn Off Unused Elementor Features

Head to: Elementor → Settings → Features

Disable what you don’t use:

  • Landing Page
  • Icon Libraries
  • Usage Data tracking
  • Global Fonts or Colors (if you style via theme)

Every feature you turn off lightens the frontend payload.

Clean Up WordPress Core Bloat

WordPress ships with a lot of scripts and styles you don’t need — especially if you’re using a visual builder like Elementor.

Add the following to your child theme’s functions.php file:

PHP
function dequeue_extra_assets() {
    // Disable Gutenberg block CSS
    wp_dequeue_style('wp-block-library');

    // Disable Elementor icons if unused
    wp_dequeue_style('elementor-icons');

    // Remove dashicons for non-logged-in users
    if (!is_user_logged_in()) {
        wp_deregister_style('dashicons');
    }
}
add_action('wp_enqueue_scripts', 'dequeue_extra_assets', 100);

This reduces unnecessary CSS/JS, improving your initial load and Largest Contentful Paint (LCP).

Use WebP Images and Lazy Loading (The Smart Way)

WebP images are 30–40% smaller than JPEG or PNG.

a. Upload WebP Images Directly

Most modern browsers support WebP. If your image editor doesn’t export WebP, use an online tool like Squoosh.

b. Use the <picture> Tag (If You’re Comfortable With HTML)

Insert a Custom HTML widget in Elementor and paste:

HTML
<picture>
  <source srcset="/wp-content/uploads/2025/04/image.webp" type="image/webp">
  <img src="/wp-content/uploads/2025/04/image.jpg" alt="Descriptive Alt" loading="lazy">
</picture>

This ensures fallback compatibility with older browsers while serving WebP to modern ones.

Inline Critical CSS for Faster First Paint

This is an advanced technique but highly effective.

Use a tool like Critical to generate above-the-fold CSS. Then:

  • Paste it into Elementor → Custom Code
  • Or add it inside <style> tags in your child theme’s header.php

Warning: Only do this for CSS used in the viewport. Inline too much, and you’ll slow down the site instead of speeding it up.

Disable Emojis, Embeds, and WordPress Extras

These features run JavaScript on every page — even if you don’t use them.

Add this to functions.php:

PHP
// Disable emojis
remove_action('wp_head', 'print_emoji_detection_script', 7);
remove_action('wp_print_styles', 'print_emoji_styles');

// Disable embeds
function disable_embeds_code_init() {
    remove_action('rest_api_init', 'wp_oembed_register_route');
    remove_filter('oembed_dataparse', 'wp_filter_oembed_result', 10);
    remove_action('wp_head', 'wp_oembed_add_discovery_links');
    remove_action('wp_head', 'wp_oembed_add_host_js');
}
add_action('init', 'disable_embeds_code_init', 9999);

That’s a quick win for TTFB and script execution time.

Note:- Time to First Byte (TTFB) refers to the time between the browser requesting a page and when it receives the first byte of information from the server.

Defer JavaScript for Non-Critical Scripts

JavaScript blocking your render? Let’s fix that:

PHP
function defer_custom_scripts($tag, $handle, $src) {
    if (is_admin()) return $tag;

    $defer_list = ['elementor-frontend', 'astra-theme-js']; // Add more as needed
    if (in_array($handle, $defer_list)) {
        return '<script src="' . esc_url($src) . '" defer></script>';
    }
    return $tag;
}
add_filter('script_loader_tag', 'defer_custom_scripts', 10, 3);

This defers specific scripts, allowing HTML and CSS to load first. Keep Elementor’s core scripts untouched unless tested.

Self-Host Fonts: No More Google Fonts Lag

a. Use System Fonts (Fastest)

Go to: Astra → Customize → Global → Typography
 Choose system fonts like:

  • Arial
  • Helvetica
  • Georgia

No external requests = lightning fast loads.

b. Self-Host Custom Fonts

Want to use Poppins or Lato?

  1. Use google-webfonts-helper to generate font files.
  2. Upload to your child theme /fonts folder.
  3. In style.css, add:
CSS
@font-face {
  font-family: 'Poppins';
  src: url('/wp-content/themes/your-child/fonts/poppins.woff2') format('woff2');
  font-display: swap;
}

Apply it via Elementor’s Site Settings → Typography

Server-Side Tweaks for Even More Speed

If your hosting provider allows .htaccess, add:

XML
<IfModule mod_deflate.c>
  AddOutputFilterByType DEFLATE text/css application/javascript text/html
</IfModule>

<IfModule mod_expires.c>
  ExpiresActive On
  ExpiresByType image/webp "access plus 1 year"
  ExpiresByType text/css "access plus 1 month"
  ExpiresByType application/javascript "access plus 1 month"
</IfModule>

This enables compression and long-term caching.

Test Everything: Speed, Stability, and Structure

Use these tools regularly:

  • Lighthouse (DevTools) → Audit Core Web Vitals
  • PageSpeed Insights → Find layout shift or blocking scripts
  • WebPageTest.org → Analyze time to first byte, paint, and filmstrip loading

Each test reveals a new bottleneck — then you optimize again.

Conclusion: Lean, Fast, and Fully in Control

By skipping the plugin route and customizing your Astra + Elementor setup manually, you get the best of both worlds: blazing-fast performance and full design freedom.

You’re not just chasing scores — you’re building a sustainable, scalable website that delights users and ranks well in search engines.

What Is JavaScript?

What Is JavaScript? A Beginner-Friendly Guide to the Web’s Favorite Language

If you’ve ever clicked a button on a website and watched something happen instantly — like a pop-up message, a menu expanding, or an animation — you’ve seen JavaScript in action. But what is JavaScript exactly, and why is it everywhere on the web?

In this beginner-friendly guide, we’ll break down what JavaScript is, what it does, and why it’s one of the most essential languages for web development.

What Is JavaScript?

JavaScript is a high-level programming language used to create interactive effects within web browsers. It runs directly in the browser, allowing web pages to react to user input in real-time.

Originally created in 1995 by Netscape, JavaScript has evolved into a powerful tool that does far more than add simple interactivity. Today, it’s used for everything from building web apps and games to powering server-side applications with frameworks like Node.js.

Unlike HTML (which structures content) and CSS (which styles it), JavaScript makes websites dynamic. Without it, most websites would be static and unresponsive.

Why Is JavaScript So Popular?

There are a few big reasons JavaScript has become the web’s favorite language:

  • Runs in every browser — No installation needed
  • Versatile — Works for front-end and back-end development
  • Huge ecosystem — Thousands of libraries and frameworks like React, Vue, and Angular
  • Active community — Tons of tutorials, forums, and resources for learners

Whether you’re just starting out or aiming to become a full-stack developer, JavaScript is a great first language.

How JavaScript Works

When you open a website, your browser loads HTML, CSS, and JavaScript. HTML gives the structure, CSS styles it, and JavaScript makes it interactive.

JavaScript code can be written directly into an HTML file or in separate .js files. Here’s a simple example:

HTML
<!DOCTYPE html>
<html>
<head>
  <title>My First JS Page</title>
</head>

<body>
  <h1 id="greeting">Hello!</h1>
  <button onclick="changeText()">Click Me</button>

<script>
    function changeText() {
      document.getElementById("greeting").innerText = "You clicked the button!";
    }
</script>

</body>
</html>

Here,

  • onclick="changeText()" tells the browser to run the changeText function when the button is clicked.
  • document.getElementById("greeting") selects the HTML element with the ID of “greeting”.
  • .innerText = "You clicked the button!" changes the text inside the element.

This is JavaScript in its simplest form: responding to an event (a button click) and updating the page content.

Core Concepts in JavaScript

Here are a few fundamental building blocks of the language:

1. Variables

Variables store data values.

JavaScript
let name = "Amol";
const age = 25;

2. Functions

Functions are reusable blocks of code.

JavaScript
function greet(user) {
  console.log("Hello, " + user + "!");
}

3. Events

JavaScript responds to user interactions like clicks, keypresses, or mouse movements.

JavaScript
document.getElementById("btn").addEventListener("click", greetUser);

4. Conditionals

They let you make decisions in your code.

JavaScript
if (age >= 18) {
  console.log("Adult");
} else {
  console.log("Minor");
}

What Can You Build With JavaScript?

JavaScript is incredibly flexible. Here’s what you can build with it:

  • Interactive websites (forms, animations, dropdowns)
  • Single-page applications (like Gmail or Facebook)
  • Mobile apps (with React Native)
  • Games (2D browser games or simple puzzle games)
  • Server-side apps (using Node.js)
  • Browser extensions

It’s truly a full-stack language when combined with frameworks and tools.

Learning JavaScript: Tips for Beginners

  • Start with small projects like to-do lists or calculators.
  • Practice regularly to build muscle memory.
  • Use online resources like MDN Web Docs, freeCodeCamp, or Codecademy.
  • Join communities like Stack Overflow or Reddit’s r/learnjavascript.
  • Don’t rush. Learning to code is a marathon, not a sprint.

Conclusion

So, what is JavaScript? It’s the language that brings the web to life. Without it, websites would be dull and lifeless. For beginners, it’s the perfect entry point into programming thanks to its simplicity, power, and widespread use.

Whether you’re dreaming of becoming a web developer or just curious about how websites work, learning JavaScript is a smart move. It’s not just a coding language — it’s the heartbeat of modern web development.

Happy coding..!

How to Build a Weather App in Kotlin

How to Build a Weather App in Kotlin Using MVVM, Retrofit, and Room

Building an Android app that fetches live weather data is a great way to get hands-on with networking, local storage, and clean architecture principles. In this guide, we’ll build a Weather App in Kotlin using MVVM, Retrofit for API calls, and Room for local caching. It’s a solid project for interviews or real-world use — especially if you’re still working with older setups and haven’t yet moved to Clean + MVVM Architecture, and Jetpack Compose.

Technical Disclaimer:
The code snippets shared here are from an older codebase, so things like the API or the implementation might be different now. If you’re working with the latest tech stack, you’ll probably need to make a few tweaks to the code at different levels.

Weather App Project Overview

Our Weather App will:

  • Fetch weather data from OpenWeatherMap API.
  • Use MVVM (Model-View-ViewModel) architecture for clean code separation.
  • Implement Retrofit for API communication.
  • Store data locally using Room Database for offline access.
  • Display a list of weather forecasts with RecyclerView.
  • Ensure smooth UI updates using LiveData.

Project Structure

Kotlin
WeatherApp/
│── api/
│   ├── WeatherService.kt
│   ├── ApiClient.kt
│── model/
│   ├── WeatherResponse.kt
│── repository/
│   ├── WeatherRepository.kt
│── viewmodel/
│   ├── WeatherViewModel.kt
│── view/
│   ├── MainActivity.kt
│   ├── WeatherAdapter.kt
│── database/
│   ├── WeatherDao.kt
│   ├── WeatherDatabase.kt
│── utils/
│   ├── Constants.kt
│── res/
│   ├── layout/
│   │   ├── activity_main.xml
│   │   ├── item_weather.xml

Setting Up Retrofit for API Calls

First, we need to integrate Retrofit to fetch weather data from OpenWeatherMap.

Add Dependencies

Add these dependencies to your build.gradle (Module: app) file:

Kotlin
dependencies {
    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
    implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.4.1'
}

Create API Interface

Kotlin
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.GET
import retrofit2.http.Query

interface WeatherService {
    @GET("weather")
    suspend fun getWeather(
        @Query("q") city: String,
        @Query("appid") apiKey: String,
        @Query("units") units: String = "metric"
    ): WeatherResponse
}

Create Retrofit Client

Kotlin
object ApiClient {
    private const val BASE_URL = "https://api.openweathermap.org/data/2.5/"

    val instance: WeatherService by lazy {
        Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .build()
            .create(WeatherService::class.java)
    }
}

This setup allows us to fetch weather data efficiently.

Note:- An API key is mandatory. Make sure to create a valid API key — if you use an invalid one or skip it entirely, the API will throw an error response like this:

JSON
{
  "cod": 401,
  "message": "Invalid API key. Please see https://openweathermap.org/faq#error401 for more info."
}

Creating Data Models

The API response will be mapped to data classes.

Kotlin
data class WeatherResponse(
    val name: String,
    val main: Main,
    val weather: List<Weather>
)

data class Main(
    val temp: Double
)

data class Weather(
    val description: String
)

Implementing Room Database

To cache weather data, let’s create a Room Database.

Add Dependencies

Kotlin
dependencies {
    implementation 'androidx.room:room-runtime:2.4.2'
    kapt 'androidx.room:room-compiler:2.4.2'
}

Create Entity & DAO

Kotlin
import androidx.room.*

@Entity
data class WeatherEntity(
    @PrimaryKey val city: String,
    val temperature: Double,
    val description: String
)

@Dao
interface WeatherDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insertWeather(weather: WeatherEntity)

    @Query("SELECT * FROM WeatherEntity WHERE city = :city")
    suspend fun getWeather(city: String): WeatherEntity?
}

Create Database

Kotlin
@Database(entities = [WeatherEntity::class], version = 1)
abstract class WeatherDatabase : RoomDatabase() {
    abstract fun weatherDao(): WeatherDao
}

Creating Repository

The repository will handle data fetching.

Kotlin
class WeatherRepository(private val api: WeatherService, private val dao: WeatherDao) {

    suspend fun getWeather(city: String, apiKey: String): WeatherEntity {
        val response = api.getWeather(city, apiKey)
        val weatherEntity = WeatherEntity(
            city = response.name,
            temperature = response.main.temp,
            description = response.weather.first().description
        )
        dao.insertWeather(weatherEntity)
        return weatherEntity
    }
}

Implementing ViewModel

Kotlin
class WeatherViewModel(private val repository: WeatherRepository) : ViewModel() {
    private val _weather = MutableLiveData<WeatherEntity>()
    val weather: LiveData<WeatherEntity> get() = _weather
    
    fun fetchWeather(city: String, apiKey: String) {
        viewModelScope.launch {
            val data = repository.getWeather(city, apiKey)
            _weather.postValue(data)
        }
    }
}

Creating UI with RecyclerView

Adapter Class

Kotlin
class WeatherAdapter(private val weatherList: List<WeatherEntity>) : RecyclerView.Adapter<WeatherAdapter.ViewHolder>() {
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.item_weather, parent, false)
        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val weather = weatherList[position]
        holder.city.text = weather.city
        holder.temp.text = "${weather.temperature}°C"
        holder.desc.text = weather.description
    }
}

Activity Layout

XML
<RecyclerView
    android:id="@+id/recyclerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

Conclusion

This tutorial covers API integration, MVVM architecture, and local caching. By following these steps, you can build a solid Android app that fetches and stores weather data efficiently.

If you want to take it further, you can experiment with adding new features such as real-time updates, notifications, or even integrating Jetpack Compose for a more modern UI approach. The foundation is now set for you to keep exploring and improving your Android development skills..!

What is CSS

What Is CSS? And How Does It Works

When you open a website and notice the stylish fonts, colors, layout, and smooth transitions — you’re actually looking at the magic of CSS, or Cascading Style Sheets. If HTML is the skeleton of a web page, CSS is the skin, clothes, and personality.

Whether you’re just getting started in web development or brushing up on your skills, understanding how CSS works is essential. In this guide, we’ll break down what CSS is, how it’s used, the different types of CSS, and how the “cascading” part actually plays out.

What Is CSS, Really?

CSS stands for Cascading Style Sheets. It’s a stylesheet language used to describe the look and formatting of HTML (or XML) documents. While HTML structures your web page (text, headings, images), CSS brings it to life with visual styles — like colors, spacing, layout grids, animations, and responsiveness.

Think of it as the design layer of a web page.

Why CSS Matters

Here’s why CSS is so powerful and widely used:

  • It separates content from design, making your code easier to maintain.
  • A single CSS file can style multiple HTML pages.
  • It allows for responsive layouts that work across devices.
  • With animations and transitions, it enables smooth visual effects without JavaScript.
  • CSS is lightweight, fast, and scalable for small or massive websites.

The 3 Types of CSS: Inline, Internal, and External

Now that you know what CSS does, let’s look at how you can use it. There are three primary ways to apply CSS to HTML.

1. Inline CSS: Quick and Dirty

With inline CSS, styles are written directly into HTML tags using the style attribute.

HTML
<p style="color: blue; font-size: 18px;">This is inline CSS</p>

Pros:

  • Easy to apply to one element
  • Good for quick testing

Cons:

  • Not reusable
  • Difficult to maintain
  • Clutters your HTML

Use inline CSS only when absolutely necessary, like overriding something temporarily.

2. Internal CSS: Neat but Limited

Internal CSS is written inside a <style> tag within the <head> section of the HTML document.

HTML
<!DOCTYPE html>
<html>
<head>
  <style>
    p {
      color: green;
      font-size: 20px;
    }
  </style>
</head>
<body>
  <p>This is internal CSS</p>
</body>
</html>

Pros:

  • Keeps everything in one file
  • Easier for small projects or single-page sites

Cons:

  • Can’t be reused across other pages
  • Not optimal for large websites

3. External CSS: The Professional Way

This is the recommended and most scalable way to use CSS. You write all your styles in a separate .css file and link it to your HTML file using a <link> tag.

style.css

CSS
{
  color: red;
  font-size: 22px;
}

index.html

HTML
<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <p>This is external CSS</p>
</body>
</html>

Pros:

  • Clean and organized
  • Reusable across pages
  • Great for team projects

Cons:

  • Requires an extra file request (but can be optimized)

How CSS Selectors Work

CSS is all about selecting HTML elements and applying styles to them. Here are the most commonly used selectors:

Selector TypeSyntaxDescription
Elementp {}Targets all <p> tags
Class.btn {}Targets elements with class="btn"
ID#main {}Targets the element with id="main"
Descendantdiv p {}Targets all <p> inside a <div>
Attributeinput[type="text"]Targets <input> elements with type="text"

You can also combine selectors, use pseudo-classes (:hover:focus, etc.), or write media queries to adapt your design for different screen sizes.

Understanding the Cascade in CSS

The Cascading in CSS refers to the hierarchy and priority of styles when there’s a conflict.

Order of precedence:

  1. Browser default styles
  2. External stylesheets
  3. Internal styles
  4. Inline styles
  5. !important (Overrides everything—use with caution!)

Example:

HTML
<p style="color: blue;">Hello</p>

Even if your external stylesheet has p { color: red; }, the paragraph will still be blue because inline styles win.

Note: Avoid overusing !important. Instead, understand and leverage the natural cascade and specificity of selectors.

Classes vs IDs: What’s the Difference?

Class:

HTML
<p class="highlight">This is a class</p>
CSS
.highlight {
  color: orange;
}
  • Reusable
  • Can apply to multiple elements
  • Prefix with . in CSS

ID:

HTML
<p id="unique">This is an ID</p>
CSS
#unique {
  color: green;
}
  • Should be unique per page
  • Prefix with # in CSS
  • More specific than classes

Bonus: Making Your CSS Responsive

Modern websites must adapt to different screen sizes. You can use media queries to apply styles conditionally:

CSS
@media (max-width: 768px) {
  body {
    font-size: 16px;
  }
}

This rule changes the font size when the screen width is 768px or less — great for mobile optimization.

Conclusion 

CSS is more than just a tool — it’s the visual language of the web. By learning the types of CSS, mastering selectors, and understanding how styles cascade, you set a strong foundation for building responsive, modern websites.

Whether you’re styling a simple blog or working on a complex web app, knowing when and how to apply CSS properly is key to creating beautiful, user-friendly experiences.

TL;DR (Too Long; Didn’t Read)

  • CSS = Cascading Style Sheets, used to style HTML
  • Three types: Inline, Internal, and External
  • Use selectors to target and style HTML elements
  • CSS follows a cascade, where some rules override others
  • Use classes for reuse, IDs for unique elements
  • For responsive design, use media queries
Declaration-Site Variance

Understanding Kotlin Declaration-Site Variance: Kotlin’s In & Out vs. Java Wildcards

Kotlin provides a powerful type system that includes declaration-site variance, making generics more flexible and safe. If you’ve ever worked with generics in Java, you might recall the ? extends and ? super keywords. Kotlin simplifies this with in and out modifiers.

In this blog, we’ll break down declaration-site variance in Kotlin, explore how in and out work, and compare them to Java wildcards to clarify these concepts.

What is Declaration-Site Variance in Kotlin?

In Kotlin, the ability to specify variance modifiers on class declarations provides convenience and consistency because these modifiers apply to all places where the class is used. This concept is known as a declaration-site variance.

Declaration-site variance in Kotlin is achieved by using variance modifiers on type parameters when defining a class. As you already knows there are two main variance modifiers:

  1. out (covariant): Denoted by the out keyword, it allows the type parameter to be used as a return type or read-only property. It specifies that the type parameter can only occur in the “out” position, meaning it can only be returned from functions or accessed in a read-only manner.
  2. in (contravariant): Denoted by the in keyword, it allows the type parameter to be used as a parameter type. It specifies that the type parameter can only occur in the “in” position, meaning it can only be passed as a parameter to functions.

By specifying these variance modifiers on type parameters, you define the variance behavior of the class, and it remains consistent across all usages of the class.

On the other hand, Java handles variance differently through use-site variance. In Java, each usage of a type with a type parameter can specify whether the type parameter can be replaced with its subtypes or supertypes using wildcard types (? extends and ? super). This means that at each usage point of the type, you can decide the variance behavior.

It’s important to note that while Kotlin supports declaration-site variance with the out and in modifiers, it also provides a certain level of use-site variance through the out and in projection syntax (out T and in T). These projections allow you to control the variance behavior in specific usage points within the code.

Declaration-site variance in Kotlin Vs. Java wildcards

In Kotlin, declaration-site variance allows for more concise code because variance modifiers are specified once on the declaration of a class or interface. This means that clients of the class or interface don’t have to think about the variance modifiers. The convenience of declaration-site variance is that the variance behavior is determined at the point of declaration and remains consistent throughout the codebase.

On the other hand, in Java, wildcards are used to handle variance at the use site. To create APIs that behave according to users’ expectations, the library writer has to use wildcards extensively. For example, in the Java 8 standard library, wildcards are used on every use of the Function interface. This can lead to code like Function<? super T, ? extends R> in method signatures.

To illustrate the declaration of the map method in the Stream interface in Java :

Kotlin
/* Java */
public interface Stream<T> {
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
}

In the Java code, wildcards are used in the declaration of the map method to handle the variance of the function argument. This can make the code less readable and more cumbersome, especially when dealing with complex type hierarchies.

In contrast, the Kotlin code uses declaration-site variance, specifying the variance once on the declaration makes the code much more concise and elegant.

Benefits of Declaration-Site Variance in Kotlin

  1. Stronger Type Safety — Prevents incorrect type assignments.
  2. More Readable Code — Clearly defines how a generic class is used.
  3. No Wildcards Needed — Unlike Java’s ? extends and ? super, Kotlin’s variance is built-in.

Conclusion

Understanding declaration-site variance in Kotlin with in and out is crucial for writing type-safe and maintainable generic classes. The out modifier allows a class to only produce values, making it covariant, while in allows a class to only consume values, making it contravariant.

By leveraging these concepts, you can write more flexible, safe, and concise Kotlin code without the complexity of Java’s wildcards.

error: Content is protected !!