fix: Improve WebView performance by sanitizing problematic HTML attributes

- Remove jsaction, jscontroller, jsname attributes that trigger navigation events
- Strip unnecessary id attributes to reduce DOM size
- Remove tabindex from non-interactive elements
- Fix invalid nested p tags inside pre/span blocks
- Prevents WebKit crashes on complex HTML content
This commit is contained in:
Ilyas Hallak 2025-10-07 20:41:43 +02:00
parent a2c805b700
commit 7b12bb4cf5

View File

@ -37,11 +37,27 @@ struct WebView: UIViewRepresentable {
func updateUIView(_ webView: WKWebView, context: Context) { func updateUIView(_ webView: WKWebView, context: Context) {
context.coordinator.onHeightChange = onHeightChange context.coordinator.onHeightChange = onHeightChange
context.coordinator.onScroll = onScroll context.coordinator.onScroll = onScroll
let isDarkMode = colorScheme == .dark let isDarkMode = colorScheme == .dark
let fontSize = getFontSize(from: settings.fontSize ?? .extraLarge) let fontSize = getFontSize(from: settings.fontSize ?? .extraLarge)
let fontFamily = getFontFamily(from: settings.fontFamily ?? .serif) let fontFamily = getFontFamily(from: settings.fontFamily ?? .serif)
// Clean up problematic HTML that kills performance
let cleanedHTML = htmlContent
// Remove Google attributes that cause navigation events
.replacingOccurrences(of: #"\s*jsaction="[^"]*""#, with: "", options: .regularExpression)
.replacingOccurrences(of: #"\s*jscontroller="[^"]*""#, with: "", options: .regularExpression)
.replacingOccurrences(of: #"\s*jsname="[^"]*""#, with: "", options: .regularExpression)
// Remove unnecessary IDs that bloat the DOM
.replacingOccurrences(of: #"\s*id="[^"]*""#, with: "", options: .regularExpression)
// Remove tabindex from non-interactive elements
.replacingOccurrences(of: #"\s*tabindex="[^"]*""#, with: "", options: .regularExpression)
// Remove role=button from figures (causes false click targets)
.replacingOccurrences(of: #"\s*role="button""#, with: "", options: .regularExpression)
// Fix invalid nested <p> tags inside <pre><span>
.replacingOccurrences(of: #"<pre><span[^>]*>([^<]*)<p>"#, with: "<pre><span>$1\n", options: .regularExpression)
.replacingOccurrences(of: #"</p>([^<]*)</span></pre>"#, with: "\n$1</span></pre>", options: .regularExpression)
let styledHTML = """ let styledHTML = """
<html> <html>
<head> <head>
@ -222,7 +238,7 @@ struct WebView: UIViewRepresentable {
</style> </style>
</head> </head>
<body> <body>
\(htmlContent) \(cleanedHTML)
<script> <script>
let lastHeight = 0; let lastHeight = 0;
let heightUpdateTimeout = null; let heightUpdateTimeout = null;