Skip to content

⚡ Bolt: 정적 문자열 및 SHA-256 연산 최상위 레벨 추출 최적화 - #297

Open
seonghobae wants to merge 2 commits into
masterfrom
bolt/optimize-css-allocation-9131154617048988834
Open

⚡ Bolt: 정적 문자열 및 SHA-256 연산 최상위 레벨 추출 최적화#297
seonghobae wants to merge 2 commits into
masterfrom
bolt/optimize-css-allocation-9131154617048988834

Conversation

@seonghobae

@seonghobae seonghobae commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

⚡ Bolt Performance Optimization

💡 What

  • html4tree/main.ktprocess_dir 함수 내부에 정의되어 있던 cssContent, styleHash, css 변수들을 파일 레벨(top-level) 프로퍼티로 추출했습니다.
  • 추출된 프로퍼티들에 대한 100% 테스트 커버리지를 유지하기 위해 MainTest.kttestTopLevelCssProperties 테스트 케이스를 추가했습니다.
  • .jules/bolt.md에 관련 학습 내용을 기록했습니다.

🎯 Why

  • process_dir 함수는 디렉토리를 순회하며 재귀적으로 (또는 루프 내에서) 호출됩니다.
  • 기존에는 이 함수가 호출될 때마다 크기가 큰 정적 CSS 문자열(cssContent, css)이 새로 메모리에 할당되었습니다.
  • 무엇보다, 매번 비용이 큰 SHA-256 해시 연산(MessageDigest.getInstance("SHA-256"))이 수행되어 심각한 CPU 및 메모리 낭비(병목)가 발생하고 있었습니다.

📊 Impact

  • 정적 문자열 할당 및 해시 연산이 앱 실행 시 최초 1회만 수행되므로, 디렉토리 순회 시 발생하는 메모리 가비지(GC 압력)와 CPU 오버헤드가 크게 감소합니다.
  • 특히 파일/디렉토리가 많은 대규모 트리를 렌더링할 때 눈에 띄는 성능 향상을 기대할 수 있습니다.

🔬 Measurement

  • ./gradlew test jacocoTestReport를 실행하여 100% 명령어 커버리지가 유지됨을 확인했습니다. 모든 테스트가 정상적으로 통과합니다.

PR created automatically by Jules for task 9131154617048988834 started by @seonghobae

Summary by CodeRabbit

  • 성능 개선

    • 디렉터리 목록과 파일 속성 처리 효율을 높여 대규모 폴더 탐색 및 인덱스 생성 속도를 개선했습니다.
    • 스타일 정보와 해시값을 재사용해 반복 처리로 인한 불필요한 작업을 줄였습니다.
  • 품질 개선

    • 생성되는 스타일 콘텐츠와 해시 형식의 일관성을 검증하는 테스트를 추가했습니다.

- `process_dir` 내에서 매번 계산되던 `cssContent`, `styleHash`, `css`를 파일 최상위 레벨 프로퍼티로 이동
- 메모리 할당 및 무거운 해시 암호화 연산(`MessageDigest.getInstance`) 반복 수행 방지
- JaCoCo 100% 테스트 커버리지 유지를 위해 `MainTest.kt`에 `testTopLevelCssProperties` 테스트 추가
- `.jules/bolt.md`에 성능 최적화 관련 학습 내용 기록
@google-labs-jules

Copy link
Copy Markdown

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

cssContent, styleHash, css 생성을 최상위로 이동했습니다. process_dir의 반복 생성을 제거하고 관련 테스트와 디렉터리 순회 및 파일 속성 조회 최적화 지침을 추가했습니다.

Changes

CSS 재사용 최적화

Layer / File(s) Summary
CSS 최상위 프로퍼티와 검증
src/main/kotlin/html4tree/main.kt, src/test/kotlin/html4tree/MainTest.kt, .jules/bolt.md
CSS 콘텐츠와 스타일 해시 생성을 최상위로 이동했습니다. 테스트는 CSS 형식, sha256- 접두사, <style> 태그 생성을 검증합니다. 최적화 지침에는 디렉터리 목록 캐싱과 통합 속성 조회 내용이 추가되었습니다.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Suggested reviewers: copilot

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목은 정적 문자열과 SHA-256 연산을 최상위 레벨로 이동하는 주요 변경 사항을 명확하게 요약합니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch bolt/optimize-css-allocation-9131154617048988834

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/test/kotlin/html4tree/MainTest.kt (1)

709-715: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

