Skip to content

Commit

Permalink
perf: Make next-page-static-info use Atom instead of String (#7…
Browse files Browse the repository at this point in the history
…5587)

### What?

Use `swc_atoms::Atom` instead of `String` in `next-swc`. 

### Why?

`Atom` does not allocate if another instance has the same value, meaning that `clone()` is a single atomic operation. But `String` allocates regardless of any other occurrence.
  • Loading branch information
kdy1 authored Feb 3, 2025
1 parent 90090ba commit fd8b054
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use next_custom_transforms::transforms::page_static_info::{
collect_exports, extract_exported_const_values, Const,
};
use serde_json::Value;
use swc_core::ecma::ast::Program;
use swc_core::{atoms::atom, ecma::ast::Program};
use turbo_tasks::{ResolvedVc, Vc};
use turbo_tasks_fs::FileSystemPath;
use turbopack::module_options::{ModuleRule, ModuleRuleEffect};
Expand Down Expand Up @@ -51,7 +51,7 @@ impl CustomTransformer for NextPageStaticInfo {
async fn transform(&self, program: &mut Program, ctx: &TransformContext<'_>) -> Result<()> {
if let Some(collected_exports) = collect_exports(program)? {
let mut properties_to_extract = collected_exports.extra_properties.clone();
properties_to_extract.insert("config".to_string());
properties_to_extract.insert(atom!("config"));

let extracted = extract_exported_const_values(program, properties_to_extract);

Expand Down Expand Up @@ -82,7 +82,8 @@ impl CustomTransformer for NextPageStaticInfo {
}

if is_app_page {
if let Some(Some(Const::Value(Value::Object(config_obj)))) = extracted.get("config")
if let Some(Some(Const::Value(Value::Object(config_obj)))) =
extracted.get(&atom!("config"))
{
let mut messages = vec![format!(
"Page config in {} is deprecated. Replace `export const config=…` with \
Expand Down Expand Up @@ -110,7 +111,7 @@ impl CustomTransformer for NextPageStaticInfo {
}
}

if collected_exports.directives.contains("client")
if collected_exports.directives.contains(&atom!("client"))
&& collected_exports.generate_static_params
&& is_app_page
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::collections::{HashMap, HashSet};

use rustc_hash::{FxHashMap, FxHashSet};
use serde_json::{Map, Number, Value};
use swc_core::{
atoms::Atom,
common::{Mark, SyntaxContext},
ecma::{
ast::{
Expand All @@ -22,12 +22,12 @@ pub enum Const {
}

pub(crate) struct CollectExportedConstVisitor {
pub properties: HashMap<String, Option<Const>>,
pub properties: FxHashMap<Atom, Option<Const>>,
expr_ctx: ExprCtx,
}

impl CollectExportedConstVisitor {
pub fn new(properties_to_extract: HashSet<String>) -> Self {
pub fn new(properties_to_extract: FxHashSet<Atom>) -> Self {
Self {
properties: properties_to_extract
.into_iter()
Expand Down Expand Up @@ -60,7 +60,7 @@ impl Visit for CollectExportedConstVisitor {
..
} = decl
{
let id = id.sym.as_ref();
let id = &id.sym;
if let Some(prop) = self.properties.get_mut(id) {
*prop = extract_value(self.expr_ctx, init, id.to_string());
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
use std::collections::HashSet;

use lazy_static::lazy_static;
use swc_core::ecma::{
ast::{
Decl, ExportDecl, ExportNamedSpecifier, ExportSpecifier, Expr, ExprOrSpread, ExprStmt, Lit,
ModuleExportName, ModuleItem, NamedExport, Pat, Stmt, Str, VarDeclarator,
use swc_core::{
atoms::atom,
ecma::{
ast::{
Decl, ExportDecl, ExportNamedSpecifier, ExportSpecifier, Expr, ExprOrSpread, ExprStmt,
Lit, ModuleExportName, ModuleItem, NamedExport, Pat, Stmt, Str, VarDeclarator,
},
visit::{Visit, VisitWith},
},
visit::{Visit, VisitWith},
};

use super::{ExportInfo, ExportInfoWarning};
Expand Down Expand Up @@ -46,11 +49,11 @@ impl Visit for CollectExportsVisitor {
if is_directive {
if value == "use server" {
let export_info = self.export_info.get_or_insert(Default::default());
export_info.directives.insert("server".to_string());
export_info.directives.insert(atom!("server"));
}
if value == "use client" {
let export_info = self.export_info.get_or_insert(Default::default());
export_info.directives.insert("client".to_string());
export_info.directives.insert(atom!("client"));
}
}
} else {
Expand Down Expand Up @@ -86,7 +89,7 @@ impl Visit for CollectExportsVisitor {
let export_info = self.export_info.get_or_insert(Default::default());
export_info.runtime = decl.init.as_ref().and_then(|init| {
if let Expr::Lit(Lit::Str(Str { value, .. })) = &**init {
Some(value.to_string())
Some(value.clone())
} else {
None
}
Expand All @@ -102,18 +105,18 @@ impl Visit for CollectExportsVisitor {
{
let export_info =
self.export_info.get_or_insert(Default::default());
export_info.preferred_region.push(value.to_string());
export_info.preferred_region.push(value.clone());
}
}
} else if let Expr::Lit(Lit::Str(Str { value, .. })) = &**init {
let export_info =
self.export_info.get_or_insert(Default::default());
export_info.preferred_region.push(value.to_string());
export_info.preferred_region.push(value.clone());
}
}
} else {
let export_info = self.export_info.get_or_insert(Default::default());
export_info.extra_properties.insert(id.sym.to_string());
export_info.extra_properties.insert(id.sym.clone());
}
}
}
Expand Down Expand Up @@ -169,16 +172,15 @@ impl Visit for CollectExportsVisitor {

if export_info.runtime.is_none() && value.sym == "runtime" {
export_info.warnings.push(ExportInfoWarning::new(
value.sym.to_string(),
"it was not assigned to a string literal".to_string(),
value.sym.clone(),
"it was not assigned to a string literal",
));
}

if export_info.preferred_region.is_empty() && value.sym == "preferredRegion" {
export_info.warnings.push(ExportInfoWarning::new(
value.sym.to_string(),
"it was not assigned to a string literal or an array of string literals"
.to_string(),
value.sym.clone(),
"it was not assigned to a string literal or an array of string literals",
));
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use std::collections::{HashMap, HashSet};

use anyhow::Result;
pub use collect_exported_const_visitor::Const;
use collect_exports_visitor::CollectExportsVisitor;
use once_cell::sync::Lazy;
use regex::Regex;
use rustc_hash::{FxHashMap, FxHashSet};
use serde::{Deserialize, Serialize};
use swc_core::{
atoms::Atom,
base::SwcComments,
common::GLOBALS,
ecma::{ast::Program, visit::VisitWith},
Expand Down Expand Up @@ -38,33 +38,33 @@ pub struct PageStaticInfo {
pub amp: Option<Amp>,
}

#[derive(Debug, Default, Serialize, Deserialize)]
#[derive(Debug, Default, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ExportInfoWarning {
pub key: String,
pub message: String,
pub key: Atom,
pub message: &'static str,
}

impl ExportInfoWarning {
pub fn new(key: String, message: String) -> Self {
pub fn new(key: Atom, message: &'static str) -> Self {
Self { key, message }
}
}

#[derive(Debug, Default, Serialize, Deserialize)]
#[derive(Debug, Default, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ExportInfo {
pub ssr: bool,
pub ssg: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub runtime: Option<String>,
pub runtime: Option<Atom>,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub preferred_region: Vec<String>,
pub preferred_region: Vec<Atom>,
pub generate_image_metadata: Option<bool>,
pub generate_sitemaps: Option<bool>,
pub generate_static_params: bool,
pub extra_properties: HashSet<String>,
pub directives: HashSet<String>,
pub extra_properties: FxHashSet<Atom>,
pub directives: FxHashSet<Atom>,
/// extra properties to bubble up warning messages from visitor,
/// since this isn't a failure to abort the process.
pub warnings: Vec<ExportInfoWarning>,
Expand Down Expand Up @@ -209,8 +209,8 @@ pub fn collect_rsc_module_info(
/// error.
pub fn extract_exported_const_values(
source_ast: &Program,
properties_to_extract: HashSet<String>,
) -> HashMap<String, Option<Const>> {
properties_to_extract: FxHashSet<Atom>,
) -> FxHashMap<Atom, Option<Const>> {
GLOBALS.set(&Default::default(), || {
let mut visitor =
collect_exported_const_visitor::CollectExportedConstVisitor::new(properties_to_extract);
Expand Down

0 comments on commit fd8b054

Please sign in to comment.