Safari 15 渲染canvas时发生崩溃问题,求可行解决方案
Safari 15(macOS/iPhone/iPad端)canvas渲染崩溃解决方案
该问题是Safari 15系列的已知底层渲染bug,触发条件为canvas使用system-ui字体绘制包含中文字符的内容,且canvas实际像素尺寸大于显示尺寸(即做了高DPI适配)时就会触发崩溃,旧版本Safari不受影响。
以下是可行的解决办法:
- 方案1:调整canvas字体声明,增加明确的中文字体 fallback
不要单独使用system-ui作为字体值,补充苹果系统内置的中文字体作为fallback,避免Safari在动态匹配system-ui对应的中文字形时触发bug,改造成本最低,是最优先推荐的修复方式。修正后的字体声明示例:ctx.font = '48px system-ui, -apple-system, BlinkMacSystemFont, "PingFang SC", "Hiragino Sans GB", sans-serif'; - 方案2:取消canvas高DPI适配
若业务对canvas绘制清晰度要求不高,可以直接将canvas的实际宽高和样式宽高设为相同值,避免像素缩放触发渲染异常,对应修改代码为:canvas.width = 800; canvas.height = 600; - 方案3:使用离屏canvas中转绘制
若必须保留system-ui字体和高DPI适配,可以先把文字绘制到一个小尺寸的离屏canvas上,再将离屏canvas作为图片资源绘制到目标canvas上,绕开直接绘制的bug。 - 方案4:全局声明
system-ui的字体 fallback
可以在CSS中增加@font-face声明,给全局的system-ui字体指定明确的系统内置字体源,避免所有canvas场景下的匹配异常:@font-face { font-family: system-ui; src: local(".SFNS-Regular"), local("PingFang SC"), local("Hiragino Sans GB"); }
修正后的完整可运行代码示例:
<html> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <script language="javascript"> function init2() { const canvas = document.createElement("canvas"); canvas.style.width = "800px"; canvas.style.height = "600px"; canvas.width = 1600; canvas.height = 1200; document.body.appendChild(canvas); var ctx = canvas.getContext('2d'); // 补充中文字体fallback修复崩溃 ctx.font = '48px system-ui, -apple-system, "PingFang SC", sans-serif'; ctx.fillText('Hello World, 你好中文', 10, 50); } </script> </head> <body onload="init2()"> </body> </html>
内容的提问来源于stack exchange,提问作者Howard
相关产品推荐
相关产品推荐

