Edit Page

JavaScript Dead Code Elimination (DCE)

The Kotlin/JS Gradle plugin includes a dead code elimination (DCE) tool. Dead code elimination is often also called tree shaking. It reduces the size or the resulting JavaScript code by removing unused properties, functions, and classes.

Unused declarations can appear in cases like:

  • A function is inlined and never gets called directly (which happens always except for few situations).
  • A module uses a shared library. Its parts that you don't use still get into the resulting bundle without DCE. For example, the Kotlin standard library contains functions for manipulating lists, arrays, char sequences, adapters for DOM, and so on. Altogether, they comprise about 1.3 mb file. A simple "Hello, world" application only requires console routines, which is only few kilobytes for the entire file.

Kotlin/JS Gradle plugin handles DCE automatically when you build a production bundle, for example, with browserProductionWebpack task. The development bundling tasks don't include DCE.

Excluding declarations from DCE

Sometimes you may need to keep a function or a class in the resulting JavaScript code even if you don't use it in your module, for example, if you're going to use it in the client JavaScript code.

To keep certain declarations from elimination, add the dceTask block into the Gradle build script and list the declarations as the arguments of the keep function. An argument must be the declaration's fully qualified name with the module name as a prefix: moduleName.dot.separated.package.name.declarationName

kotlin.target.browser {
    dceTask {
        keep 'myKotlinJSModule.org.example.getName', 'myKotlinJSModule.org.example.User'
    }
}
kotlin.target.browser {
    dceTask {
        keep("myKotlinJSModule.org.example.getName", "myKotlinJSModule.org.example.User" )
    }
}

Note that the names of functions with parameters are mangled in the generated JavaScript code. To keep such functions from elimination, use the mangled names in the keep arguments.

Known issue: DCE and ktor

In Kotlin 1.3.71, there is a known issue of using ktor in Kotlin/JS projects. In some cases, you may get a type error like <something> is not a function that comes from the io.ktor:ktor-client-js:1.3.0 or io.ktor:ktor-client-core:1.3.0 artifacts. To avoid this issue, add the following DCE configuration:

kotlin.target.browser {
    dceTask {
        keep 'ktor-ktor-io.\$\$importsForInline\$\$.ktor-ktor-io.io.ktor.utils.io'
    }
}
kotlin.target.browser {
    dceTask {
        keep("ktor-ktor-io.\$\$importsForInline\$\$.ktor-ktor-io.io.ktor.utils.io")
    }
}