feat(资源管理): 加速资源首次加载
build.yaml / build (push) Successful in 51s

This commit is contained in:
xiaoqidun committed 2026-10-15 17:26:57 +08:00
1 parent 5dea48d54b
commit 59e3a7d36e
2 files changed
+32 -6

No files matched your search

+11 -5
View File
@@ -133,6 +133,7 @@ type outputContext struct {
checkpoint func() error checkpoint func() error
checked time.Time checked time.Time
pending uint8 pending uint8
interval uint8
} }
// Write 将数据块交给浏览器保存 // Write 将数据块交给浏览器保存
@@ -826,7 +827,9 @@ func documentResources(args []js.Value) (any, error) {
} }
ctx := context.Background() ctx := context.Background()
if len(args) == 1 { if len(args) == 1 {
ctx = newOutputContext(args[0]) operation := newOutputContext(args[0])
operation.interval = 255
ctx = operation
} }
return currentSession.Reader.ResourceSummaries(ctx) return currentSession.Reader.ResourceSummaries(ctx)
} }
@@ -5478,10 +5481,10 @@ func compressionFromJS(value js.Value, options *ofdgo.CompressionOptions) error
return options.Validate() return options.Validate()
} }
// newOutputContext 创建单次串行导出的取消上下文 // newOutputContext 创建单次串行操作的取消上下文
// 入参: checkpoint 浏览器取消检查回调 // 入参: checkpoint 浏览器取消检查回调
// 返回: context.Context 导出上下文 // 返回: *outputContext 操作上下文
func newOutputContext(checkpoint js.Value) context.Context { func newOutputContext(checkpoint js.Value) *outputContext {
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
return &outputContext{Context: ctx, cancel: cancel, checkpoint: func() error { return awaitExport(checkpoint) }} return &outputContext{Context: ctx, cancel: cancel, checkpoint: func() error { return awaitExport(checkpoint) }}
} }
@@ -5500,7 +5503,7 @@ func newEditorOperationContext(callback js.Value) (context.Context, func(string,
} }
} }
// Err 在取消检查间隙处理浏览器消息,不为每个像素触发跨语言回调 // Err 按操作间隔检查时间并处理浏览器消息,每次调用均检查已有取消状态
// 返回: error 取消错误 // 返回: error 取消错误
func (c *outputContext) Err() error { func (c *outputContext) Err() error {
if err := c.Context.Err(); err != nil { if err := c.Context.Err(); err != nil {
@@ -5511,6 +5514,9 @@ func (c *outputContext) Err() error {
return nil return nil
} }
c.pending = 15 c.pending = 15
if c.interval != 0 {
c.pending = c.interval
}
if time.Since(c.checked) >= 50*time.Millisecond { if time.Since(c.checked) >= 50*time.Millisecond {
c.checked = time.Now() c.checked = time.Now()
if err := c.checkpoint(); err != nil { if err := c.checkpoint(); err != nil {
+21 -1
View File
@@ -40,6 +40,26 @@ type editorXMLPatch struct {
data []byte data []byte
} }
// editorXMLReader 在内存XML上直接读取字节,按块检查长词元的取消信号
type editorXMLReader struct {
*bytes.Reader
ctx context.Context
remaining uint16
}
// ReadByte 读取XML词元字节,每4096字节检查取消状态
// 返回: byte 当前字节, error 取消或读取错误
func (r *editorXMLReader) ReadByte() (byte, error) {
if r.remaining == 0 {
if err := r.ctx.Err(); err != nil {
return 0, err
}
r.remaining = 4096
}
r.remaining--
return r.Reader.ReadByte()
}
// editorXMLPrefix 跳过UTF-8字节序标记和XML空白,探测后保留首个内容字节 // editorXMLPrefix 跳过UTF-8字节序标记和XML空白,探测后保留首个内容字节
// 入参: input 带缓冲的输入流,读取错误及取消信号由底层传递 // 入参: input 带缓冲的输入流,读取错误及取消信号由底层传递
// 返回: bool 是否以XML标记起始, error 读取错误 // 返回: bool 是否以XML标记起始, error 读取错误
@@ -86,7 +106,7 @@ func parseEditorXML(data []byte) (*editorXML, error) {
func parseEditorXMLContext(ctx context.Context, data []byte) (*editorXML, error) { func parseEditorXMLContext(ctx context.Context, data []byte) (*editorXML, error) {
var input io.Reader = bytes.NewReader(data) var input io.Reader = bytes.NewReader(data)
if ctx != nil { if ctx != nil {
input = imageInput{ReadCloser: io.NopCloser(input), context: ctx} input = &editorXMLReader{Reader: bytes.NewReader(data), ctx: ctx}
} }
d := xml.NewDecoder(input) d := xml.NewDecoder(input)
var root *editorXML var root *editorXML