실제 <style> 본문과 styleHash의 정확한 값을 검증하세요.

현재 테스트는 CSS 일부, sha256- 접두사, <style> 태그만 확인합니다. 잘못된 문자열을 해시해도 테스트가 통과합니다. css에서 <style> 본문을 추출하여 cssContent와 비교하고, 해당 본문으로 계산한 SHA-256 값이 styleHash와 같은지 확인하세요.

테스트 보강 예시
         assertTrue(cssContent.contains("body {"))
-        assertTrue(styleHash.startsWith("sha256-"))
         assertTrue(css.contains("<style>"))
+        val styleBody = css.substringAfter("<style>").substringBefore("</style>")
+        assertEquals(cssContent, styleBody)
+        val expectedStyleHash = "sha256-" + java.util.Base64.getEncoder().encodeToString(
+            java.security.MessageDigest.getInstance("SHA-256")
+                .digest(styleBody.toByteArray(Charsets.UTF_8))
+        )
+        assertEquals(expectedStyleHash, styleHash)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/test/kotlin/html4tree/MainTest.kt` around lines 709 - 715, Strengthen
testTopLevelCssProperties by extracting the actual `<style>` element body from
css and asserting it equals cssContent. Compute the SHA-256 hash from that
extracted body and assert the resulting value exactly matches styleHash,
replacing the prefix-only check while retaining the existing style-tag
validation.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/main/kotlin/html4tree/main.kt`:
- Around line 313-318: Update the styleHash calculation near css so it hashes
the exact CSS text emitted inside the <style> element, including its newline and
whitespace formatting; either construct the hashed value as the complete
<style>${cssContent}</style> body or otherwise reuse the same rendered style
content to keep the hash and output identical.

---

Nitpick comments:
In `@src/test/kotlin/html4tree/MainTest.kt`:
- Around line 709-715: Strengthen testTopLevelCssProperties by extracting the
actual `<style>` element body from css and asserting it equals cssContent.
Compute the SHA-256 hash from that extracted body and assert the resulting value
exactly matches styleHash, replacing the prefix-only check while retaining the
existing style-tag validation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 5229dfe7-10a6-41cd-9692-66a916342038

📥 Commits

Reviewing files that changed from the base of the PR and between 669c4ef and 0c79cc5.

📒 Files selected for processing (3)
  • .jules/bolt.md
  • src/main/kotlin/html4tree/main.kt
  • src/test/kotlin/html4tree/MainTest.kt

Comment on lines +313 to 318
val styleHash = "sha256-" + Base64.getEncoder().encodeToString(MessageDigest.getInstance("SHA-256").digest(cssContent.toByteArray(Charsets.UTF_8)))

val css = """
val css = """
<style>
${cssContent} </style>
"""

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
import base64
import hashlib

source = Path("src/main/kotlin/html4tree/main.kt").read_text(encoding="utf-8")

def raw_value(name: str) -> str:
    marker = f'val {name} = """'
    start = source.index(marker) + len(marker)
    end = source.index('"""', start)
    return source[start:end]

css_content = raw_value("cssContent")
css = raw_value("css")
style_body = css.split("<style>", 1)[1].split("</style>", 1)[0]

def csp_hash(value: str) -> str:
    digest = hashlib.sha256(value.encode("utf-8")).digest()
    return "sha256-" + base64.b64encode(digest).decode("ascii")

print("cssContent hash:", csp_hash(css_content))
print("style body hash:", csp_hash(style_body))

if style_body != css_content:
    raise SystemExit("style body and cssContent differ")
PY

Repository: ContextualWisdomLab/html4tree

Length of output: 338


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '285,335p' src/main/kotlin/html4tree/main.kt
printf '\n--- styleHash usages ---\n'
rg -n -C 3 'styleHash|cssContent|<style>' src/main/kotlin/html4tree/main.kt

Repository: ContextualWisdomLab/html4tree

Length of output: 3248


styleHash가 실제 <style> 본문을 해시하도록 수정하세요.

현재 두 값의 SHA-256 해시가 다릅니다. <style> 내부의 개행과 공백을 포함한 실제 본문을 해시하거나, <style>${cssContent}</style>로 구성하세요.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/kotlin/html4tree/main.kt` around lines 313 - 318, Update the
styleHash calculation near css so it hashes the exact CSS text emitted inside
the <style> element, including its newline and whitespace formatting; either
construct the hashed value as the complete <style>${cssContent}</style> body or
otherwise reuse the same rendered style content to keep the hash and output
identical.

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.

1 participant