-
Notifications
You must be signed in to change notification settings - Fork 33
⚡ Optimize DateFormatter creation in ActivityHeatmapView #65
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -26,6 +26,24 @@ final class ActivityHeatmapView: NSView { | |
| private var gridOffsetX: CGFloat = 0 | ||
| private var gridWidth: CGFloat = 0 | ||
|
|
||
| // MARK: - 缓存 | ||
| private lazy var calendar = Calendar.current | ||
| private lazy var monthFormatter: DateFormatter = { | ||
| let formatter = DateFormatter() | ||
| formatter.dateFormat = "MMM" | ||
| return formatter | ||
| }() | ||
| private lazy var weekdaySymbols: [String] = { | ||
| let formatter = DateFormatter() | ||
| formatter.locale = Locale.current | ||
| return formatter.shortWeekdaySymbols ?? ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"] | ||
| }() | ||
|
Comment on lines
+36
to
+40
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The private lazy var weekdaySymbols: [String] = {
return calendar.shortWeekdaySymbols ?? ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
}()
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jules fix
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good catch! I've simplified |
||
| private lazy var tooltipDateFormatter: DateFormatter = { | ||
| let formatter = DateFormatter() | ||
| formatter.dateStyle = .medium | ||
| return formatter | ||
| }() | ||
|
|
||
| // MARK: - 翻转坐标系 | ||
| override var isFlipped: Bool { true } | ||
|
|
||
|
|
@@ -111,7 +129,6 @@ final class ActivityHeatmapView: NSView { | |
| gridOffsetX = max(0, floor((bounds.width - contentWidth) / 2)) | ||
|
|
||
| cellRects.removeAll() | ||
| let calendar = Calendar.current | ||
|
|
||
| for (index, activity) in activityData.enumerated() { | ||
| let weekday = calendar.component(.weekday, from: activity.date) | ||
|
|
@@ -218,10 +235,6 @@ final class ActivityHeatmapView: NSView { | |
| } | ||
|
|
||
| private func drawMonthLabels() { | ||
| let calendar = Calendar.current | ||
| let monthFormatter = DateFormatter() | ||
| monthFormatter.dateFormat = "MMM" | ||
|
|
||
| var lastMonth = -1 | ||
| var lastLabelMaxX: CGFloat = -CGFloat.greatestFiniteMagnitude | ||
| for (index, activity) in activityData.enumerated() { | ||
|
|
@@ -244,11 +257,6 @@ final class ActivityHeatmapView: NSView { | |
| } | ||
|
|
||
| private func drawWeekdayLabels() { | ||
| let calendar = Calendar.current | ||
| let formatter = DateFormatter() | ||
| formatter.locale = Locale.current | ||
| let symbols = formatter.shortWeekdaySymbols ?? ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"] | ||
|
|
||
| let displayRows = [0, 2, 4] | ||
| let attrs: [NSAttributedString.Key: Any] = [ | ||
| .font: NSFont.systemFont(ofSize: 9), | ||
|
|
@@ -257,7 +265,7 @@ final class ActivityHeatmapView: NSView { | |
|
|
||
| for row in displayRows { | ||
| let symbolIndex = (row + calendar.firstWeekday - 1) % 7 | ||
| let label = String(symbols[symbolIndex].prefix(3)) | ||
| let label = String(weekdaySymbols[symbolIndex].prefix(3)) | ||
| let y = monthLabelHeight + CGFloat(row) * (cellSize + cellSpacing) | ||
| label.draw(at: NSPoint(x: gridOffsetX, y: y + 1), withAttributes: attrs) | ||
| } | ||
|
|
@@ -312,9 +320,7 @@ final class ActivityHeatmapView: NSView { | |
| let activity = activityData[index] | ||
| let tooltip = ensureTooltipView(in: host) | ||
|
|
||
| let dateFormatter = DateFormatter() | ||
| dateFormatter.dateStyle = .medium | ||
| let dateStr = dateFormatter.string(from: activity.date) | ||
| let dateStr = tooltipDateFormatter.string(from: activity.date) | ||
| let totalFormat = NSLocalizedString("heatmap.totalFormat", comment: "") | ||
| let detailFormat = NSLocalizedString("heatmap.detailFormat", comment: "") | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Caching
Calendar.currentin a lazy property captures a snapshot of calendar settings at first access, so long-running sessions can render stale weekday alignment after the user changes region/first-weekday or time zone in macOS settings.recalculateLayout()anddrawWeekdayLabels()now depend on this cached value, which can misplace cells and labels until restart, whereas the previous code re-readCalendar.currenton each call. UseCalendar.autoupdatingCurrent(or refresh the cache on locale/time-zone change notifications) to preserve correct rendering.Useful? React with 👍 / 👎.